Sat Feb 11 06:34:33 2012

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  active_list
struct  addr_range
struct  callno_entry
struct  chan_iax2_pvt
struct  chan_iax2_pvt::signaling_queue
struct  create_addr_info
struct  dpcache
struct  dpreq_data
struct  dynamic_list
struct  firmwares
struct  iax2_context
struct  iax2_dpcache
struct  iax2_peer
struct  iax2_pkt_buf
struct  iax2_registry
struct  iax2_thread
struct  iax2_trunk_peer
struct  iax2_user
struct  iax_dual
struct  iax_firmware
struct  iax_rr
struct  idle_list
struct  parsed_dial_string
struct  peercnt
struct  registrations
struct  signaling_queue_entry
struct  tpeers

Defines

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

Enumerations

enum  { NEW_PREVENT = 0, NEW_ALLOW = 1, NEW_FORCE = 2, NEW_ALLOW_CALLTOKEN_VALIDATED = 3 }
enum  {
  CACHE_FLAG_EXISTS = (1 << 0), CACHE_FLAG_NONEXISTENT = (1 << 1), CACHE_FLAG_CANEXIST = (1 << 2), CACHE_FLAG_PENDING = (1 << 3),
  CACHE_FLAG_TIMEOUT = (1 << 4), CACHE_FLAG_TRANSMITTED = (1 << 5), CACHE_FLAG_UNKNOWN = (1 << 6), CACHE_FLAG_MATCHMORE = (1 << 7)
}
enum  calltoken_peer_enum { CALLTOKEN_DEFAULT = 0, CALLTOKEN_YES = 1, CALLTOKEN_AUTO = 2, CALLTOKEN_NO = 3 }
 Call token validation settings. More...
enum  iax2_state { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) }
enum  iax2_thread_iostate { IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_SCHEDREADY }
enum  iax2_thread_type { IAX_THREAD_TYPE_POOL, IAX_THREAD_TYPE_DYNAMIC }
enum  iax_reg_state {
  REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED,
  REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH
}
enum  iax_transfer_state {
  TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED,
  TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED,
  TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS
}

Functions

static void __attempt_transmit (const void *data)
static void __auth_reject (const void *nothing)
static void __auto_congest (const void *nothing)
static void __auto_hangup (const void *nothing)
static int __do_deliver (void *data)
static void __expire_registry (const void *data)
static int __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
static void __get_from_jb (const void *p)
static void __iax2_do_register_s (const void *data)
static void __iax2_poke_noanswer (const void *data)
static void __iax2_poke_peer_s (const void *data)
static int __iax2_show_peers (int fd, int *total, struct mansession *s, const int argc, const char *const argv[])
static void __reg_module (void)
static int __schedule_action (void(*func)(const void *data), const void *data, const char *funcname)
static int __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final)
static void __send_lagrq (const void *data)
static void __send_ping (const void *data)
static int __unload_module (void)
static void __unreg_module (void)
static int acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen)
static int acf_iaxvar_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int acf_iaxvar_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
static int add_calltoken_ignore (const char *addr)
static void add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
static int addr_range_cmp_cb (void *obj, void *arg, int flags)
static int addr_range_delme_cb (void *obj, void *arg, int flags)
static int addr_range_hash_cb (const void *obj, const int flags)
static int addr_range_match_address_cb (void *obj, void *arg, int flags)
static int apply_context (struct iax2_context *con, const char *context)
static int ast_cli_netstats (struct mansession *s, int fd, int limit_fmt)
 AST_DATA_STRUCTURE (iax2_user, DATA_EXPORT_IAX2_USER)
 AST_DATA_STRUCTURE (iax2_peer, DATA_EXPORT_IAX2_PEER)
static struct ast_channelast_iax2_new (int callno, int state, iax2_format capability, const char *linkedid)
 Create new call, interface with the PBX core.
static int attempt_transmit (const void *data)
static int auth_fail (int callno, int failcode)
static int auth_reject (const void *data)
static int authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt)
static int authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
static int authenticate_request (int call_num)
static int authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies)
static int auto_congest (const void *data)
static int auto_hangup (const void *data)
static void build_callno_limits (struct ast_variable *v)
static struct iax2_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 (iax2_format subclass)
static void construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
static int create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
static int create_callno_pools (void)
static int decode_frame (ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static int decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static void defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here)
 Queue the last read full frame for processing by a certain thread.
static void delete_users (void)
static void destroy_firmware (struct iax_firmware *cur)
static void dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
static void * dp_lookup_thread (void *data)
static void encmethods_to_str (int e, struct ast_str *buf)
static int encrypt_frame (ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
static int expire_registry (const void *data)
static struct iax2_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 iax2_format iax2_best_codec (iax2_format formats)
static enum ast_bridge_result iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
static int iax2_call (struct ast_channel *c, const char *dest, int timeout)
static int iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 part of the IAX2 dial plan switch interface
static iax2_format iax2_codec_choose (struct ast_codec_pref *pref, iax2_format formats, int find_best)
static int iax2_data_add_codecs (struct ast_data *root, const char *node_name, iax2_format formats)
static unsigned int iax2_datetime (const char *tz)
static void iax2_destroy (int callno)
static void iax2_destroy_helper (struct chan_iax2_pvt *pvt)
static int iax2_devicestate (const char *data)
 Part of the device state notification system ---.
static int iax2_digit_begin (struct ast_channel *c, char digit)
static int iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration)
static int iax2_do_register (struct iax2_registry *reg)
static int iax2_do_register_s (const void *data)
static void iax2_dprequest (struct iax2_dpcache *dp, int callno)
static void * iax2_dup_variable_datastore (void *)
static int iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Execute IAX2 dialplan switch.
static int iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 switch interface.
static int iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan)
static void iax2_frame_free (struct iax_frame *fr)
static void iax2_free_variable_datastore (void *)
const char * iax2_getformatname (iax2_format format)
 iax2 wrapper function for ast_getformatname
static char * iax2_getformatname_multiple (char *codec_buf, size_t len, iax2_format format)
static int iax2_getpeername (struct sockaddr_in sin, char *host, int len)
static int iax2_getpeertrunk (struct sockaddr_in sin)
static int iax2_hangup (struct ast_channel *c)
static int iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen)
static int iax2_key_rotate (const void *vpvt)
static void iax2_lock_owner (int callno)
static int iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 Switch interface.
static int iax2_parse_allow_disallow (struct ast_codec_pref *pref, iax2_format *formats, const char *list, int allowing)
static int iax2_poke_noanswer (const void *data)
static int iax2_poke_peer (struct iax2_peer *peer, int heldcall)
static int iax2_poke_peer_cb (void *obj, void *arg, int flags)
static int iax2_poke_peer_s (const void *data)
static int iax2_predestroy (int callno)
static void * iax2_process_thread (void *data)
static void iax2_process_thread_cleanup (void *data)
static int iax2_prov_app (struct ast_channel *chan, const char *data)
static int iax2_provision (struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
static int iax2_queryoption (struct ast_channel *c, int option, void *data, int *datalen)
static int iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen)
 Queue a control frame on the ast_channel owner.
static int iax2_queue_frame (int callno, struct ast_frame *f)
 Queue a frame to a call's owning asterisk channel.
static int iax2_queue_hangup (int callno)
 Queue a hangup frame on the ast_channel owner.
static struct ast_frameiax2_read (struct ast_channel *c)
static int iax2_register (const char *value, int lineno)
static struct ast_channeliax2_request (const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
static int iax2_sched_add (struct ast_sched_context *sched, int when, ast_sched_cb callback, const void *data)
static int iax2_sched_replace (int id, struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data)
static int iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
static int iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen)
static int iax2_sendimage (struct ast_channel *c, struct ast_frame *img)
static int iax2_sendtext (struct ast_channel *c, const char *text)
static int iax2_setoption (struct ast_channel *c, int option, void *data, int datalen)
static int iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly)
static int iax2_transfer (struct ast_channel *c, const char *dest)
static int iax2_transmit (struct iax_frame *fr)
static int iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now)
static int iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr)
static int iax2_vnak (int callno)
static int iax2_write (struct ast_channel *c, struct ast_frame *f)
static int iax_check_version (char *dev)
static void iax_debug_output (const char *data)
static void iax_error_output (const char *data)
static int iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
static void iax_outputframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
static int iax_park (struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context)
static void * iax_park_thread (void *stuff)
static struct iax_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 iax2_format uncompress_subclass (unsigned char csub)
static void unlink_peer (struct iax2_peer *peer)
static int unload_module (void)
static void unlock_both (unsigned short callno0, unsigned short callno1)
static void unwrap_timestamp (struct iax_frame *fr)
static void update_jbsched (struct chan_iax2_pvt *pvt)
static void update_max_nontrunk (void)
static void update_max_trunk (void)
static int update_packet (struct iax_frame *f)
static int update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
static int user_cmp_cb (void *obj, void *arg, int flags)
static int user_delme_cb (void *obj, void *arg, int flags)
static void user_destructor (void *obj)
static int user_hash_cb (const void *obj, const int flags)
static struct iax2_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 struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", }
static char accountcode [AST_MAX_ACCOUNT_CODE]
static int adsi = 0
static int amaflags = 0
static struct ast_module_infoast_module_info = &__mod_info
static int authdebug = 0
static int autokill = 0
static struct ao2_containercallno_limits
static struct ao2_containercallno_pool
static const unsigned int CALLNO_POOL_BUCKETS = 2699
static struct ao2_containercallno_pool_trunk
static struct ao2_containercalltoken_ignores
static struct ast_cli_entry cli_iax2 []
static struct sockaddr_in debugaddr
static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048
static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192
static char default_parkinglot [AST_MAX_CONTEXT]
static int defaultsockfd = -1
static int delayreject = 0
struct {
   struct iax_frame *   first
   struct iax_frame *   last
frame_queue [IAX_MAX_CALLS+1]
 a list of frames that may need to be retransmitted
static int global_max_trunk_mtu
static uint16_t global_maxcallno
static uint16_t global_maxcallno_nonval
static int global_rtautoclear = 120
static struct ast_flags64 globalflags = { 0 }
static iax2_format iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH
static struct ast_data_entry iax2_data_providers []
static int iax2_encryption = 0
static int(* iax2_regfunk )(const char *username, int onoff) = NULL
static struct ast_switch iax2_switch
static struct ast_channel_tech iax2_tech
static struct ast_datastore_info iax2_variable_datastore_info
static struct ao2_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+1]
 an array of iax2 pvt structures
static ast_mutex_t iaxsl [ARRAY_LEN(iaxs)]
 chan_iax2_pvt structure locks
static int iaxthreadcount = DEFAULT_THREAD_COUNT
static int iaxtrunkdebug = 0
static struct ast_custom_function iaxvar_function
static struct io_contextio
static int jittertargetextra = 40
static int lagrq_time = 10
static char language [MAX_LANGUAGE] = ""
static int last_authmethod = 0
static const time_t MAX_CALLTOKEN_DELAY = 10
static int max_reg_expire
static int max_retries = 4
static int maxauthreq = 3
static int maxjitterbuffer = 1000
static int maxjitterinterps = 10
static int maxnontrunkcall = 1
static int maxtrunkcall = TRUNK_CALL_START
static int min_reg_expire
static char mohinterpret [MAX_MUSICCLASS]
static char mohsuggest [MAX_MUSICCLASS]
static struct ast_netsock_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 ao2_containerpeercnts
static struct ao2_containerpeers
static struct ast_data_handler peers_data_provider
static int ping_time = 21
static struct ast_codec_pref prefs
struct {
   unsigned int   cos
   unsigned int   tos
qos
static int randomcalltokendata
static char regcontext [AST_MAX_CONTEXT] = ""
static int resyncthreshold = 1000
static struct ast_sched_contextsched
static int srvlookup = 0
static const char tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)"
static int test_losspct = 0
static struct ast_timertimer
static uint16_t total_nonval_callno_used = 0
static struct ast_taskprocessortransmit_processor
static int trunk_maxmtu
static int trunk_nmaxmtu
static int trunk_timed
static int trunk_untimed
static int trunkfreq = 20
static int trunkmaxsize = MAX_TRUNKDATA
static struct ao2_containerusers
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 %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"

Referenced by ast_cli_netstats().

#define ACN_FORMAT2   "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"

Referenced by ast_cli_netstats().

#define CALLNO_TO_PTR (  )     ((void *)(unsigned long)(a))

Definition at line 239 of file chan_iax2.c.

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

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

Referenced by handle_call_token().

#define CALLTOKEN_IE_FORMAT   "%u?%s"

Referenced by handle_call_token().

#define DATA_EXPORT_IAX2_PEER ( MEMBER   ) 

Definition at line 14580 of file chan_iax2.c.

#define DATA_EXPORT_IAX2_USER ( MEMBER   ) 

Definition at line 14657 of file chan_iax2.c.

#define DEBUG_SCHED_MULTITHREAD

Definition at line 231 of file chan_iax2.c.

#define DEBUG_SUPPORT

Definition at line 247 of file chan_iax2.c.

#define DEFAULT_CONTEXT   "default"

#define DEFAULT_DROP   3

Definition at line 245 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

Definition at line 341 of file chan_iax2.c.

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

#define DEFAULT_FREQ_OK   60 * 1000

Definition at line 340 of file chan_iax2.c.

Referenced by build_peer().

#define DEFAULT_MAX_THREAD_COUNT   100

Definition at line 242 of file chan_iax2.c.

#define DEFAULT_MAXMS   2000

Definition at line 339 of file chan_iax2.c.

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

#define DEFAULT_RETRY_TIME   1000

Definition at line 243 of file chan_iax2.c.

Referenced by __find_callno(), and complete_transfer().

#define DEFAULT_THREAD_COUNT   10

Definition at line 241 of file chan_iax2.c.

#define DEFAULT_TRUNKDATA   640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 621 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

#define DONT_RESCHEDULE   -2

Definition at line 363 of file chan_iax2.c.

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

#define FORMAT   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n"

#define FORMAT   "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"

#define FORMAT   "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-11s %-32.32s\n"

#define FORMAT   "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"

#define FORMAT2   "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"

#define FORMAT2   "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"

#define FORMAT2   "%-15.15s %-15.15s %s %-15.15s %-8s %s %-11s %-32.32s\n"

#define FORMAT2   "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"

#define FORMATB   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"

#define GAMMA   (0.01)

Definition at line 252 of file chan_iax2.c.

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

Definition at line 542 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

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

Allow the FWDOWNL command?

Definition at line 429 of file chan_iax2.c.

Referenced by set_config(), and socket_process().

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

Already disconnected

Definition at line 412 of file chan_iax2.c.

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

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

Definition at line 344 of file chan_iax2.c.

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

#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF

Definition at line 318 of file chan_iax2.c.

Referenced by cache_get_callno_locked(), and set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH

#define IAX_CAPABILITY_LOWFREE

#define IAX_CAPABILITY_MEDBANDWIDTH

Definition at line 320 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 419 of file chan_iax2.c.

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

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

Force old behaviour by turning off prefs

Definition at line 418 of file chan_iax2.c.

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

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

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

Definition at line 417 of file chan_iax2.c.

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

#define IAX_DEBUGDIGEST ( msg,
key   ) 

Definition at line 347 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 428 of file chan_iax2.c.

Referenced by socket_process().

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

Needs to be deleted

Definition at line 404 of file chan_iax2.c.

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

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

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

Whether we should assume encrypted tx/rx

Definition at line 415 of file chan_iax2.c.

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

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

Forces call encryption, if encryption not possible hangup

Definition at line 433 of file chan_iax2.c.

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

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

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

Definition at line 423 of file chan_iax2.c.

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

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

CallerID has been specified

Definition at line 403 of file chan_iax2.c.

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

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

Allow immediate off-hook to extension s

Definition at line 430 of file chan_iax2.c.

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

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

Whether we have a key populated

Definition at line 416 of file chan_iax2.c.

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

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

Maximum outstanding AUTHREQ restriction is in place

Definition at line 427 of file chan_iax2.c.

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

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

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

This is a provisioning request

Definition at line 413 of file chan_iax2.c.

Referenced by iax2_provision(), and socket_process().

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

Whether or not we quelch audio

Definition at line 414 of file chan_iax2.c.

Referenced by iax2_write(), and socket_process().

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

Allow receiving of connected line updates

Definition at line 432 of file chan_iax2.c.

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

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

erase me on expire

Definition at line 422 of file chan_iax2.c.

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

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

let realtime stay till your reload

Definition at line 420 of file chan_iax2.c.

Referenced by __expire_registry(), handle_cli_iax2_prune_realtime(), prune_peers(), prune_users(), realtime_peer(), realtime_user(), set_config(), and update_registry().

#define IAX_RTIGNOREREGEXPIRE   (uint64_t)(1 << 21)

When using realtime, ignore registration expiration

Definition at line 424 of file chan_iax2.c.

Referenced by realtime_peer(), and set_config().

#define IAX_RTSAVE_SYSNAME   (uint64_t)(1 << 8)

Save Systname on Realtime Updates

Definition at line 411 of file chan_iax2.c.

Referenced by realtime_update_peer(), and set_config().

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

Send a realtime update

Definition at line 421 of file chan_iax2.c.

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

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

Send ANI along with CallerID

Definition at line 410 of file chan_iax2.c.

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

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

Allow sending of connected line updates

Definition at line 431 of file chan_iax2.c.

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

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

Turn on and off caller id shrinking

Definition at line 434 of file chan_iax2.c.

Referenced by check_access(), and set_config().

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

Temporary (realtime)

Definition at line 405 of file chan_iax2.c.

Referenced by __expire_registry(), realtime_peer(), realtime_user(), reg_source_db(), and update_registry().

#define IAX_TRANSFERMEDIA   (uint64_t)(1 << 23)

When doing IAX2 transfers, transfer media only

Definition at line 426 of file chan_iax2.c.

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

#define IAX_TRUNK   (uint64_t)(1 << 3)

#define IAX_TRUNKTIMESTAMPS   (uint64_t)(1 << 22)

Send trunk timestamps

Definition at line 425 of file chan_iax2.c.

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

#define IAX_USEJITTERBUF   (uint64_t)(1 << 5)

#define MARK_IAX_SUBCLASS_TX   0x8000

Definition at line 629 of file chan_iax2.c.

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

#define MAX_JITTER_BUFFER   50

Definition at line 618 of file chan_iax2.c.

#define MAX_PEER_BUCKETS   563

This module will get much higher performance when doing a lot of user and peer lookups if the number of buckets is increased from 1. However, to maintain old behavior for Asterisk 1.4, these are set to 1 by default. When using multiple buckets, search order through these containers is considered random, so you will not be able to depend on the order the entires are specified in iax.conf for matching order.

Definition at line 880 of file chan_iax2.c.

Referenced by load_objects().

#define MAX_RETRY_TIME   10000

Definition at line 616 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 623 of file chan_iax2.c.

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

#define MAX_TRUNK_MTU   1240

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

Definition at line 261 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_mtu(), and set_config().

#define MAX_TRUNKDATA   640 * 200

40ms, uncompressed linear * 200 channels

Definition at line 285 of file chan_iax2.c.

Referenced by set_config(), and set_config_destroy().

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

Definition at line 884 of file chan_iax2.c.

Referenced by load_module(), and load_objects().

#define MEMORY_SIZE   100

Definition at line 244 of file chan_iax2.c.

#define MIN_JITTER_BUFFER   10

Definition at line 619 of file chan_iax2.c.

#define MIN_RETRY_TIME   100

Definition at line 615 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME   60

Definition at line 249 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 227 of file chan_iax2.c.

#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

Definition at line 626 of file chan_iax2.c.


Enumeration Type Documentation

anonymous enum

Enumerator:
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 2048 of file chan_iax2.c.

02048      {
02049    /* do not allow a new call number, only search ones in use for match */
02050    NEW_PREVENT = 0,
02051    /* search for match first, then allow a new one to be allocated */
02052    NEW_ALLOW = 1,
02053    /* do not search for match, force a new call number */
02054    NEW_FORCE = 2,
02055    /* do not search for match, force a new call number.  Signifies call number
02056     * has been calltoken validated */
02057    NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
02058 };

anonymous enum

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

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

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

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

enum iax2_state

Enumerator:
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 391 of file chan_iax2.c.

00391                 {
00392    IAX_STATE_STARTED =        (1 << 0),
00393    IAX_STATE_AUTHENTICATED =  (1 << 1),
00394    IAX_STATE_TBD =            (1 << 2),
00395 };

Enumerator:
IAX_IOSTATE_IDLE 
IAX_IOSTATE_READY 
IAX_IOSTATE_PROCESSING 
IAX_IOSTATE_SCHEDREADY 

Definition at line 981 of file chan_iax2.c.

Enumerator:
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 988 of file chan_iax2.c.

00988                       {
00989    IAX_THREAD_TYPE_POOL,
00990    IAX_THREAD_TYPE_DYNAMIC,
00991 };

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


Function Documentation

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

Definition at line 3542 of file chan_iax2.c.

References chan_iax2_pvt::addr, iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, ast_channel_name(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_REMOVE, ast_log(), ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, chan_iax2_pvt::error, f, iax_frame::final, frame_queue, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, ast_frame_subclass::integer, LOG_WARNING, MAX_RETRY_TIME, iax_frame::oseqno, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_command(), send_packet(), ast_frame::subclass, iax_frame::transfer, iax_frame::ts, update_packet(), and iax2_registry::us.

Referenced by attempt_transmit().

03543 {
03544    /* Attempt to transmit the frame to the remote peer...
03545       Called without iaxsl held. */
03546    struct iax_frame *f = (struct iax_frame *)data;
03547    int freeme = 0;
03548    int callno = f->callno;
03549    /* Make sure this call is still active */
03550    if (callno) 
03551       ast_mutex_lock(&iaxsl[callno]);
03552    if (callno && iaxs[callno]) {
03553       if ((f->retries < 0) /* Already ACK'd */ ||
03554           (f->retries >= max_retries) /* Too many attempts */) {
03555             /* Record an error if we've transmitted too many times */
03556             if (f->retries >= max_retries) {
03557                if (f->transfer) {
03558                   /* Transfer timeout */
03559                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03560                } else if (f->final) {
03561                   iax2_destroy(callno);
03562                } else {
03563                   if (iaxs[callno]->owner)
03564                      ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),ast_channel_name(iaxs[f->callno]->owner), f->af.frametype, f->af.subclass.integer, f->ts, f->oseqno);
03565                   iaxs[callno]->error = ETIMEDOUT;
03566                   if (iaxs[callno]->owner) {
03567                      struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03568                      /* Hangup the fd */
03569                      iax2_queue_frame(callno, &fr); /* XXX */
03570                      /* Remember, owner could disappear */
03571                      if (iaxs[callno] && iaxs[callno]->owner)
03572                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03573                   } else {
03574                      if (iaxs[callno]->reg) {
03575                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03576                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03577                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03578                      }
03579                      iax2_destroy(callno);
03580                   }
03581                }
03582 
03583             }
03584             freeme = 1;
03585       } else {
03586          /* Update it if it needs it */
03587          update_packet(f);
03588          /* Attempt transmission */
03589          send_packet(f);
03590          f->retries++;
03591          /* Try again later after 10 times as long */
03592          f->retrytime *= 10;
03593          if (f->retrytime > MAX_RETRY_TIME)
03594             f->retrytime = MAX_RETRY_TIME;
03595          /* Transfer messages max out at one second */
03596          if (f->transfer && (f->retrytime > 1000))
03597             f->retrytime = 1000;
03598          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03599       }
03600    } else {
03601       /* Make sure it gets freed */
03602       f->retries = -1;
03603       freeme = 1;
03604    }
03605 
03606    if (freeme) {
03607       /* Don't attempt delivery, just remove it from the queue */
03608       AST_LIST_REMOVE(&frame_queue[callno], f, list);
03609       ast_mutex_unlock(&iaxsl[callno]);
03610       f->retrans = -1; /* this is safe because this is the scheduled function */
03611       /* Free the IAX frame */
03612       iax2_frame_free(f);
03613    } else if (callno) {
03614       ast_mutex_unlock(&iaxsl[callno]);
03615    }
03616 }

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

Definition at line 9046 of file chan_iax2.c.

References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, iax_ie_data::buf, IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iax_ie_data::pos, and send_command_final().

Referenced by auth_reject().

09047 {
09048    /* Called from IAX thread only, without iaxs lock */
09049    int callno = (int)(long)(nothing);
09050    struct iax_ie_data ied;
09051    ast_mutex_lock(&iaxsl[callno]);
09052    if (iaxs[callno]) {
09053       memset(&ied, 0, sizeof(ied));
09054       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
09055          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
09056          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
09057       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
09058          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
09059          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09060       }
09061       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
09062    }
09063    ast_mutex_unlock(&iaxsl[callno]);
09064 }

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

Definition at line 4728 of file chan_iax2.c.

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

Referenced by auto_congest().

04729 {
04730    int callno = PTR_TO_CALLNO(nothing);
04731    struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04732    ast_mutex_lock(&iaxsl[callno]);
04733    if (iaxs[callno]) {
04734       iaxs[callno]->initid = -1;
04735       iax2_queue_frame(callno, &f);
04736       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04737    }
04738    ast_mutex_unlock(&iaxsl[callno]);
04739 }

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

Definition at line 9095 of file chan_iax2.c.

References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, iax_ie_data::buf, IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iax_ie_data::pos, and send_command_final().

Referenced by auto_hangup().

09096 {
09097    /* Called from IAX thread only, without iaxs lock */
09098    int callno = (int)(long)(nothing);
09099    struct iax_ie_data ied;
09100    ast_mutex_lock(&iaxsl[callno]);
09101    if (iaxs[callno]) {
09102       memset(&ied, 0, sizeof(ied));
09103       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09104       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09105       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09106    }
09107    ast_mutex_unlock(&iaxsl[callno]);
09108 }

static int __do_deliver ( void *  data  )  [static]

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

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

Referenced by __get_from_jb(), and schedule_delivery().

03329 {
03330    /* Just deliver the packet by using queueing.  This is called by
03331      the IAX thread with the iaxsl lock held. */
03332    struct iax_frame *fr = data;
03333    fr->retrans = -1;
03334    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03335    if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03336       iax2_queue_frame(fr->callno, &fr->af);
03337    /* Free our iax frame */
03338    iax2_frame_free(fr);
03339    /* And don't run again */
03340    return 0;
03341 }

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

Definition at line 8673 of file chan_iax2.c.

References iax2_peer::addr, ast_db_del(), ast_debug, AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_test_flag64, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event, iax2_peer::name, peer_unref(), peercnt_modify(), realtime_update_peer(), register_peer_exten(), and unlink_peer().

Referenced by expire_registry().

08674 {
08675    struct iax2_peer *peer = (struct iax2_peer *) data;
08676 
08677    if (!peer)
08678       return;
08679    if (peer->expire == -1) {
08680       /* Removed already (possibly through CLI), ignore */
08681       return;
08682    }
08683 
08684    peer->expire = -1;
08685 
08686    ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08687    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08688       realtime_update_peer(peer->name, &peer->addr, 0);
08689    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08690    /* modify entry in peercnts table as _not_ registered */
08691    peercnt_modify(0, 0, &peer->addr);
08692    /* Reset the address */
08693    memset(&peer->addr, 0, sizeof(peer->addr));
08694    /* Reset expiry value */
08695    peer->expiry = min_reg_expire;
08696    if (!ast_test_flag64(peer, IAX_TEMPONLY))
08697       ast_db_del("IAX/Registry", peer->name);
08698    register_peer_exten(peer, 0);
08699    ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
08700    if (iax2_regfunk)
08701       iax2_regfunk(peer->name, 0);
08702 
08703    if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08704       unlink_peer(peer);
08705 
08706    peer_unref(peer);
08707 }

static int __find_callno ( unsigned short  callno,
unsigned short  dcallno,
struct sockaddr_in *  sin,
int  new,
int  sockfd,
int  return_locked,
int  check_dcallno 
) [static]

Definition at line 2831 of file chan_iax2.c.

References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ao2_find, ao2_ref, ast_copy_flags64, ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_set, callno_entry::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), iax2_getpeername(), iax2_sched_add(), IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, chan_iax2_pvt::lagid, LOG_WARNING, match(), NEW_ALLOW, new_iax(), OBJ_POINTER, parkinglot, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, replace_callno(), send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), chan_iax2_pvt::transfer, TRUNK_CALL_START, and update_max_nontrunk().

Referenced by find_callno(), and find_callno_locked().

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

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

Definition at line 4120 of file chan_iax2.c.

References __do_deliver(), ast_codec_interp_len(), ast_format_copy(), ast_format_from_old_bitfield(), ast_format_rate(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_test_flag64, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), jb_frame::data, ast_frame::delivery, ast_frame_subclass::format, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.

Referenced by get_from_jb().

04121 {
04122    int callno = PTR_TO_CALLNO(p);
04123    struct chan_iax2_pvt *pvt = NULL;
04124    struct iax_frame *fr;
04125    jb_frame frame;
04126    int ret;
04127    long ms;
04128    long next;
04129    struct timeval now = ast_tvnow();
04130    
04131    /* Make sure we have a valid private structure before going on */
04132    ast_mutex_lock(&iaxsl[callno]);
04133    pvt = iaxs[callno];
04134    if (!pvt) {
04135       /* No go! */
04136       ast_mutex_unlock(&iaxsl[callno]);
04137       return;
04138    }
04139 
04140    pvt->jbid = -1;
04141    
04142    /* round up a millisecond since ast_sched_runq does; */
04143    /* prevents us from spinning while waiting for our now */
04144    /* to catch up with runq's now */
04145    now.tv_usec += 1000;
04146    
04147    ms = ast_tvdiff_ms(now, pvt->rxcore);
04148    
04149    if(ms >= (next = jb_next(pvt->jb))) {
04150       struct ast_format voicefmt;
04151       ast_format_from_old_bitfield(&voicefmt, pvt->voiceformat);
04152       ret = jb_get(pvt->jb, &frame, ms, ast_codec_interp_len(&voicefmt));
04153       switch(ret) {
04154       case JB_OK:
04155          fr = frame.data;
04156          __do_deliver(fr);
04157          /* __do_deliver() can cause the call to disappear */
04158          pvt = iaxs[callno];
04159          break;
04160       case JB_INTERP:
04161       {
04162          struct ast_frame af = { 0, };
04163          
04164          /* create an interpolation frame */
04165          af.frametype = AST_FRAME_VOICE;
04166          ast_format_copy(&af.subclass.format, &voicefmt);
04167          af.samples  = frame.ms * (ast_format_rate(&voicefmt) / 1000);
04168          af.src  = "IAX2 JB interpolation";
04169          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
04170          af.offset = AST_FRIENDLY_OFFSET;
04171          
04172          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
04173           * which we'd need to malloc, and then it would free it.  That seems like a drag */
04174          if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
04175             iax2_queue_frame(callno, &af);
04176             /* iax2_queue_frame() could cause the call to disappear */
04177             pvt = iaxs[callno];
04178          }
04179       }
04180          break;
04181       case JB_DROP:
04182          iax2_frame_free(frame.data);
04183          break;
04184       case JB_NOFRAME:
04185       case JB_EMPTY:
04186          /* do nothing */
04187          break;
04188       default:
04189          /* shouldn't happen */
04190          break;
04191       }
04192    }
04193    if (pvt)
04194       update_jbsched(pvt);
04195    ast_mutex_unlock(&iaxsl[callno]);
04196 }

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

Definition at line 8343 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

08344 {
08345    struct iax2_registry *reg = (struct iax2_registry *)data;
08346    reg->expire = -1;
08347    iax2_do_register(reg);
08348 }

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

Definition at line 12047 of file chan_iax2.c.

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

Referenced by iax2_poke_noanswer().

12048 {
12049    struct iax2_peer *peer = (struct iax2_peer *)data;
12050    int callno;
12051 
12052    if (peer->lastms > -1) {
12053       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
12054       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
12055       ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
12056    }
12057    if ((callno = peer->callno) > 0) {
12058       ast_mutex_lock(&iaxsl[callno]);
12059       iax2_destroy(callno);
12060       ast_mutex_unlock(&iaxsl[callno]);
12061    }
12062    peer->callno = 0;
12063    peer->lastms = -1;
12064    /* Try again quickly */
12065    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
12066    if (peer->pokeexpire == -1)
12067       peer_unref(peer);
12068 }

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

Definition at line 9155 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

09156 {
09157    struct iax2_peer *peer = (struct iax2_peer *)data;
09158    iax2_poke_peer(peer, 0);
09159    peer_unref(peer);
09160 }

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

Definition at line 6716 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().

06717 {
06718    regex_t regexbuf;
06719    int havepattern = 0;
06720    int total_peers = 0;
06721    int online_peers = 0;
06722    int offline_peers = 0;
06723    int unmonitored_peers = 0;
06724    struct ao2_iterator i;
06725 
06726 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-11s %-32.32s\n"
06727 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-11s %-32.32s\n"
06728 
06729    struct iax2_peer *peer = NULL;
06730    char name[256];
06731    struct ast_str *encmethods = ast_str_alloca(256);
06732    int registeredonly=0;
06733    char idtext[256] = "";
06734    switch (argc) {
06735    case 6:
06736       if (!strcasecmp(argv[3], "registered"))
06737          registeredonly = 1;
06738       else
06739          return RESULT_SHOWUSAGE;
06740       if (!strcasecmp(argv[4], "like")) {
06741          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06742             return RESULT_SHOWUSAGE;
06743          havepattern = 1;
06744       } else
06745          return RESULT_SHOWUSAGE;
06746       break;
06747    case 5:
06748       if (!strcasecmp(argv[3], "like")) {
06749          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06750             return RESULT_SHOWUSAGE;
06751          havepattern = 1;
06752       } else
06753          return RESULT_SHOWUSAGE;
06754       break;
06755    case 4:
06756       if (!strcasecmp(argv[3], "registered"))
06757          registeredonly = 1;
06758       else
06759          return RESULT_SHOWUSAGE;
06760       break;
06761    case 3:
06762       break;
06763    default:
06764       return RESULT_SHOWUSAGE;
06765    }
06766 
06767 
06768    if (!s)
06769       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", "Description");
06770 
06771    i = ao2_iterator_init(peers, 0);
06772    for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
06773       char nm[20];
06774       char status[20];
06775       int retstatus;
06776       struct sockaddr_in peer_addr;
06777 
06778       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06779 
06780       if (registeredonly && !peer_addr.sin_addr.s_addr) {
06781          continue;
06782       }
06783       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0)) {
06784          continue;
06785       }
06786 
06787       if (!ast_strlen_zero(peer->username))
06788          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06789       else
06790          ast_copy_string(name, peer->name, sizeof(name));
06791 
06792       encmethods_to_str(peer->encmethods, encmethods);
06793       retstatus = peer_status(peer, status, sizeof(status));
06794       if (retstatus > 0)
06795          online_peers++;
06796       else if (!retstatus)
06797          offline_peers++;
06798       else
06799          unmonitored_peers++;
06800 
06801       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06802 
06803       if (s) {
06804          astman_append(s,
06805             "Event: PeerEntry\r\n%s"
06806             "Channeltype: IAX2\r\n"
06807             "ObjectName: %s\r\n"
06808             "ChanObjectType: peer\r\n"
06809             "IPaddress: %s\r\n"
06810             "IPport: %d\r\n"
06811             "Dynamic: %s\r\n"
06812             "Trunk: %s\r\n"
06813             "Encryption: %s\r\n"
06814             "Status: %s\r\n"
06815             "Description: %s\r\n\r\n",
06816             idtext,
06817             name,
06818             ast_sockaddr_stringify_addr(&peer->addr),
06819             ast_sockaddr_port(&peer->addr),
06820             ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06821             ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06822             peer->encmethods ? ast_str_buffer(encmethods) : "no",
06823             status,
06824             peer->description);
06825       } else {
06826          ast_cli(fd, FORMAT, name,
06827             ast_sockaddr_stringify_addr(&peer->addr),
06828             ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06829             nm,
06830             ast_sockaddr_port(&peer->addr),
06831             ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : "   ",
06832             peer->encmethods ? "(E)" : "   ",
06833             status,
06834             peer->description);
06835       }
06836       total_peers++;
06837    }
06838    ao2_iterator_destroy(&i);
06839 
06840    if (!s)
06841       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06842          total_peers, online_peers, offline_peers, unmonitored_peers);
06843 
06844    if (havepattern)
06845       regfree(&regexbuf);
06846 
06847    if (total)
06848       *total = total_peers;
06849 
06850    return RESULT_SUCCESS;
06851 #undef FORMAT
06852 #undef FORMAT2
06853 }

static void __reg_module ( void   )  [static]

Definition at line 14896 of file chan_iax2.c.

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

Definition at line 1460 of file chan_iax2.c.

References ast_copy_string(), ast_debug, iax2_thread::cond, iax2_thread::curfunc, find_idle_thread(), IAX_IOSTATE_SCHEDREADY, iax2_thread::iostate, iax2_thread::lock, iax2_thread::scheddata, iax2_thread::schedfunc, signal_condition(), and thread.

01461 {
01462    struct iax2_thread *thread = NULL;
01463    static time_t lasterror;
01464    static time_t t;
01465 
01466    thread = find_idle_thread();
01467 
01468    if (thread != NULL) {
01469       thread->schedfunc = func;
01470       thread->scheddata = data;
01471       thread->iostate = IAX_IOSTATE_SCHEDREADY;
01472 #ifdef DEBUG_SCHED_MULTITHREAD
01473       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01474 #endif
01475       signal_condition(&thread->lock, &thread->cond);
01476       return 0;
01477    }
01478    time(&t);
01479    if (t != lasterror)
01480       ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01481    lasterror = t;
01482 
01483    return -1;
01484 }

static int __send_command ( struct chan_iax2_pvt i,
char  type,
int  command,
unsigned int  ts,
const unsigned char *  data,
int  datalen,
int  seqno,
int  now,
int  transfer,
int  final 
) [static]

Definition at line 7542 of file chan_iax2.c.

References ast_frame::data, ast_frame::datalen, ast_frame::frametype, iax2_send(), ast_frame_subclass::integer, ast_frame::ptr, queue_signalling(), ast_frame::src, and ast_frame::subclass.

Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().

07544 {
07545    struct ast_frame f = { 0, };
07546    int res = 0;
07547 
07548    f.frametype = type;
07549    f.subclass.integer = command;
07550    f.datalen = datalen;
07551    f.src = __FUNCTION__;
07552    f.data.ptr = (void *) data;
07553 
07554    if ((res = queue_signalling(i, &f)) <= 0) {
07555       return res;
07556    }
07557 
07558    return iax2_send(i, &f, ts, seqno, now, transfer, final);
07559 }

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

Definition at line 1569 of file chan_iax2.c.

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

Referenced by send_lagrq().

01570 {
01571    int callno = (long) data;
01572 
01573    ast_mutex_lock(&iaxsl[callno]);
01574 
01575    if (iaxs[callno]) {
01576       if (iaxs[callno]->peercallno) {
01577          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01578          if (iaxs[callno]->lagid != DONT_RESCHEDULE) {
01579             iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01580          }
01581       }
01582    } else {
01583       ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01584    }
01585 
01586    ast_mutex_unlock(&iaxsl[callno]);
01587 }

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

Definition at line 1502 of file chan_iax2.c.

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

Referenced by send_ping().

01503 {
01504    int callno = (long) data;
01505 
01506    ast_mutex_lock(&iaxsl[callno]);
01507 
01508    if (iaxs[callno]) {
01509       if (iaxs[callno]->peercallno) {
01510          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01511          if (iaxs[callno]->pingid != DONT_RESCHEDULE) {
01512             iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01513          }
01514       }
01515    } else {
01516       ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01517    }
01518 
01519    ast_mutex_unlock(&iaxsl[callno]);
01520 }

static int __unload_module ( void   )  [static]

Definition at line 14382 of file chan_iax2.c.

References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), ast_data_unregister, ast_format_cap_destroy(), ast_manager_unregister(), ast_mutex_destroy, ast_netsock_release(), AST_PTHREADT_NULL, ast_sched_context_destroy(), ast_taskprocessor_unreference(), AST_TEST_UNREGISTER, ast_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), ast_channel_tech::capabilities, cleanup_thread_list(), delete_users(), iax2_destroy(), iax_provision_unload(), network_change_event_unsubscribe(), and reload_firmware().

14383 {
14384    struct ast_context *con;
14385    int x;
14386 
14387    network_change_event_unsubscribe();
14388 
14389    ast_manager_unregister("IAXpeers");
14390    ast_manager_unregister("IAXpeerlist");
14391    ast_manager_unregister("IAXnetstats");
14392    ast_manager_unregister("IAXregistry");
14393    ast_unregister_application(papp);
14394    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14395    ast_unregister_switch(&iax2_switch);
14396    ast_channel_unregister(&iax2_tech);
14397 
14398    if (netthreadid != AST_PTHREADT_NULL) {
14399       pthread_cancel(netthreadid);
14400       pthread_kill(netthreadid, SIGURG);
14401       pthread_join(netthreadid, NULL);
14402    }
14403 
14404    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14405       if (iaxs[x]) {
14406          iax2_destroy(x);
14407       }
14408    }
14409 
14410    /* Call for all threads to halt */
14411    cleanup_thread_list(&idle_list);
14412    cleanup_thread_list(&active_list);
14413    cleanup_thread_list(&dynamic_list);
14414 
14415    ast_netsock_release(netsock);
14416    ast_netsock_release(outsock);
14417    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14418       if (iaxs[x]) {
14419          iax2_destroy(x);
14420       }
14421    }
14422    ast_manager_unregister( "IAXpeers" );
14423    ast_manager_unregister( "IAXpeerlist" );
14424    ast_manager_unregister( "IAXnetstats" );
14425    ast_manager_unregister( "IAXregistry" );
14426    ast_unregister_application(papp);
14427 #ifdef TEST_FRAMEWORK
14428    AST_TEST_UNREGISTER(test_iax2_peers_get);
14429    AST_TEST_UNREGISTER(test_iax2_users_get);
14430 #endif
14431    ast_data_unregister(NULL);
14432    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14433    ast_unregister_switch(&iax2_switch);
14434    ast_channel_unregister(&iax2_tech);
14435    delete_users();
14436    iax_provision_unload();
14437    reload_firmware(1);
14438 
14439    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14440       ast_mutex_destroy(&iaxsl[x]);
14441    }
14442 
14443    ao2_ref(peers, -1);
14444    ao2_ref(users, -1);
14445    ao2_ref(iax_peercallno_pvts, -1);
14446    ao2_ref(iax_transfercallno_pvts, -1);
14447    ao2_ref(peercnts, -1);
14448    ao2_ref(callno_limits, -1);
14449    ao2_ref(calltoken_ignores, -1);
14450    ao2_ref(callno_pool, -1);
14451    ao2_ref(callno_pool_trunk, -1);
14452    if (timer) {
14453       ast_timer_close(timer);
14454    }
14455    transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14456    ast_sched_context_destroy(sched);
14457    sched = NULL;
14458 
14459    con = ast_context_find(regcontext);
14460    if (con)
14461       ast_context_destroy(con, "IAX2");
14462    ast_unload_realtime("iaxpeers");
14463 
14464    iax2_tech.capabilities = ast_format_cap_destroy(iax2_tech.capabilities);
14465    return 0;
14466 }

static void __unreg_module ( void   )  [static]

Definition at line 14896 of file chan_iax2.c.

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

Definition at line 14022 of file chan_iax2.c.

References chan_iax2_pvt::addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, chan_iax2_pvt::callno, IAX_CALLENCRYPTED, LOG_ERROR, chan_iax2_pvt::osptoken, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, and chan_iax2_pvt::username.

14023 {
14024    struct chan_iax2_pvt *pvt;
14025    unsigned int callno;
14026    int res = 0;
14027 
14028    if (!chan || chan->tech != &iax2_tech) {
14029       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
14030       return -1;
14031    }
14032 
14033    callno = PTR_TO_CALLNO(chan->tech_pvt);
14034    ast_mutex_lock(&iaxsl[callno]);
14035    if (!(pvt = iaxs[callno])) {
14036       ast_mutex_unlock(&iaxsl[callno]);
14037       return -1;
14038    }
14039 
14040    if (!strcasecmp(args, "osptoken")) {
14041       ast_copy_string(buf, pvt->osptoken, buflen);
14042    } else if (!strcasecmp(args, "peerip")) {
14043       ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
14044    } else if (!strcasecmp(args, "peername")) {
14045       ast_copy_string(buf, pvt->username, buflen);
14046    } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
14047       snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
14048    } else {
14049       res = -1;
14050    }
14051 
14052    ast_mutex_unlock(&iaxsl[callno]);
14053 
14054    return res;
14055 }

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

Definition at line 9869 of file chan_iax2.c.

References ast_channel_datastore_find(), ast_copy_string(), AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_datastore::data, ast_var_t::entries, ast_var_t::name, ast_var_t::value, and var.

09870 {
09871    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09872    AST_LIST_HEAD(, ast_var_t) *varlist;
09873    struct ast_var_t *var;
09874 
09875    if (!variablestore) {
09876       *buf = '\0';
09877       return 0;
09878    }
09879    varlist = variablestore->data;
09880 
09881    AST_LIST_LOCK(varlist);
09882    AST_LIST_TRAVERSE(varlist, var, entries) {
09883       if (strcmp(var->name, data) == 0) {
09884          ast_copy_string(buf, var->value, len);
09885          break;
09886       }
09887    }
09888    AST_LIST_UNLOCK(varlist);
09889    return 0;
09890 }

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

Definition at line 9892 of file chan_iax2.c.

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

09893 {
09894    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09895    AST_LIST_HEAD(, ast_var_t) *varlist;
09896    struct ast_var_t *var;
09897 
09898    if (!variablestore) {
09899       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09900       if (!variablestore) {
09901          ast_log(LOG_ERROR, "Memory allocation error\n");
09902          return -1;
09903       }
09904       varlist = ast_calloc(1, sizeof(*varlist));
09905       if (!varlist) {
09906          ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09907          return -1;
09908       }
09909 
09910       AST_LIST_HEAD_INIT(varlist);
09911       variablestore->data = varlist;
09912       variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09913       ast_channel_datastore_add(chan, variablestore);
09914    } else
09915       varlist = variablestore->data;
09916 
09917    AST_LIST_LOCK(varlist);
09918    AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09919       if (strcmp(var->name, data) == 0) {
09920          AST_LIST_REMOVE_CURRENT(entries);
09921          ast_var_delete(var);
09922          break;
09923       }
09924    }
09925    AST_LIST_TRAVERSE_SAFE_END;
09926    var = ast_var_assign(data, value);
09927    if (var)
09928       AST_LIST_INSERT_TAIL(varlist, var, entries);
09929    else
09930       ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09931    AST_LIST_UNLOCK(varlist);
09932    return 0;
09933 }

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

Definition at line 2572 of file chan_iax2.c.

References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), ast_strlen_zero(), addr_range::delme, addr_range::ha, LOG_WARNING, and OBJ_POINTER.

Referenced by set_config().

02573 {
02574    struct addr_range tmp;
02575    struct addr_range *addr_range = NULL;
02576    struct ast_ha *ha = NULL;
02577    int error = 0;
02578 
02579    if (ast_strlen_zero(addr)) {
02580       ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02581       return -1;
02582    }
02583 
02584    ha = ast_append_ha("permit", addr, NULL, &error);
02585 
02586    /* check for valid config information */
02587    if (error) {
02588       ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02589       return -1;
02590    }
02591 
02592    ast_copy_ha(ha, &tmp.ha);
02593    /* find or create the addr_range */
02594    if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02595       ao2_lock(addr_range);
02596       addr_range->delme = 0;
02597       ao2_unlock(addr_range);
02598    } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02599       /* copy over config data into addr_range object */
02600       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
02601       ao2_link(calltoken_ignores, addr_range);
02602    } else {
02603       ast_free_ha(ha);
02604       return -1;
02605    }
02606 
02607    ast_free_ha(ha);
02608    ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02609 
02610    return 0;
02611 }

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

Definition at line 4802 of file chan_iax2.c.

References iax_ie_data::buf, chan_iax2_pvt::calltoken_ie_len, IAX_IE_CALLTOKEN, and iax_ie_data::pos.

Referenced by cache_get_callno_locked(), iax2_call(), iax2_do_register(), iax2_poke_peer(), and registry_rerequest().

04803 {
04804    /* first make sure their are two empty bytes left in ied->buf */
04805    if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04806       ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;  /* type */
04807       ied->buf[ied->pos++] = 0;   /* data size,  ZERO in this case */
04808       pvt->calltoken_ie_len = 2;
04809    }
04810 }

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

Definition at line 2224 of file chan_iax2.c.

References ast_ha::addr, ast_sockaddr_cmp_addr(), CMP_MATCH, CMP_STOP, addr_range::ha, and ast_ha::netmask.

Referenced by load_objects().

02225 {
02226    struct addr_range *lim1 = obj, *lim2 = arg;
02227    return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
02228          !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
02229          CMP_MATCH | CMP_STOP : 0;
02230 }

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

Definition at line 2209 of file chan_iax2.c.

References addr_range::delme.

Referenced by set_config_destroy().

02210 {
02211    struct addr_range *lim = obj;
02212    lim->delme = 1;
02213    return 0;
02214 }

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

Definition at line 2216 of file chan_iax2.c.

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

Referenced by load_objects().

02217 {
02218    const struct addr_range *lim = obj;
02219    struct sockaddr_in sin;
02220    ast_sockaddr_to_sin(&lim->ha.addr, &sin);
02221    return abs((int) sin.sin_addr.s_addr);
02222 }

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

Definition at line 2244 of file chan_iax2.c.

References ast_ha::addr, ast_sockaddr_to_sin, CMP_MATCH, CMP_STOP, addr_range::ha, and ast_ha::netmask.

Referenced by calltoken_required(), and set_peercnt_limit().

02245 {
02246    struct addr_range *addr_range = obj;
02247    struct sockaddr_in *sin = arg;
02248    struct sockaddr_in ha_netmask_sin;
02249    struct sockaddr_in ha_addr_sin;
02250 
02251    ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin);
02252    ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin);
02253 
02254    if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) {
02255       return CMP_MATCH | CMP_STOP;
02256    }
02257    return 0;
02258 }

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

Definition at line 7600 of file chan_iax2.c.

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

Referenced by check_access().

07601 {
07602    while(con) {
07603       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07604          return -1;
07605       con = con->next;
07606    }
07607    return 0;
07608 }

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

Definition at line 7301 of file chan_iax2.c.

References ACN_FORMAT1, ACN_FORMAT2, ARRAY_LEN, ast_channel_name(), ast_cli(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, astman_append(), jb_info::current, iax_rr::delay, iax_rr::dropped, chan_iax2_pvt::first_iax_message, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, iax_frame_subclass2str(), IAX_USEJITTERBUF, jb_getinfo(), iax_rr::jitter, jb_info::jitter, chan_iax2_pvt::last_iax_message, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, MARK_IAX_SUBCLASS_TX, jb_info::min, iax_rr::ooo, iax_rr::packets, and chan_iax2_pvt::remote_rr.

Referenced by handle_cli_iax2_show_netstats(), and manager_iax2_show_netstats().

07302 {
07303    int x;
07304    int numchans = 0;
07305    char first_message[10] = { 0, };
07306    char last_message[10] = { 0, };
07307 #define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
07308 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07309    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07310       ast_mutex_lock(&iaxsl[x]);
07311       if (iaxs[x]) {
07312          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07313          jb_info jbinfo;
07314          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07315          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07316 
07317          if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07318             jb_getinfo(iaxs[x]->jb, &jbinfo);
07319             localjitter = jbinfo.jitter;
07320             localdelay = jbinfo.current - jbinfo.min;
07321             locallost = jbinfo.frames_lost;
07322             locallosspct = jbinfo.losspct/1000;
07323             localdropped = jbinfo.frames_dropped;
07324             localooo = jbinfo.frames_ooo;
07325          } else {
07326             localjitter = -1;
07327             localdelay = 0;
07328             locallost = -1;
07329             locallosspct = -1;
07330             localdropped = 0;
07331             localooo = -1;
07332          }
07333          if (s)
07334             astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07335                iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
07336                iaxs[x]->pingtime,
07337                localjitter,
07338                localdelay,
07339                locallost,
07340                locallosspct,
07341                localdropped,
07342                localooo,
07343                iaxs[x]->frames_received/1000,
07344                iaxs[x]->remote_rr.jitter,
07345                iaxs[x]->remote_rr.delay,
07346                iaxs[x]->remote_rr.losscnt,
07347                iaxs[x]->remote_rr.losspct,
07348                iaxs[x]->remote_rr.dropped,
07349                iaxs[x]->remote_rr.ooo,
07350                iaxs[x]->remote_rr.packets/1000,
07351                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07352                first_message,
07353                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07354                last_message);
07355          else
07356             ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07357                iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
07358                iaxs[x]->pingtime,
07359                localjitter,
07360                localdelay,
07361                locallost,
07362                locallosspct,
07363                localdropped,
07364                localooo,
07365                iaxs[x]->frames_received/1000,
07366                iaxs[x]->remote_rr.jitter,
07367                iaxs[x]->remote_rr.delay,
07368                iaxs[x]->remote_rr.losscnt,
07369                iaxs[x]->remote_rr.losspct,
07370                iaxs[x]->remote_rr.dropped,
07371                iaxs[x]->remote_rr.ooo,
07372                iaxs[x]->remote_rr.packets/1000,
07373                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07374                first_message,
07375                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07376                last_message);
07377          numchans++;
07378       }
07379       ast_mutex_unlock(&iaxsl[x]);
07380    }
07381 
07382    return numchans;
07383 }

AST_DATA_STRUCTURE ( iax2_user  ,
DATA_EXPORT_IAX2_USER   
)

AST_DATA_STRUCTURE ( iax2_peer  ,
DATA_EXPORT_IAX2_PEER   
)

static struct ast_channel* ast_iax2_new ( int  callno,
int  state,
iax2_format  capability,
const char *  linkedid 
) [static, read]

Create new call, interface with the PBX core.

Definition at line 5787 of file chan_iax2.c.

References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, ast_party_caller::ani, chan_iax2_pvt::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_calloc, ast_channel_alloc, ast_channel_datastore_add(), ast_channel_name(), ast_channel_release(), ast_copy_string(), ast_datastore_alloc, ast_datastore_free(), ast_debug, ast_format_cap_from_old_bitfield(), ast_format_copy(), ast_free, ast_hangup(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_module_ref(), ast_mutex_lock, ast_mutex_unlock, ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_strlen_zero(), ast_var_assign(), ast_channel::caller, chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, chan_iax2_pvt::cid_name, chan_iax2_pvt::cid_num, ast_channel::context, chan_iax2_pvt::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::dialed, chan_iax2_pvt::dnid, ast_var_t::entries, ast_channel::exten, chan_iax2_pvt::exten, ast_party_redirecting::from, chan_iax2_pvt::host, iax2_ami_channelupdate(), chan_iax2_pvt::iaxvars, ast_party_caller::id, ast_datastore::inheritance, chan_iax2_pvt::language, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_party_id::name, ast_channel::nativeformats, ast_variable::next, ast_party_dialed::number, ast_party_id::number, chan_iax2_pvt::owner, chan_iax2_pvt::parkinglot, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, ast_channel::rawreadformat, ast_channel::rawwriteformat, chan_iax2_pvt::rdnis, ast_channel::readformat, ast_channel::redirecting, ast_party_dialed::str, ast_party_number::str, ast_channel::tech, ast_channel::tech_pvt, ast_party_dialed::transit_network_select, ast_party_number::valid, ast_variable::value, var, chan_iax2_pvt::vars, and ast_channel::writeformat.

Referenced by iax2_request(), and socket_process().

05788 {
05789    struct ast_channel *tmp;
05790    struct chan_iax2_pvt *i;
05791    struct ast_variable *v = NULL;
05792    struct ast_format tmpfmt;
05793 
05794    if (!(i = iaxs[callno])) {
05795       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05796       return NULL;
05797    }
05798 
05799    /* Don't hold call lock */
05800    ast_mutex_unlock(&iaxsl[callno]);
05801    tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
05802    ast_mutex_lock(&iaxsl[callno]);
05803    if (i != iaxs[callno]) {
05804       if (tmp) {
05805          /* unlock and relock iaxsl[callno] to preserve locking order */
05806          ast_mutex_unlock(&iaxsl[callno]);
05807          tmp = ast_channel_release(tmp);
05808          ast_mutex_lock(&iaxsl[callno]);
05809       }
05810       return NULL;
05811    }
05812    iax2_ami_channelupdate(i);
05813    if (!tmp)
05814       return NULL;
05815    tmp->tech = &iax2_tech;
05816    /* We can support any format by default, until we get restricted */
05817    ast_format_cap_from_old_bitfield(tmp->nativeformats, capability);
05818    ast_best_codec(tmp->nativeformats, &tmpfmt);
05819 
05820    ast_format_copy(&tmp->readformat, &tmpfmt);
05821    ast_format_copy(&tmp->rawreadformat, &tmpfmt);
05822    ast_format_copy(&tmp->writeformat, &tmpfmt);
05823    ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
05824 
05825    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05826 
05827    if (!ast_strlen_zero(i->parkinglot))
05828       ast_channel_parkinglot_set(tmp, i->parkinglot);
05829    /* Don't use ast_set_callerid() here because it will
05830     * generate a NewCallerID event before the NewChannel event */
05831    if (!ast_strlen_zero(i->ani)) {
05832       tmp->caller.ani.number.valid = 1;
05833       tmp->caller.ani.number.str = ast_strdup(i->ani);
05834    } else if (!ast_strlen_zero(i->cid_num)) {
05835       tmp->caller.ani.number.valid = 1;
05836       tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05837    }
05838    tmp->dialed.number.str = ast_strdup(i->dnid);
05839    if (!ast_strlen_zero(i->rdnis)) {
05840       tmp->redirecting.from.number.valid = 1;
05841       tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05842    }
05843    tmp->caller.id.name.presentation = i->calling_pres;
05844    tmp->caller.id.number.presentation = i->calling_pres;
05845    tmp->caller.id.number.plan = i->calling_ton;
05846    tmp->dialed.transit_network_select = i->calling_tns;
05847    if (!ast_strlen_zero(i->language))
05848       ast_channel_language_set(tmp, i->language);
05849    if (!ast_strlen_zero(i->accountcode))
05850       ast_channel_accountcode_set(tmp, i->accountcode);
05851    if (i->amaflags)
05852       tmp->amaflags = i->amaflags;
05853    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05854    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05855    if (i->adsi)
05856       tmp->adsicpe = i->peeradsicpe;
05857    else
05858       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05859    i->owner = tmp;
05860    i->capability = capability;
05861 
05862    /* Set inherited variables */
05863    if (i->vars) {
05864       for (v = i->vars ; v ; v = v->next)
05865          pbx_builtin_setvar_helper(tmp, v->name, v->value);
05866    }
05867    if (i->iaxvars) {
05868       struct ast_datastore *variablestore;
05869       struct ast_variable *var, *prev = NULL;
05870       AST_LIST_HEAD(, ast_var_t) *varlist;
05871       ast_debug(1, "Loading up the channel with IAXVARs\n");
05872       varlist = ast_calloc(1, sizeof(*varlist));
05873       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05874       if (variablestore && varlist) {
05875          variablestore->data = varlist;
05876          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05877          AST_LIST_HEAD_INIT(varlist);
05878          for (var = i->iaxvars; var; var = var->next) {
05879             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05880             if (prev)
05881                ast_free(prev);
05882             prev = var;
05883             if (!newvar) {
05884                /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
05885                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05886             } else {
05887                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05888             }
05889          }
05890          if (prev)
05891             ast_free(prev);
05892          i->iaxvars = NULL;
05893          ast_channel_datastore_add(i->owner, variablestore);
05894       } else {
05895          if (variablestore) {
05896             ast_datastore_free(variablestore);
05897          }
05898          if (varlist) {
05899             ast_free(varlist);
05900          }
05901       }
05902    }
05903 
05904    if (state != AST_STATE_DOWN) {
05905       if (ast_pbx_start(tmp)) {
05906          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
05907          ast_hangup(tmp);
05908          i->owner = NULL;
05909          return NULL;
05910       }
05911    }
05912 
05913    ast_module_ref(ast_module_info->self);
05914    return tmp;
05915 }

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

Definition at line 3618 of file chan_iax2.c.

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and transmit_frame().

03619 {
03620 #ifdef SCHED_MULTITHREADED
03621    if (schedule_action(__attempt_transmit, data))
03622 #endif      
03623       __attempt_transmit(data);
03624    return 0;
03625 }

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

Definition at line 9080 of file chan_iax2.c.

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

Referenced by socket_process().

09081 {
09082    /* Schedule sending the authentication failure in one second, to prevent
09083       guessing */
09084    if (iaxs[callno]) {
09085       iaxs[callno]->authfail = failcode;
09086       if (delayreject) {
09087          iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 
09088             sched, 1000, auth_reject, (void *)(long)callno);
09089       } else
09090          auth_reject((void *)(long)callno);
09091    }
09092    return 0;
09093 }

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

Definition at line 9066 of file chan_iax2.c.

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

Referenced by auth_fail().

09067 {
09068    int callno = (int)(long)(data);
09069    ast_mutex_lock(&iaxsl[callno]);
09070    if (iaxs[callno])
09071       iaxs[callno]->authid = -1;
09072    ast_mutex_unlock(&iaxsl[callno]);
09073 #ifdef SCHED_MULTITHREADED
09074    if (schedule_action(__auth_reject, data))
09075 #endif      
09076       __auth_reject(data);
09077    return 0;
09078 }

static int authenticate ( const char *  challenge,
const char *  secret,
const char *  keyn,
int  authmethods,
struct iax_ie_data ied,
struct sockaddr_in *  sin,
struct chan_iax2_pvt pvt 
) [static]

Definition at line 8165 of file chan_iax2.c.

References ast_inet_ntoa(), ast_key_get(), AST_KEY_PRIVATE, ast_log(), ast_sign(), ast_strlen_zero(), build_encryption_keys(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, iax_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, LOG_NOTICE, MD5Final(), MD5Init(), and MD5Update().

Referenced by action_login(), authenticate_reply(), and registry_rerequest().

08166 {
08167    int res = -1;
08168    int x;
08169    if (!ast_strlen_zero(keyn)) {
08170       if (!(authmethods & IAX_AUTH_RSA)) {
08171          if (ast_strlen_zero(secret)) 
08172             ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(sin->sin_addr));
08173       } else if (ast_strlen_zero(challenge)) {
08174          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08175       } else {
08176          char sig[256];
08177          struct ast_key *key;
08178          key = ast_key_get(keyn, AST_KEY_PRIVATE);
08179          if (!key) {
08180             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08181          } else {
08182             if (ast_sign(key, (char*)challenge, sig)) {
08183                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08184                res = -1;
08185             } else {
08186                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08187                res = 0;
08188             }
08189          }
08190       }
08191    } 
08192    /* Fall back */
08193    if (res && !ast_strlen_zero(secret)) {
08194       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08195          struct MD5Context md5;
08196          unsigned char digest[16];
08197          char digres[128];
08198          MD5Init(&md5);
08199          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08200          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08201          MD5Final(digest, &md5);
08202          /* If they support md5, authenticate with it.  */
08203          for (x=0;x<16;x++)
08204             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
08205          if (pvt) {
08206             build_encryption_keys(digest, pvt);
08207          }
08208          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08209          res = 0;
08210       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08211          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08212          res = 0;
08213       } else
08214          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08215    }
08216    return res;
08217 }

static int authenticate_reply ( struct chan_iax2_pvt p,
struct sockaddr_in *  sin,
struct iax_ies ies,
const char *  override,
const char *  okey 
) [static]

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

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_calloc, ast_channel_datastore_add(), ast_datastore_alloc, ast_datastore_free(), AST_FRAME_IAX, ast_free, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_sockaddr_to_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_assign(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, iax_ie_data::buf, chan_iax2_pvt::callno, chan_iax2_pvt::challenge, iax_ies::challenge, ast_datastore::data, DATASTORE_INHERIT_FOREVER, chan_iax2_pvt::encmethods, iax_ies::encmethods, ast_var_t::entries, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_FORCE_ENCRYPT, IAX_KEYPOPULATED, ast_datastore::inheritance, LOG_ERROR, LOG_NOTICE, iax2_peer::mask, merge_encryption(), ast_variable::name, iax2_peer::name, ast_variable::next, iax2_peer::outkey, chan_iax2_pvt::owner, chan_iax2_pvt::peer, peer_unref(), iax_ie_data::pos, realtime_peer(), iax2_peer::secret, send_command(), chan_iax2_pvt::username, iax2_peer::username, iax_ies::username, ast_variable::value, var, and iax_ies::vars.

Referenced by socket_process().

08224 {
08225    struct iax2_peer *peer = NULL;
08226    /* Start pessimistic */
08227    int res = -1;
08228    int authmethods = 0;
08229    struct iax_ie_data ied;
08230    uint16_t callno = p->callno;
08231 
08232    memset(&ied, 0, sizeof(ied));
08233    
08234    if (ies->username)
08235       ast_string_field_set(p, username, ies->username);
08236    if (ies->challenge)
08237       ast_string_field_set(p, challenge, ies->challenge);
08238    if (ies->authmethods)
08239       authmethods = ies->authmethods;
08240    if (authmethods & IAX_AUTH_MD5)
08241       merge_encryption(p, ies->encmethods);
08242    else
08243       p->encmethods = 0;
08244 
08245    /* Check for override RSA authentication first */
08246    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08247       /* Normal password authentication */
08248       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08249    } else {
08250       struct ao2_iterator i = ao2_iterator_init(peers, 0);
08251       while ((peer = ao2_iterator_next(&i))) {
08252          struct sockaddr_in peer_addr;
08253 
08254          ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08255 
08256          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
08257              /* No peer specified at our end, or this is the peer */
08258              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08259              /* No username specified in peer rule, or this is the right username */
08260              && (!peer_addr.sin_addr.s_addr || ((sin->sin_addr.s_addr & peer->mask.s_addr) == (peer_addr.sin_addr.s_addr & peer->mask.s_addr)))
08261              /* No specified host, or this is our host */
08262             ) {
08263             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08264             if (!res) {
08265                peer_unref(peer);
08266                break;
08267             }
08268          }
08269          peer_unref(peer);
08270       }
08271       ao2_iterator_destroy(&i);
08272       if (!peer) {
08273          /* We checked our list and didn't find one.  It's unlikely, but possible, 
08274             that we're trying to authenticate *to* a realtime peer */
08275          const char *peer_name = ast_strdupa(p->peer);
08276          ast_mutex_unlock(&iaxsl[callno]);
08277          if ((peer = realtime_peer(peer_name, NULL))) {
08278             ast_mutex_lock(&iaxsl[callno]);
08279             if (!(p = iaxs[callno])) {
08280                peer_unref(peer);
08281                return -1;
08282             }
08283             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08284             peer_unref(peer);
08285          }
08286          if (!peer) {
08287             ast_mutex_lock(&iaxsl[callno]);
08288             if (!(p = iaxs[callno]))
08289                return -1;
08290          }
08291       }
08292    }
08293 
08294    if (ies->encmethods) {
08295       ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08296    } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08297       ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
08298       return -1;             /* if force encryption is yes, and no encryption methods, then return -1 to hangup */
08299    }
08300    if (!res) {
08301       struct ast_datastore *variablestore;
08302       struct ast_variable *var, *prev = NULL;
08303       AST_LIST_HEAD(, ast_var_t) *varlist;
08304       varlist = ast_calloc(1, sizeof(*varlist));
08305       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08306       if (variablestore && varlist && p->owner) {
08307          variablestore->data = varlist;
08308          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08309          AST_LIST_HEAD_INIT(varlist);
08310          for (var = ies->vars; var; var = var->next) {
08311             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08312             if (prev)
08313                ast_free(prev);
08314             prev = var;
08315             if (!newvar) {
08316                /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */
08317                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08318             } else {
08319                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08320             }
08321          }
08322          if (prev)
08323             ast_free(prev);
08324          ies->vars = NULL;
08325          ast_channel_datastore_add(p->owner, variablestore);
08326       } else {
08327          if (p->owner)
08328             ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08329          if (variablestore)
08330             ast_datastore_free(variablestore);
08331          if (varlist)
08332             ast_free(varlist);
08333       }
08334    }
08335 
08336    if (!res)
08337       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08338    return res;
08339 }

static int authenticate_request ( int  call_num  )  [static]

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

References ao2_find, AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_random(), ast_set_flag64, ast_string_field_set, ast_test_flag64, chan_iax2_pvt::authmethods, iax_ie_data::buf, chan_iax2_pvt::challenge, iax2_user::curauthreq, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, iax2_user::maxauthreq, OBJ_KEY, iax_ie_data::pos, send_command(), send_command_final(), user_unref(), and chan_iax2_pvt::username.

Referenced by socket_process().

07876 {
07877    struct iax_ie_data ied;
07878    int res = -1, authreq_restrict = 0;
07879    char challenge[10];
07880    struct chan_iax2_pvt *p = iaxs[call_num];
07881 
07882    memset(&ied, 0, sizeof(ied));
07883 
07884    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
07885    if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07886       struct iax2_user *user;
07887 
07888       user = ao2_find(users, p->username, OBJ_KEY);
07889       if (user) {
07890          if (user->curauthreq == user->maxauthreq)
07891             authreq_restrict = 1;
07892          else
07893             user->curauthreq++;
07894          user = user_unref(user);
07895       }
07896    }
07897 
07898    /* If the AUTHREQ limit test failed, send back an error */
07899    if (authreq_restrict) {
07900       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07901       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07902       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07903       return 0;
07904    }
07905 
07906    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07907    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07908       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07909       ast_string_field_set(p, challenge, challenge);
07910       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
07911       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07912    }
07913    if (p->encmethods)
07914       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07915 
07916    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07917 
07918    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07919 
07920    if (p->encmethods)
07921       ast_set_flag64(p, IAX_ENCRYPTED);
07922 
07923    return res;
07924 }

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

Definition at line 7926 of file chan_iax2.c.

References ao2_find, ast_atomic_fetchadd_int(), ast_check_signature(), ast_clear_flag64, ast_copy_string(), ast_key_get(), AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::challenge, iax2_user::curauthreq, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_FORCE_ENCRYPT, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_user::name, OBJ_KEY, iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user_unref(), and chan_iax2_pvt::username.

Referenced by socket_process().

07927 {
07928    char requeststr[256];
07929    char md5secret[256] = "";
07930    char secret[256] = "";
07931    char rsasecret[256] = "";
07932    int res = -1; 
07933    int x;
07934    struct iax2_user *user;
07935 
07936    if (p->authrej) {
07937       return res;
07938    }
07939    user = ao2_find(users, p->username, OBJ_KEY);
07940    if (user) {
07941       if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07942          ast_atomic_fetchadd_int(&user->curauthreq, -1);
07943          ast_clear_flag64(p, IAX_MAXAUTHREQ);
07944       }
07945       ast_string_field_set(p, host, user->name);
07946       user = user_unref(user);
07947    }
07948    if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 
07949       ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.");
07950       return res;
07951    }
07952    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07953       return res;
07954    if (ies->password)
07955       ast_copy_string(secret, ies->password, sizeof(secret));
07956    if (ies->md5_result)
07957       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07958    if (ies->rsa_result)
07959       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07960    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07961       struct ast_key *key;
07962       char *keyn;
07963       char tmpkey[256];
07964       char *stringp=NULL;
07965       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07966       stringp=tmpkey;
07967       keyn = strsep(&stringp, ":");
07968       while(keyn) {
07969          key = ast_key_get(keyn, AST_KEY_PUBLIC);
07970          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07971             res = 0;
07972             break;
07973          } else if (!key)
07974             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07975          keyn = strsep(&stringp, ":");
07976       }
07977    } else if (p->authmethods & IAX_AUTH_MD5) {
07978       struct MD5Context md5;
07979       unsigned char digest[16];
07980       char *tmppw, *stringp;
07981       
07982       tmppw = ast_strdupa(p->secret);
07983       stringp = tmppw;
07984       while((tmppw = strsep(&stringp, ";"))) {
07985          MD5Init(&md5);
07986          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07987          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07988          MD5Final(digest, &md5);
07989          /* If they support md5, authenticate with it.  */
07990          for (x=0;x<16;x++)
07991             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
07992          if (!strcasecmp(requeststr, md5secret)) {
07993             res = 0;
07994             break;
07995          }
07996       }
07997    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07998       if (!strcmp(secret, p->secret))
07999          res = 0;
08000    }
08001    return res;
08002 }

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

Definition at line 4741 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

Referenced by iax2_call(), sip_call(), and sip_show_sched().

04742 {
04743 #ifdef SCHED_MULTITHREADED
04744    if (schedule_action(__auto_congest, data))
04745 #endif      
04746       __auto_congest(data);
04747    return 0;
04748 }

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

Definition at line 9110 of file chan_iax2.c.

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

Referenced by iax2_dprequest(), and iax2_provision().

09111 {
09112    int callno = (int)(long)(data);
09113    ast_mutex_lock(&iaxsl[callno]);
09114    if (iaxs[callno]) {
09115       iaxs[callno]->autoid = -1;
09116    }
09117    ast_mutex_unlock(&iaxsl[callno]);
09118 #ifdef SCHED_MULTITHREADED
09119    if (schedule_action(__auto_hangup, data))
09120 #endif      
09121       __auto_hangup(data);
09122    return 0;
09123 }

static void build_callno_limits ( struct ast_variable v  )  [static]

Definition at line 2517 of file chan_iax2.c.

References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), addr_range::delme, addr_range::ha, addr_range::limit, LOG_ERROR, ast_variable::name, ast_variable::next, OBJ_POINTER, and ast_variable::value.

Referenced by set_config().

02518 {
02519    struct addr_range *addr_range = NULL;
02520    struct addr_range tmp;
02521    struct ast_ha *ha;
02522    int limit;
02523    int error;
02524    int found;
02525 
02526    for (; v; v = v->next) {
02527       limit = -1;
02528       error = 0;
02529       found = 0;
02530       ha = ast_append_ha("permit", v->name, NULL, &error);
02531 
02532       /* check for valid config information */
02533       if (error) {
02534          ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02535          continue;
02536       } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02537          ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02538          ast_free_ha(ha);
02539          continue;
02540       }
02541 
02542       ast_copy_ha(ha, &tmp.ha);
02543       /* find or create the addr_range */
02544       if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02545          ao2_lock(addr_range);
02546          found = 1;
02547       } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02548          ast_free_ha(ha);
02549          return; /* out of memory */
02550       }
02551 
02552       /* copy over config data into addr_range object */
02553       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
02554       ast_free_ha(ha); /* cleanup the tmp ha */
02555       addr_range->limit = limit;
02556       addr_range->delme = 0;
02557 
02558       /* cleanup */
02559       if (found) {
02560          ao2_unlock(addr_range);
02561       } else {
02562          ao2_link(callno_limits, addr_range);
02563       }
02564       ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02565    }
02566 }

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

Definition at line 12304 of file chan_iax2.c.

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

Referenced by build_user().

12305 {
12306    struct iax2_context *con;
12307 
12308    if ((con = ast_calloc(1, sizeof(*con))))
12309       ast_copy_string(con->context, context, sizeof(con->context));
12310    
12311    return con;
12312 }

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

Definition at line 6257 of file chan_iax2.c.

References ast_aes_set_decrypt_key(), ast_aes_set_encrypt_key(), build_rand_pad(), chan_iax2_pvt::ecx, chan_iax2_pvt::mydcx, and chan_iax2_pvt::semirand.

Referenced by build_encryption_keys(), and iax2_key_rotate().

06258 {
06259    /* it is required to hold the corresponding decrypt key to our encrypt key
06260     * in the pvt struct because queued frames occasionally need to be decrypted and
06261     * re-encrypted when updated for a retransmission */
06262    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06263    ast_aes_set_encrypt_key(digest, &pvt->ecx);
06264    ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06265 }

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

Definition at line 6251 of file chan_iax2.c.

References ast_aes_set_decrypt_key(), build_ecx_key(), and chan_iax2_pvt::dcx.

Referenced by authenticate(), and decrypt_frame().

06252 {
06253    build_ecx_key(digest, pvt);
06254    ast_aes_set_decrypt_key(digest, &pvt->dcx);
06255 }

static struct iax2_peer * build_peer ( const char *  name,
struct ast_variable v,
struct ast_variable alt,
int  temponly 
) [static, read]

Create peer structure based on configuration.

Definition at line 12455 of file chan_iax2.c.

References iax2_peer::addr, iax2_peer::adsi, ao2_alloc, ao2_find, ast_append_ha(), ast_callerid_split(), ast_clear_flag64, ast_copy_flags64, ast_dnsmgr_lookup(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_false(), ast_free_ha(), ast_get_ip(), ast_log(), AST_SCHED_DEL, ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_to_sin, ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_true(), iax2_peer::authmethods, CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, cid_name, cid_num, context, iax2_peer::defaddr, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::expire, iax2_peer::expiry, get_auth_methods(), get_encrypt_methods(), iax2_peer::ha, iax2_parse_allow_disallow(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, inet_aton(), ast_variable::lineno, LOG_WARNING, iax2_peer::mailbox, mailbox, iax2_peer::mask, iax2_peer::maxcallno, iax2_peer::maxms, mwi_event_cb(), iax2_peer::mwi_event_sub, iax2_peer::name, ast_variable::name, ast_variable::next, OBJ_KEY, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, prefs, iax2_peer::prefs, S_OR, secret, iax2_peer::smoothing, iax2_peer::sockfd, ast_sockaddr::ss, strsep(), unlink_peer(), ast_variable::value, and zonetag.

12456 {
12457    struct iax2_peer *peer = NULL;
12458    struct ast_ha *oldha = NULL;
12459    int maskfound = 0;
12460    int found = 0;
12461    int firstpass = 1;
12462 
12463    if (!temponly) {
12464       peer = ao2_find(peers, name, OBJ_KEY);
12465       if (peer && !ast_test_flag64(peer, IAX_DELME))
12466          firstpass = 0;
12467    }
12468 
12469    if (peer) {
12470       found++;
12471       if (firstpass) {
12472          oldha = peer->ha;
12473          peer->ha = NULL;
12474       }
12475       unlink_peer(peer);
12476    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12477       peer->expire = -1;
12478       peer->pokeexpire = -1;
12479       peer->sockfd = defaultsockfd;
12480       peer->addr.ss.ss_family = AF_INET;
12481       if (ast_string_field_init(peer, 32))
12482          peer = peer_unref(peer);
12483    }
12484 
12485    if (peer) {
12486       if (firstpass) {
12487          ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12488          peer->encmethods = iax2_encryption;
12489          peer->adsi = adsi;
12490          ast_string_field_set(peer,secret,"");
12491          if (!found) {
12492             ast_string_field_set(peer, name, name);
12493             ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12494             peer->expiry = min_reg_expire;
12495          }
12496          peer->prefs = prefs;
12497          peer->capability = iax2_capability;
12498          peer->smoothing = 0;
12499          peer->pokefreqok = DEFAULT_FREQ_OK;
12500          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12501          peer->maxcallno = 0;
12502          peercnt_modify(0, 0, &peer->addr);
12503          peer->calltoken_required = CALLTOKEN_DEFAULT;
12504          ast_string_field_set(peer,context,"");
12505          ast_string_field_set(peer,peercontext,"");
12506          ast_clear_flag64(peer, IAX_HASCALLERID);
12507          ast_string_field_set(peer, cid_name, "");
12508          ast_string_field_set(peer, cid_num, "");
12509          ast_string_field_set(peer, mohinterpret, mohinterpret);
12510          ast_string_field_set(peer, mohsuggest, mohsuggest);
12511       }
12512 
12513       if (!v) {
12514          v = alt;
12515          alt = NULL;
12516       }
12517       while(v) {
12518          if (!strcasecmp(v->name, "secret")) {
12519             ast_string_field_set(peer, secret, v->value);
12520          } else if (!strcasecmp(v->name, "mailbox")) {
12521             ast_string_field_set(peer, mailbox, v->value);
12522          } else if (!strcasecmp(v->name, "hasvoicemail")) {
12523             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12524                ast_string_field_set(peer, mailbox, name);
12525             }
12526          } else if (!strcasecmp(v->name, "mohinterpret")) {
12527             ast_string_field_set(peer, mohinterpret, v->value);
12528          } else if (!strcasecmp(v->name, "mohsuggest")) {
12529             ast_string_field_set(peer, mohsuggest, v->value);
12530          } else if (!strcasecmp(v->name, "dbsecret")) {
12531             ast_string_field_set(peer, dbsecret, v->value);
12532          } else if (!strcasecmp(v->name, "description")) {
12533             ast_string_field_set(peer, description, v->value);
12534          } else if (!strcasecmp(v->name, "trunk")) {
12535             ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 
12536             if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12537                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12538                ast_clear_flag64(peer, IAX_TRUNK);
12539             }
12540          } else if (!strcasecmp(v->name, "auth")) {
12541             peer->authmethods = get_auth_methods(v->value);
12542          } else if (!strcasecmp(v->name, "encryption")) {
12543             peer->encmethods |= get_encrypt_methods(v->value);
12544             if (!peer->encmethods) {
12545                ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12546             }
12547          } else if (!strcasecmp(v->name, "forceencryption")) {
12548             if (ast_false(v->value)) {
12549                ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12550             } else {
12551                peer->encmethods |= get_encrypt_methods(v->value);
12552                if (peer->encmethods) {
12553                   ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12554                }
12555             }
12556          } else if (!strcasecmp(v->name, "transfer")) {
12557             if (!strcasecmp(v->value, "mediaonly")) {
12558                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12559             } else if (ast_true(v->value)) {
12560                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12561             } else
12562                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12563          } else if (!strcasecmp(v->name, "jitterbuffer")) {
12564             ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12565          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12566             ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12567          } else if (!strcasecmp(v->name, "host")) {
12568             if (!strcasecmp(v->value, "dynamic")) {
12569                /* They'll register with us */
12570                ast_set_flag64(peer, IAX_DYNAMIC);
12571                if (!found) {
12572                   /* Initialize stuff iff we're not found, otherwise
12573                      we keep going with what we had */
12574                   if (ast_sockaddr_port(&peer->addr)) {
12575                      peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12576                   }
12577                   ast_sockaddr_setnull(&peer->addr);
12578                }
12579             } else {
12580                /* Non-dynamic.  Make sure we become that way if we're not */
12581                AST_SCHED_DEL(sched, peer->expire);
12582                ast_clear_flag64(peer, IAX_DYNAMIC);
12583                if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12584                   return peer_unref(peer);
12585                if (!ast_sockaddr_port(&peer->addr)) {
12586                   ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12587                }
12588             }
12589             if (!maskfound)
12590                inet_aton("255.255.255.255", &peer->mask);
12591          } else if (!strcasecmp(v->name, "defaultip")) {
12592             struct ast_sockaddr peer_defaddr_tmp;
12593 
12594             peer_defaddr_tmp.ss.ss_family = AF_INET;
12595             if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12596                return peer_unref(peer);
12597             }
12598             ast_sockaddr_to_sin(&peer_defaddr_tmp,
12599                       &peer->defaddr);
12600          } else if (!strcasecmp(v->name, "sourceaddress")) {
12601             peer_set_srcaddr(peer, v->value);
12602          } else if (!strcasecmp(v->name, "permit") ||
12603                   !strcasecmp(v->name, "deny")) {
12604             peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12605          } else if (!strcasecmp(v->name, "mask")) {
12606             maskfound++;
12607             inet_aton(v->value, &peer->mask);
12608          } else if (!strcasecmp(v->name, "context")) {
12609             ast_string_field_set(peer, context, v->value);
12610          } else if (!strcasecmp(v->name, "regexten")) {
12611             ast_string_field_set(peer, regexten, v->value);
12612          } else if (!strcasecmp(v->name, "peercontext")) {
12613             ast_string_field_set(peer, peercontext, v->value);
12614          } else if (!strcasecmp(v->name, "port")) {
12615             if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12616                peer->defaddr.sin_port = htons(atoi(v->value));
12617             } else {
12618                ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12619             }
12620          } else if (!strcasecmp(v->name, "username")) {
12621             ast_string_field_set(peer, username, v->value);
12622          } else if (!strcasecmp(v->name, "allow")) {
12623             iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12624          } else if (!strcasecmp(v->name, "disallow")) {
12625             iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12626          } else if (!strcasecmp(v->name, "callerid")) {
12627             if (!ast_strlen_zero(v->value)) {
12628                char name2[80];
12629                char num2[80];
12630                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12631                ast_string_field_set(peer, cid_name, name2);
12632                ast_string_field_set(peer, cid_num, num2);
12633             } else {
12634                ast_string_field_set(peer, cid_name, "");
12635                ast_string_field_set(peer, cid_num, "");
12636             }
12637             ast_set_flag64(peer, IAX_HASCALLERID);
12638          } else if (!strcasecmp(v->name, "fullname")) {
12639             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12640             ast_set_flag64(peer, IAX_HASCALLERID);
12641          } else if (!strcasecmp(v->name, "cid_number")) {
12642             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12643             ast_set_flag64(peer, IAX_HASCALLERID);
12644          } else if (!strcasecmp(v->name, "sendani")) {
12645             ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12646          } else if (!strcasecmp(v->name, "inkeys")) {
12647             ast_string_field_set(peer, inkeys, v->value);
12648          } else if (!strcasecmp(v->name, "outkey")) {
12649             ast_string_field_set(peer, outkey, v->value);
12650          } else if (!strcasecmp(v->name, "qualify")) {
12651             if (!strcasecmp(v->value, "no")) {
12652                peer->maxms = 0;
12653             } else if (!strcasecmp(v->value, "yes")) {
12654                peer->maxms = DEFAULT_MAXMS;
12655             } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12656                ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno);
12657                peer->maxms = 0;
12658             }
12659          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12660             peer->smoothing = ast_true(v->value);
12661          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12662             if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12663                ast_log(LOG_WARNING, "Qualification testing frequency of peer '%s' when OK should a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno);
12664             }
12665          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12666             if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12667                ast_log(LOG_WARNING, "Qualification testing frequency of peer '%s' when NOT OK should be a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno);
12668             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
12669          } else if (!strcasecmp(v->name, "timezone")) {
12670             ast_string_field_set(peer, zonetag, v->value);
12671          } else if (!strcasecmp(v->name, "adsi")) {
12672             peer->adsi = ast_true(v->value);
12673          } else if (!strcasecmp(v->name, "connectedline")) {
12674             if (ast_true(v->value)) {
12675                ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12676             } else if (!strcasecmp(v->value, "send")) {
12677                ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12678                ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12679             } else if (!strcasecmp(v->value, "receive")) {
12680                ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12681                ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12682             } else {
12683                ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12684             }
12685          } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12686             if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12687                ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12688             } else {
12689                peercnt_modify(1, peer->maxcallno, &peer->addr);
12690             }
12691          } else if (!strcasecmp(v->name, "requirecalltoken")) {
12692             /* default is required unless in optional ip list */
12693             if (ast_false(v->value)) {
12694                peer->calltoken_required = CALLTOKEN_NO;
12695             } else if (!strcasecmp(v->value, "auto")) {
12696                peer->calltoken_required = CALLTOKEN_AUTO;
12697             } else if (ast_true(v->value)) {
12698                peer->calltoken_required = CALLTOKEN_YES;
12699             } else {
12700                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12701             }
12702          } /* else if (strcasecmp(v->name,"type")) */
12703          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
12704          v = v->next;
12705          if (!v) {
12706             v = alt;
12707             alt = NULL;
12708          }
12709       }
12710       if (!peer->authmethods)
12711          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12712       ast_clear_flag64(peer, IAX_DELME);
12713    }
12714 
12715    if (oldha)
12716       ast_free_ha(oldha);
12717 
12718    if (!ast_strlen_zero(peer->mailbox)) {
12719       char *mailbox, *context;
12720       context = mailbox = ast_strdupa(peer->mailbox);
12721       strsep(&context, "@");
12722       if (ast_strlen_zero(context))
12723          context = "default";
12724       peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12725          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12726          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12727          AST_EVENT_IE_END);
12728    }
12729 
12730    return peer;
12731 }

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

Definition at line 6241 of file chan_iax2.c.

References ast_random().

Referenced by build_ecx_key(), and update_packet().

06242 {
06243    long tmp;
06244    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06245       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06246       buf += sizeof(tmp);
06247       len -= sizeof(tmp);
06248    }
06249 }

static struct iax2_user * build_user ( const char *  name,
struct ast_variable v,
struct ast_variable alt,
int  temponly 
) [static, read]

Create in-memory user structure from configuration.

Definition at line 12747 of file chan_iax2.c.

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

12748 {
12749    struct iax2_user *user = NULL;
12750    struct iax2_context *con, *conl = NULL;
12751    struct ast_ha *oldha = NULL;
12752    struct iax2_context *oldcon = NULL;
12753    int format;
12754    int firstpass=1;
12755    int oldcurauthreq = 0;
12756    char *varname = NULL, *varval = NULL;
12757    struct ast_variable *tmpvar = NULL;
12758 
12759    if (!temponly) {
12760       user = ao2_find(users, name, OBJ_KEY);
12761       if (user && !ast_test_flag64(user, IAX_DELME))
12762          firstpass = 0;
12763    }
12764 
12765    if (user) {
12766       if (firstpass) {
12767          oldcurauthreq = user->curauthreq;
12768          oldha = user->ha;
12769          oldcon = user->contexts;
12770          user->ha = NULL;
12771          user->contexts = NULL;
12772       }
12773       /* Already in the list, remove it and it will be added back (or FREE'd) */
12774       ao2_unlink(users, user);
12775    } else {
12776       user = ao2_alloc(sizeof(*user), user_destructor);
12777    }
12778    
12779    if (user) {
12780       if (firstpass) {
12781          ast_string_field_free_memory(user);
12782          memset(user, 0, sizeof(struct iax2_user));
12783          if (ast_string_field_init(user, 32)) {
12784             user = user_unref(user);
12785             goto cleanup;
12786          }
12787          user->maxauthreq = maxauthreq;
12788          user->curauthreq = oldcurauthreq;
12789          user->prefs = prefs;
12790          user->capability = iax2_capability;
12791          user->encmethods = iax2_encryption;
12792          user->adsi = adsi;
12793          user->calltoken_required = CALLTOKEN_DEFAULT;
12794          ast_string_field_set(user, name, name);
12795          ast_string_field_set(user, language, language);
12796          ast_copy_flags64(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12797          ast_clear_flag64(user, IAX_HASCALLERID);
12798          ast_string_field_set(user, cid_name, "");
12799          ast_string_field_set(user, cid_num, "");
12800          ast_string_field_set(user, accountcode, accountcode);
12801          ast_string_field_set(user, mohinterpret, mohinterpret);
12802          ast_string_field_set(user, mohsuggest, mohsuggest);
12803       }
12804       if (!v) {
12805          v = alt;
12806          alt = NULL;
12807       }
12808       while(v) {
12809          if (!strcasecmp(v->name, "context")) {
12810             con = build_context(v->value);
12811             if (con) {
12812                if (conl)
12813                   conl->next = con;
12814                else
12815                   user->contexts = con;
12816                conl = con;
12817             }
12818          } else if (!strcasecmp(v->name, "permit") ||
12819                   !strcasecmp(v->name, "deny")) {
12820             user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12821          } else if (!strcasecmp(v->name, "setvar")) {
12822             varname = ast_strdupa(v->value);
12823             if (varname && (varval = strchr(varname,'='))) {
12824                *varval = '\0';
12825                varval++;
12826                if((tmpvar = ast_variable_new(varname, varval, ""))) {
12827                   tmpvar->next = user->vars; 
12828                   user->vars = tmpvar;
12829                }
12830             }
12831          } else if (!strcasecmp(v->name, "allow")) {
12832             iax2_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12833          } else if (!strcasecmp(v->name, "disallow")) {
12834             iax2_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12835          } else if (!strcasecmp(v->name, "trunk")) {
12836             ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 
12837             if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
12838                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12839                ast_clear_flag64(user, IAX_TRUNK);
12840             }
12841          } else if (!strcasecmp(v->name, "auth")) {
12842             user->authmethods = get_auth_methods(v->value);
12843          } else if (!strcasecmp(v->name, "encryption")) {
12844             user->encmethods |= get_encrypt_methods(v->value);
12845             if (!user->encmethods) {
12846                ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12847             }
12848          } else if (!strcasecmp(v->name, "forceencryption")) {
12849             if (ast_false(v->value)) {
12850                ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12851             } else {
12852                user->encmethods |= get_encrypt_methods(v->value);
12853                if (user->encmethods) {
12854                   ast_set_flag64(user, IAX_FORCE_ENCRYPT);
12855                }
12856             }
12857          } else if (!strcasecmp(v->name, "transfer")) {
12858             if (!strcasecmp(v->value, "mediaonly")) {
12859                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12860             } else if (ast_true(v->value)) {
12861                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12862             } else
12863                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12864          } else if (!strcasecmp(v->name, "codecpriority")) {
12865             if(!strcasecmp(v->value, "caller"))
12866                ast_set_flag64(user, IAX_CODEC_USER_FIRST);
12867             else if(!strcasecmp(v->value, "disabled"))
12868                ast_set_flag64(user, IAX_CODEC_NOPREFS);
12869             else if(!strcasecmp(v->value, "reqonly")) {
12870                ast_set_flag64(user, IAX_CODEC_NOCAP);
12871                ast_set_flag64(user, IAX_CODEC_NOPREFS);
12872             }
12873          } else if (!strcasecmp(v->name, "immediate")) {
12874             ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
12875          } else if (!strcasecmp(v->name, "jitterbuffer")) {
12876             ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
12877          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12878             ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12879          } else if (!strcasecmp(v->name, "dbsecret")) {
12880             ast_string_field_set(user, dbsecret, v->value);
12881          } else if (!strcasecmp(v->name, "secret")) {
12882             if (!ast_strlen_zero(user->secret)) {
12883                char *old = ast_strdupa(user->secret);
12884 
12885                ast_string_field_build(user, secret, "%s;%s", old, v->value);
12886             } else
12887                ast_string_field_set(user, secret, v->value);
12888          } else if (!strcasecmp(v->name, "callerid")) {
12889             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12890                char name2[80];
12891                char num2[80];
12892                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12893                ast_string_field_set(user, cid_name, name2);
12894                ast_string_field_set(user, cid_num, num2);
12895                ast_set_flag64(user, IAX_HASCALLERID);
12896             } else {
12897                ast_clear_flag64(user, IAX_HASCALLERID);
12898                ast_string_field_set(user, cid_name, "");
12899                ast_string_field_set(user, cid_num, "");
12900             }
12901          } else if (!strcasecmp(v->name, "fullname")) {
12902             if (!ast_strlen_zero(v->value)) {
12903                ast_string_field_set(user, cid_name, v->value);
12904                ast_set_flag64(user, IAX_HASCALLERID);
12905             } else {
12906                ast_string_field_set(user, cid_name, "");
12907                if (ast_strlen_zero(user->cid_num))
12908                   ast_clear_flag64(user, IAX_HASCALLERID);
12909             }
12910          } else if (!strcasecmp(v->name, "cid_number")) {
12911             if (!ast_strlen_zero(v->value)) {
12912                ast_string_field_set(user, cid_num, v->value);
12913                ast_set_flag64(user, IAX_HASCALLERID);
12914             } else {
12915                ast_string_field_set(user, cid_num, "");
12916                if (ast_strlen_zero(user->cid_name))
12917                   ast_clear_flag64(user, IAX_HASCALLERID);
12918             }
12919          } else if (!strcasecmp(v->name, "accountcode")) {
12920             ast_string_field_set(user, accountcode, v->value);
12921          } else if (!strcasecmp(v->name, "mohinterpret")) {
12922             ast_string_field_set(user, mohinterpret, v->value);
12923          } else if (!strcasecmp(v->name, "mohsuggest")) {
12924             ast_string_field_set(user, mohsuggest, v->value);
12925          } else if (!strcasecmp(v->name, "parkinglot")) {
12926             ast_string_field_set(user, parkinglot, v->value);
12927          } else if (!strcasecmp(v->name, "language")) {
12928             ast_string_field_set(user, language, v->value);
12929          } else if (!strcasecmp(v->name, "amaflags")) {
12930             format = ast_cdr_amaflags2int(v->value);
12931             if (format < 0) {
12932                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12933             } else {
12934                user->amaflags = format;
12935             }
12936          } else if (!strcasecmp(v->name, "inkeys")) {
12937             ast_string_field_set(user, inkeys, v->value);
12938          } else if (!strcasecmp(v->name, "maxauthreq")) {
12939             user->maxauthreq = atoi(v->value);
12940             if (user->maxauthreq < 0)
12941                user->maxauthreq = 0;
12942          } else if (!strcasecmp(v->name, "adsi")) {
12943             user->adsi = ast_true(v->value);
12944          } else if (!strcasecmp(v->name, "connectedline")) {
12945             if (ast_true(v->value)) {
12946                ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12947             } else if (!strcasecmp(v->value, "send")) {
12948                ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
12949                ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
12950             } else if (!strcasecmp(v->value, "receive")) {
12951                ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
12952                ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
12953             } else {
12954                ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12955             }
12956          } else if (!strcasecmp(v->name, "requirecalltoken")) {
12957             /* default is required unless in optional ip list */
12958             if (ast_false(v->value)) {
12959                user->calltoken_required = CALLTOKEN_NO;
12960             } else if (!strcasecmp(v->value, "auto")) {
12961                user->calltoken_required = CALLTOKEN_AUTO;
12962             } else if (ast_true(v->value)) {
12963                user->calltoken_required = CALLTOKEN_YES;
12964             } else {
12965                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12966             }
12967          } /* else if (strcasecmp(v->name,"type")) */
12968          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
12969          v = v->next;
12970          if (!v) {
12971             v = alt;
12972             alt = NULL;
12973          }
12974       }
12975       if (!user->authmethods) {
12976          if (!ast_strlen_zero(user->secret)) {
12977             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12978             if (!ast_strlen_zero(user->inkeys))
12979                user->authmethods |= IAX_AUTH_RSA;
12980          } else if (!ast_strlen_zero(user->inkeys)) {
12981             user->authmethods = IAX_AUTH_RSA;
12982          } else {
12983             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12984          }
12985       }
12986       ast_clear_flag64(user, IAX_DELME);
12987    }
12988 cleanup:
12989    if (oldha)
12990       ast_free_ha(oldha);
12991    if (oldcon)
12992       free_context(oldcon);
12993    return user;
12994 }

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

Definition at line 13628 of file chan_iax2.c.

References add_empty_calltoken_ie(), ARRAY_LEN, ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_trylock, ast_mutex_unlock, ast_strdupa, ast_string_field_set, ast_strlen_zero(), iax_ie_data::buf, chan_iax2_pvt::capability, parsed_dial_string::context, create_addr(), parsed_dial_string::exten, find_callno_locked(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, parsed_dial_string::key, LOG_WARNING, NEW_FORCE, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, iax_ie_data::pos, secret, send_command(), create_addr_info::sockfd, and parsed_dial_string::username.

Referenced by find_cache().

13629 {
13630    struct sockaddr_in sin;
13631    int x;
13632    int callno;
13633    struct iax_ie_data ied;
13634    struct create_addr_info cai;
13635    struct parsed_dial_string pds;
13636    char *tmpstr;
13637 
13638    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13639       /* Look for an *exact match* call.  Once a call is negotiated, it can only
13640          look up entries for a single context */
13641       if (!ast_mutex_trylock(&iaxsl[x])) {
13642          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13643             return x;
13644          ast_mutex_unlock(&iaxsl[x]);
13645       }
13646    }
13647 
13648    /* No match found, we need to create a new one */
13649 
13650    memset(&cai, 0, sizeof(cai));
13651    memset(&ied, 0, sizeof(ied));
13652    memset(&pds, 0, sizeof(pds));
13653 
13654    tmpstr = ast_strdupa(data);
13655    parse_dial_string(tmpstr, &pds);
13656 
13657    if (ast_strlen_zero(pds.peer)) {
13658       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13659       return -1;
13660    }
13661 
13662    /* Populate our address from the given */
13663    if (create_addr(pds.peer, NULL, &sin, &cai))
13664       return -1;
13665 
13666    ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13667       pds.peer, pds.username, pds.password, pds.context);
13668 
13669    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13670    if (callno < 1) {
13671       ast_log(LOG_WARNING, "Unable to create call\n");
13672       return -1;
13673    }
13674 
13675    ast_string_field_set(iaxs[callno], dproot, data);
13676    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13677 
13678    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13679    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13680    /* the string format is slightly different from a standard dial string,
13681       because the context appears in the 'exten' position
13682    */
13683    if (pds.exten)
13684       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13685    if (pds.username)
13686       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13687    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13688    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13689    /* Keep password handy */
13690    if (pds.password)
13691       ast_string_field_set(iaxs[callno], secret, pds.password);
13692    if (pds.key)
13693       ast_string_field_set(iaxs[callno], outkey, pds.key);
13694    /* Start the call going */
13695    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
13696    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13697 
13698    return callno;
13699 }

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

Definition at line 6094 of file chan_iax2.c.

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

Referenced by ast_rtp_read(), and schedule_delivery().

06095 {
06096    /* Returns where in "receive time" we are.  That is, how many ms
06097       since we received (or would have received) the frame with timestamp 0 */
06098    int ms;
06099 #ifdef IAXTESTS
06100    int jit;
06101 #endif /* IAXTESTS */
06102    /* Setup rxcore if necessary */
06103    if (ast_tvzero(p->rxcore)) {
06104       p->rxcore = ast_tvnow();
06105       if (iaxdebug)
06106          ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
06107                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06108       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06109 #if 1
06110       if (iaxdebug)
06111          ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06112                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06113 #endif
06114    }
06115 
06116    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06117 #ifdef IAXTESTS
06118    if (test_jit) {
06119       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06120          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06121          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06122             jit = -jit;
06123          ms += jit;
06124       }
06125    }
06126    if (test_late) {
06127       ms += test_late;
06128       test_late = 0;
06129    }
06130 #endif /* IAXTESTS */
06131    return ms;
06132 }

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

Definition at line 5961 of file chan_iax2.c.

References ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_samp2tv(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, ast_frame::delivery, ast_frame_subclass::format, ast_frame::frametype, iax2_trunk_peer::lastsent, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, chan_iax2_pvt::peercallno, ast_frame::samples, and ast_frame::subclass.

Referenced by iax2_send(), and socket_process().

05962 {
05963    int ms;
05964    int voice = 0;
05965    int genuine = 0;
05966    int adjust;
05967    int rate = ast_format_rate(&f->subclass.format) / 1000;
05968    struct timeval *delivery = NULL;
05969 
05970 
05971    /* What sort of frame do we have?: voice is self-explanatory
05972       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
05973       non-genuine frames are CONTROL frames [ringing etc], DTMF
05974       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
05975       the others need a timestamp slaved to the voice frames so that they go in sequence
05976    */
05977    if (f) {
05978       if (f->frametype == AST_FRAME_VOICE) {
05979          voice = 1;
05980          delivery = &f->delivery;
05981       } else if (f->frametype == AST_FRAME_IAX) {
05982          genuine = 1;
05983       } else if (f->frametype == AST_FRAME_CNG) {
05984          p->notsilenttx = 0;
05985       }
05986    }
05987    if (ast_tvzero(p->offset)) {
05988       p->offset = ast_tvnow();
05989       /* Round to nearest 20ms for nice looking traces */
05990       p->offset.tv_usec -= p->offset.tv_usec % 20000;
05991    }
05992    /* If the timestamp is specified, just send it as is */
05993    if (ts)
05994       return ts;
05995    /* If we have a time that the frame arrived, always use it to make our timestamp */
05996    if (delivery && !ast_tvzero(*delivery)) {
05997       ms = ast_tvdiff_ms(*delivery, p->offset);
05998       if (ms < 0) {
05999          ms = 0;
06000       }
06001       if (iaxdebug)
06002          ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
06003    } else {
06004       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
06005       if (ms < 0)
06006          ms = 0;
06007       if (voice) {
06008          /* On a voice frame, use predicted values if appropriate */
06009          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
06010             /* Adjust our txcore, keeping voice and non-voice synchronized */
06011             /* AN EXPLANATION:
06012                When we send voice, we usually send "calculated" timestamps worked out
06013                on the basis of the number of samples sent. When we send other frames,
06014                we usually send timestamps worked out from the real clock.
06015                The problem is that they can tend to drift out of step because the 
06016                   source channel's clock and our clock may not be exactly at the same rate.
06017                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
06018                for this call.  Moving it adjusts timestamps for non-voice frames.
06019                We make the adjustment in the style of a moving average.  Each time we
06020                adjust p->offset by 10% of the difference between our clock-derived
06021                timestamp and the predicted timestamp.  That's why you see "10000"
06022                below even though IAX2 timestamps are in milliseconds.
06023                The use of a moving average avoids offset moving too radically.
06024                Generally, "adjust" roams back and forth around 0, with offset hardly
06025                changing at all.  But if a consistent different starts to develop it
06026                will be eliminated over the course of 10 frames (200-300msecs) 
06027             */
06028             adjust = (ms - p->nextpred);
06029             if (adjust < 0)
06030                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
06031             else if (adjust > 0)
06032                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
06033 
06034             if (!p->nextpred) {
06035                p->nextpred = ms; /*f->samples / rate;*/
06036                if (p->nextpred <= p->lastsent)
06037                   p->nextpred = p->lastsent + 3;
06038             }
06039             ms = p->nextpred;
06040          } else {
06041                 /* in this case, just use the actual
06042             * time, since we're either way off
06043             * (shouldn't happen), or we're  ending a
06044             * silent period -- and seed the next
06045             * predicted time.  Also, round ms to the
06046             * next multiple of frame size (so our
06047             * silent periods are multiples of
06048             * frame size too) */
06049 
06050             if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
06051                ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
06052                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
06053 
06054             if (f->samples >= rate) /* check to make sure we don't core dump */
06055             {
06056                int diff = ms % (f->samples / rate);
06057                if (diff)
06058                    ms += f->samples/rate - diff;
06059             }
06060 
06061             p->nextpred = ms;
06062             p->notsilenttx = 1;
06063          }
06064       } else if ( f->frametype == AST_FRAME_VIDEO ) {
06065          /*
06066          * IAX2 draft 03 says that timestamps MUST be in order.
06067          * It does not say anything about several frames having the same timestamp
06068          * When transporting video, we can have a frame that spans multiple iax packets
06069          * (so called slices), so it would make sense to use the same timestamp for all of
06070          * them
06071          * We do want to make sure that frames don't go backwards though
06072          */
06073          if ( (unsigned int)ms < p->lastsent )
06074             ms = p->lastsent;
06075       } else {
06076          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
06077             it's a genuine frame */
06078          if (genuine) {
06079             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
06080             if (ms <= p->lastsent)
06081                ms = p->lastsent + 3;
06082          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
06083             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
06084             ms = p->lastsent + 3;
06085          }
06086       }
06087    }
06088    p->lastsent = ms;
06089    if (voice)
06090       p->nextpred = p->nextpred + f->samples / rate;
06091    return ms;
06092 }

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

Definition at line 5917 of file chan_iax2.c.

References ast_tvdiff_ms(), ast_tvzero(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lasttxtime, MAX_TIMESTAMP_SKEW, iax2_trunk_peer::trunkact, and iax2_trunk_peer::txtrunktime.

Referenced by send_trunk().

05918 {
05919    unsigned long int mssincetx; /* unsigned to handle overflows */
05920    long int ms, pred;
05921 
05922    tpeer->trunkact = *now;
05923    mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05924    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05925       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
05926       tpeer->txtrunktime = *now;
05927       tpeer->lastsent = 999999;
05928    }
05929    /* Update last transmit time now */
05930    tpeer->lasttxtime = *now;
05931    
05932    /* Calculate ms offset */
05933    ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05934    /* Predict from last value */
05935    pred = tpeer->lastsent + sampms;
05936    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05937       ms = pred;
05938    
05939    /* We never send the same timestamp twice, so fudge a little if we must */
05940    if (ms == tpeer->lastsent)
05941       ms = tpeer->lastsent + 1;
05942    tpeer->lastsent = ms;
05943    return ms;
05944 }

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

Definition at line 2734 of file chan_iax2.c.

References ast_random().

Referenced by create_callno_pools().

02735 {
02736    return abs(ast_random());
02737 }

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

Definition at line 2265 of file chan_iax2.c.

References addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_peer::calltoken_required, iax2_user::calltoken_required, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), realtime_peer(), realtime_user(), S_OR, and user_unref().

Referenced by handle_call_token().

02266 {
02267    struct addr_range *addr_range;
02268    struct iax2_peer *peer = NULL;
02269    struct iax2_user *user = NULL;
02270    /* if no username is given, check for guest accounts */
02271    const char *find = S_OR(name, "guest");
02272    int res = 1;  /* required by default */
02273    int optional = 0;
02274    enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02275    /* There are only two cases in which calltoken validation is not required.
02276     * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
02277     *         the peer definition has not set the requirecalltoken option.
02278     * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
02279     */
02280 
02281    /* ----- Case 1 ----- */
02282    if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02283       ao2_ref(addr_range, -1);
02284       optional = 1;
02285    }
02286 
02287    /* ----- Case 2 ----- */
02288    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02289       calltoken_required = user->calltoken_required;
02290    } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02291       calltoken_required = user->calltoken_required;
02292    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02293       calltoken_required = peer->calltoken_required;
02294    } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02295       calltoken_required = peer->calltoken_required;
02296    }
02297 
02298    if (peer) {
02299       peer_unref(peer);
02300    }
02301    if (user) {
02302       user_unref(user);
02303    }
02304 
02305    ast_debug(1, "Determining if address %s with username %s requires calltoken validation.  Optional = %d  calltoken_required = %d \n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required);
02306    if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02307       (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02308       res = 0;
02309    }
02310 
02311    return res;
02312 }

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

Definition at line 7611 of file chan_iax2.c.

References iax2_user::accountcode, iax2_user::adsi, chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::amaflags, iax2_user::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags64, ast_db_get(), ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag64, ast_set_flag64, ast_shrink_phone_number(), ast_sockaddr_from_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_variable_new(), iax2_user::authmethods, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, iax_ies::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, iax_ies::codec_prefs, iax2_context::context, chan_iax2_pvt::context, context, iax2_user::contexts, iax2_user::dbsecret, DEFAULT_CONTEXT, iax_ies::dnid, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, ast_variable::file, iax_ies::format, iax2_user::ha, iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_IMMEDIATE, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, iax2_user::language, iax_ies::language, LOG_WARNING, iax2_user::maxauthreq, iax2_user::mohinterpret, iax2_user::mohsuggest, ast_variable::name, iax2_user::name, ast_variable::next, parkinglot, iax2_user::parkinglot, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, iax_ies::rdnis, realtime_user(), secret, iax2_user::secret, user_unref(), iax_ies::username, ast_variable::value, chan_iax2_pvt::vars, iax2_user::vars, iax_ies::version, and version.

Referenced by socket_process().

07612 {
07613    /* Start pessimistic */
07614    int res = -1;
07615    int version = 2;
07616    struct iax2_user *user = NULL, *best = NULL;
07617    int bestscore = 0;
07618    int gotcapability = 0;
07619    struct ast_variable *v = NULL, *tmpvar = NULL;
07620    struct ao2_iterator i;
07621    struct ast_sockaddr addr;
07622 
07623    if (!iaxs[callno])
07624       return res;
07625    if (ies->called_number)
07626       ast_string_field_set(iaxs[callno], exten, ies->called_number);
07627    if (ies->calling_number) {
07628       if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 
07629          ast_shrink_phone_number(ies->calling_number);
07630       }
07631       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07632    }
07633    if (ies->calling_name)
07634       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07635    if (ies->calling_ani)
07636       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07637    if (ies->dnid)
07638       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07639    if (ies->rdnis)
07640       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07641    if (ies->called_context)
07642       ast_string_field_set(iaxs[callno], context, ies->called_context);
07643    if (ies->language)
07644       ast_string_field_set(iaxs[callno], language, ies->language);
07645    if (ies->username)
07646       ast_string_field_set(iaxs[callno], username, ies->username);
07647    if (ies->calling_ton > -1)
07648       iaxs[callno]->calling_ton = ies->calling_ton;
07649    if (ies->calling_tns > -1)
07650       iaxs[callno]->calling_tns = ies->calling_tns;
07651    if (ies->calling_pres > -1)
07652       iaxs[callno]->calling_pres = ies->calling_pres;
07653    if (ies->format)
07654       iaxs[callno]->peerformat = ies->format;
07655    if (ies->adsicpe)
07656       iaxs[callno]->peeradsicpe = ies->adsicpe;
07657    if (ies->capability) {
07658       gotcapability = 1;
07659       iaxs[callno]->peercapability = ies->capability;
07660    } 
07661    if (ies->version)
07662       version = ies->version;
07663 
07664    /* Use provided preferences until told otherwise for actual preferences */
07665    if (ies->codec_prefs) {
07666       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07667       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07668    }
07669 
07670    if (!gotcapability) 
07671       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07672    if (version > IAX_PROTO_VERSION) {
07673       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
07674          ast_inet_ntoa(sin->sin_addr), version);
07675       return res;
07676    }
07677    /* Search the userlist for a compatible entry, and fill in the rest */
07678    ast_sockaddr_from_sin(&addr, sin);
07679    i = ao2_iterator_init(users, 0);
07680    while ((user = ao2_iterator_next(&i))) {
07681       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
07682          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
07683          && ast_apply_ha(user->ha, &addr)    /* Access is permitted from this IP */
07684          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
07685               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
07686          if (!ast_strlen_zero(iaxs[callno]->username)) {
07687             /* Exact match, stop right now. */
07688             if (best)
07689                user_unref(best);
07690             best = user;
07691             break;
07692          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07693             /* No required authentication */
07694             if (user->ha) {
07695                /* There was host authentication and we passed, bonus! */
07696                if (bestscore < 4) {
07697                   bestscore = 4;
07698                   if (best)
07699                      user_unref(best);
07700                   best = user;
07701                   continue;
07702                }
07703             } else {
07704                /* No host access, but no secret, either, not bad */
07705                if (bestscore < 3) {
07706                   bestscore = 3;
07707                   if (best)
07708                      user_unref(best);
07709                   best = user;
07710                   continue;
07711                }
07712             }
07713          } else {
07714             if (user->ha) {
07715                /* Authentication, but host access too, eh, it's something.. */
07716                if (bestscore < 2) {
07717                   bestscore = 2;
07718                   if (best)
07719                      user_unref(best);
07720                   best = user;
07721                   continue;
07722                }
07723             } else {
07724                /* Authentication and no host access...  This is our baseline */
07725                if (bestscore < 1) {
07726                   bestscore = 1;
07727                   if (best)
07728                      user_unref(best);
07729                   best = user;
07730                   continue;
07731                }
07732             }
07733          }
07734       }
07735       user_unref(user);
07736    }
07737    ao2_iterator_destroy(&i);
07738    user = best;
07739    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07740       user = realtime_user(iaxs[callno]->username, sin);
07741       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
07742           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
07743          user = user_unref(user);
07744       }
07745    }
07746    if (user) {
07747       /* We found our match (use the first) */
07748       /* copy vars */
07749       for (v = user->vars ; v ; v = v->next) {
07750          if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07751             tmpvar->next = iaxs[callno]->vars; 
07752             iaxs[callno]->vars = tmpvar;
07753          }
07754       }
07755       /* If a max AUTHREQ restriction is in place, activate it */
07756       if (user->maxauthreq > 0)
07757          ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07758       iaxs[callno]->prefs = user->prefs;
07759       ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07760       iaxs[callno]->encmethods = user->encmethods;
07761       /* Store the requested username if not specified */
07762       if (ast_strlen_zero(iaxs[callno]->username))
07763          ast_string_field_set(iaxs[callno], username, user->name);
07764       /* Store whether this is a trunked call, too, of course, and move if appropriate */
07765       ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07766       iaxs[callno]->capability = user->capability;
07767       /* And use the default context */
07768       if (ast_strlen_zero(iaxs[callno]->context)) {
07769          if (user->contexts)
07770             ast_string_field_set(iaxs[callno], context, user->contexts->context);
07771          else
07772             ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07773       }
07774       /* And any input keys */
07775       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07776       /* And the permitted authentication methods */
07777       iaxs[callno]->authmethods = user->authmethods;
07778       iaxs[callno]->adsi = user->adsi;
07779       /* If the user has callerid, override the remote caller id. */
07780       if (ast_test_flag64(user, IAX_HASCALLERID)) {
07781          iaxs[callno]->calling_tns = 0;
07782          iaxs[callno]->calling_ton = 0;
07783          ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07784          ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07785          ast_string_field_set(iaxs[callno], ani, user->cid_num);
07786          iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07787       } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07788          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07789       } /* else user is allowed to set their own CID settings */
07790       if (!ast_strlen_zero(user->accountcode))
07791          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07792       if (!ast_strlen_zero(user->mohinterpret))
07793          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07794       if (!ast_strlen_zero(user->mohsuggest))
07795          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07796       if (!ast_strlen_zero(user->parkinglot))
07797          ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07798       if (user->amaflags)
07799          iaxs[callno]->amaflags = user->amaflags;
07800       if (!ast_strlen_zero(user->language))
07801          ast_string_field_set(iaxs[callno], language, user->language);
07802       ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 
07803       /* Keep this check last */
07804       if (!ast_strlen_zero(user->dbsecret)) {
07805          char *family, *key=NULL;
07806          char buf[80];
07807          family = ast_strdupa(user->dbsecret);
07808          key = strchr(family, '/');
07809          if (key) {
07810             *key = '\0';
07811             key++;
07812          }
07813          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07814             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07815          else
07816             ast_string_field_set(iaxs[callno], secret, buf);
07817       } else
07818          ast_string_field_set(iaxs[callno], secret, user->secret);
07819       res = 0;
07820       user = user_unref(user);
07821    } else {
07822        /* user was not found, but we should still fake an AUTHREQ.
07823         * Set authmethods to the last known authmethod used by the system
07824         * Set a fake secret, it's not looked at, just required to attempt authentication.
07825         * Set authrej so the AUTHREP is rejected without even looking at its contents */
07826       iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07827       ast_string_field_set(iaxs[callno], secret, "badsecret");
07828       iaxs[callno]->authrej = 1;
07829       if (!ast_strlen_zero(iaxs[callno]->username)) {
07830          /* only send the AUTHREQ if a username was specified. */
07831          res = 0;
07832       }
07833    }
07834    ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07835    return res;
07836 }

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

Definition at line 9476 of file chan_iax2.c.

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

Referenced by socket_process().

09477 {
09478    unsigned int ourver;
09479    char rsi[80];
09480    snprintf(rsi, sizeof(rsi), "si-%s", si);
09481    if (iax_provision_version(&ourver, rsi, 1))
09482       return 0;
09483    ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09484    if (ourver != ver)
09485       iax2_provision(sin, sockfd, NULL, rsi, 1);
09486    return 0;
09487 }

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

Check if address can be used as packet source.

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

Definition at line 12330 of file chan_iax2.c.

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

Referenced by peer_set_srcaddr().

12331 {
12332    int sd;
12333    int res;
12334 
12335    sd = socket(AF_INET, SOCK_DGRAM, 0);
12336    if (sd < 0) {
12337       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12338       return -1;
12339    }
12340 
12341    res = bind(sd, sa, salen);
12342    if (res < 0) {
12343       ast_debug(1, "Can't bind: %s\n", strerror(errno));
12344       close(sd);
12345       return 1;
12346    }
12347 
12348    close(sd);
12349    return 0;
12350 }

static void cleanup_thread_list ( void *  head  )  [static]

Definition at line 14362 of file chan_iax2.c.

References AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, iax2_thread::cond, iax2_thread::lock, signal_condition(), iax2_thread::stop, thread, and iax2_thread::threadid.

Referenced by __unload_module().

14363 {
14364    AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14365    struct iax2_thread_list *list_head = head;
14366    struct iax2_thread *thread;
14367 
14368    AST_LIST_LOCK(list_head);
14369    while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
14370       pthread_t thread_id = thread->threadid;
14371 
14372       thread->stop = 1;
14373       signal_condition(&thread->lock, &thread->cond);
14374 
14375       AST_LIST_UNLOCK(list_head);
14376       pthread_join(thread_id, NULL);
14377       AST_LIST_LOCK(list_head);
14378    }
14379    AST_LIST_UNLOCK(list_head);
14380 }

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

Definition at line 8394 of file chan_iax2.c.

References ARRAY_LEN, ast_copy_string(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_UNKNOWN, iax_ies::called_number, iax2_dpcache::callno, iax_ies::dpstatus, iax2_dpcache::expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, matchmore(), iax2_dpcache::orig, iax2_dpcache::peer_list, iax_ies::refresh, status, and iax2_dpcache::waiters.

Referenced by socket_process().

08395 {
08396    char exten[256] = "";
08397    int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08398    struct iax2_dpcache *dp = NULL;
08399    
08400    if (ies->called_number)
08401       ast_copy_string(exten, ies->called_number, sizeof(exten));
08402    
08403    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08404       status = CACHE_FLAG_EXISTS;
08405    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08406       status = CACHE_FLAG_CANEXIST;
08407    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08408       status = CACHE_FLAG_NONEXISTENT;
08409 
08410    if (ies->refresh)
08411       expiry = ies->refresh;
08412    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08413       matchmore = CACHE_FLAG_MATCHMORE;
08414    
08415    AST_LIST_LOCK(&dpcache);
08416    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08417       if (strcmp(dp->exten, exten))
08418          continue;
08419       AST_LIST_REMOVE_CURRENT(peer_list);
08420       dp->callno = 0;
08421       dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08422       if (dp->flags & CACHE_FLAG_PENDING) {
08423          dp->flags &= ~CACHE_FLAG_PENDING;
08424          dp->flags |= status;
08425          dp->flags |= matchmore;
08426       }
08427       /* Wake up waiters */
08428       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08429          if (dp->waiters[x] > -1) {
08430             if (write(dp->waiters[x], "asdf", 4) < 0) {
08431             }
08432          }
08433       }
08434    }
08435    AST_LIST_TRAVERSE_SAFE_END;
08436    AST_LIST_UNLOCK(&dpcache);
08437 
08438    return 0;
08439 }

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

Definition at line 3886 of file chan_iax2.c.

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

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

03887 {
03888    int which = 0;
03889    struct iax2_peer *peer;
03890    char *res = NULL;
03891    int wordlen = strlen(word);
03892    struct ao2_iterator i;
03893 
03894    i = ao2_iterator_init(peers, 0);
03895    while ((peer = ao2_iterator_next(&i))) {
03896       if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03897          && (!flags || ast_test_flag64(peer, flags))) {
03898          res = ast_strdup(peer->name);
03899          peer_unref(peer);
03900          break;
03901       }
03902       peer_unref(peer);
03903    }
03904    ao2_iterator_destroy(&i);
03905 
03906    return res;
03907 }

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

Definition at line 6964 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_unregister().

06965 {
06966    int which = 0;
06967    struct iax2_peer *p = NULL;
06968    char *res = NULL;
06969    int wordlen = strlen(word);
06970 
06971    /* 0 - iax2; 1 - unregister; 2 - <peername> */
06972    if (pos == 2) {
06973       struct ao2_iterator i = ao2_iterator_init(peers, 0);
06974       while ((p = ao2_iterator_next(&i))) {
06975          if (!strncasecmp(p->name, word, wordlen) && 
06976             ++which > state && p->expire > 0) {
06977             res = ast_strdup(p->name);
06978             peer_unref(p);
06979             break;
06980          }
06981          peer_unref(p);
06982       }
06983       ao2_iterator_destroy(&i);
06984    }
06985 
06986    return res;
06987 }

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

Definition at line 8441 of file chan_iax2.c.

References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, AST_LIST_TRAVERSE, ast_log(), iax_ies::callno, jb_frame::data, DEFAULT_RETRY_TIME, frame_queue, iax2_frame_free(), chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingtime, remove_by_peercallno(), remove_by_transfercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, store_by_peercallno(), chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.

Referenced by socket_process().

08442 {
08443    int peercallno = 0;
08444    struct chan_iax2_pvt *pvt = iaxs[callno];
08445    struct iax_frame *cur;
08446    jb_frame frame;
08447 
08448    if (ies->callno)
08449       peercallno = ies->callno;
08450 
08451    if (peercallno < 1) {
08452       ast_log(LOG_WARNING, "Invalid transfer request\n");
08453       return -1;
08454    }
08455    remove_by_transfercallno(pvt);
08456    /* since a transfer has taken place, the address will change.
08457     * This must be accounted for in the peercnts table.  Remove
08458     * the old address and add the new one */
08459    peercnt_remove_by_addr(&pvt->addr);
08460    peercnt_add(&pvt->transfer);
08461    /* now copy over the new address */
08462    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08463    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08464    /* Reset sequence numbers */
08465    pvt->oseqno = 0;
08466    pvt->rseqno = 0;
08467    pvt->iseqno = 0;
08468    pvt->aseqno = 0;
08469 
08470    if (pvt->peercallno) {
08471       remove_by_peercallno(pvt);
08472    }
08473    pvt->peercallno = peercallno;
08474    /*this is where the transfering call swiches hash tables */
08475    store_by_peercallno(pvt);
08476    pvt->transferring = TRANSFER_NONE;
08477    pvt->svoiceformat = -1;
08478    pvt->voiceformat = 0;
08479    pvt->svideoformat = -1;
08480    pvt->videoformat = 0;
08481    pvt->transfercallno = 0;
08482    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08483    memset(&pvt->offset, 0, sizeof(pvt->offset));
08484    /* reset jitterbuffer */
08485    while(jb_getall(pvt->jb,&frame) == JB_OK)
08486       iax2_frame_free(frame.data);
08487    jb_reset(pvt->jb);
08488    pvt->lag = 0;
08489    pvt->last = 0;
08490    pvt->lastsent = 0;
08491    pvt->nextpred = 0;
08492    pvt->pingtime = DEFAULT_RETRY_TIME;
08493    AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08494       /* We must cancel any packets that would have been transmitted
08495          because now we're talking to someone new.  It's okay, they
08496          were transmitted to someone that didn't care anyway. */
08497       cur->retries = -1;
08498    }
08499    return 0;
08500 }

static unsigned char compress_subclass ( iax2_format  subclass  )  [static]

Definition at line 1605 of file chan_iax2.c.

References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.

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

01606 {
01607    int x;
01608    int power=-1;
01609    /* If it's 64 or smaller, just return it */
01610    if (subclass < IAX_FLAG_SC_LOG)
01611       return subclass;
01612    /* Otherwise find its power */
01613    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01614       if (subclass & (1LL << x)) {
01615          if (power > -1) {
01616             ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass);
01617             return 0;
01618          } else
01619             power = x;
01620       }
01621    }
01622    return power | IAX_FLAG_SC_LOG;
01623 }

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

Definition at line 9489 of file chan_iax2.c.

References jb_info::current, jb_info::frames_dropped, jb_info::frames_in, jb_info::frames_lost, jb_info::frames_ooo, iax_ie_append_int(), iax_ie_append_short(), IAX_IE_RR_DELAY, IAX_IE_RR_DROPPED, IAX_IE_RR_JITTER, IAX_IE_RR_LOSS, IAX_IE_RR_OOO, IAX_IE_RR_PKTS, chan_iax2_pvt::jb, jb_getinfo(), jb_info::jitter, jb_info::losspct, and jb_info::min.

Referenced by socket_process().

09490 {
09491    jb_info stats;
09492    jb_getinfo(pvt->jb, &stats);
09493 
09494    memset(iep, 0, sizeof(*iep));
09495 
09496    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09497    if(stats.frames_in == 0) stats.frames_in = 1;
09498    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09499    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09500    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09501    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09502    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09503 }

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

Definition at line 4616 of file chan_iax2.c.

References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ast_clear_flag64, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags64, ast_copy_string(), ast_db_get(), ast_debug, ast_format_cap_iter_end(), ast_format_cap_iter_next(), ast_format_cap_iter_start(), ast_get_ip_or_srv(), ast_getformatname(), ast_log(), ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, iax2_peer::cid_name, create_addr_info::cid_name, iax2_peer::cid_num, create_addr_info::cid_num, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, IAX_DEFAULT_PORTNO, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::mohinterpret, create_addr_info::mohinterpret, iax2_peer::mohsuggest, create_addr_info::mohsuggest, ast_channel::nativeformats, iax2_peer::outkey, create_addr_info::outkey, peer_unref(), iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, ast_sockaddr::ss, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.

04617 {
04618    struct iax2_peer *peer;
04619    int res = -1;
04620    struct ast_codec_pref ourprefs;
04621    struct sockaddr_in peer_addr;
04622 
04623    ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04624    cai->sockfd = defaultsockfd;
04625    cai->maxtime = 0;
04626    sin->sin_family = AF_INET;
04627 
04628    if (!(peer = find_peer(peername, 1))) {
04629       struct ast_sockaddr sin_tmp;
04630 
04631       cai->found = 0;
04632       sin_tmp.ss.ss_family = AF_INET;
04633       if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
04634          ast_log(LOG_WARNING, "No such host: %s\n", peername);
04635          return -1;
04636       }
04637       ast_sockaddr_to_sin(&sin_tmp, sin);
04638       if (sin->sin_port == 0) {
04639          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04640       }
04641       /* use global iax prefs for unknown peer/user */
04642       /* But move the calling channel's native codec to the top of the preference list */
04643       memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04644       if (c) {
04645          struct ast_format tmpfmt;
04646          ast_format_cap_iter_start(c->nativeformats);
04647          while (!(ast_format_cap_iter_next(c->nativeformats, &tmpfmt))) {
04648             ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
04649          }
04650          ast_format_cap_iter_end(c->nativeformats);
04651       }
04652       ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04653       return 0;
04654    }
04655 
04656    cai->found = 1;
04657 
04658    ast_sockaddr_to_sin(&peer->addr, &peer_addr);
04659 
04660    /* if the peer has no address (current or default), return failure */
04661    if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
04662       goto return_unref;
04663    }
04664 
04665    /* if the peer is being monitored and is currently unreachable, return failure */
04666    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04667       goto return_unref;
04668 
04669    ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04670    cai->maxtime = peer->maxms;
04671    cai->capability = peer->capability;
04672    cai->encmethods = peer->encmethods;
04673    cai->sockfd = peer->sockfd;
04674    cai->adsi = peer->adsi;
04675    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04676    /* Move the calling channel's native codec to the top of the preference list */
04677    if (c) {
04678       struct ast_format tmpfmt;
04679       ast_format_cap_iter_start(c->nativeformats);
04680       while (!(ast_format_cap_iter_next(c->nativeformats, &tmpfmt))) {
04681          ast_debug(1, "prepending %s to prefs\n", ast_getformatname(&tmpfmt));
04682          ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
04683       }
04684       ast_format_cap_iter_end(c->nativeformats);
04685    }
04686    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04687    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04688    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04689    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04690    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04691    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04692    ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04693    ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04694    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04695    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04696    if (ast_strlen_zero(peer->dbsecret)) {
04697       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04698    } else {
04699       char *family;
04700       char *key = NULL;
04701 
04702       family = ast_strdupa(peer->dbsecret);
04703       key = strchr(family, '/');
04704       if (key)
04705          *key++ = '\0';
04706       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04707          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04708          goto return_unref;
04709       }
04710    }
04711 
04712    if (peer_addr.sin_addr.s_addr) {
04713       sin->sin_addr = peer_addr.sin_addr;
04714       sin->sin_port = peer_addr.sin_port;
04715    } else {
04716       sin->sin_addr = peer->defaddr.sin_addr;
04717       sin->sin_port = peer->defaddr.sin_port;
04718    }
04719 
04720    res = 0;
04721 
04722 return_unref:
04723    peer_unref(peer);
04724 
04725    return res;
04726 }

static int create_callno_pools ( void   )  [static]

Definition at line 2739 of file chan_iax2.c.

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

Referenced by load_objects().

02740 {
02741    uint16_t i;
02742 
02743    if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02744       return -1;
02745    }
02746 
02747    if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02748       return -1;
02749    }
02750 
02751    /* start at 2, 0 and 1 are reserved */
02752    for (i = 2; i <= IAX_MAX_CALLS; i++) {
02753       struct callno_entry *callno_entry;
02754 
02755       if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02756          return -1;
02757       }
02758 
02759       callno_entry->callno = i;
02760 
02761       if (i < TRUNK_CALL_START) {
02762          ao2_link(callno_pool, callno_entry);
02763       } else {
02764          ao2_link(callno_pool_trunk, callno_entry);
02765       }
02766 
02767       ao2_ref(callno_entry, -1);
02768    }
02769 
02770    return 0;
02771 }

static int decode_frame ( ast_aes_decrypt_key dcx,
struct ast_iax2_full_hdr fh,
struct ast_frame f,
int *  datalen 
) [static]

Definition at line 6315 of file chan_iax2.c.

References ast_debug, ast_format_from_old_bitfield(), AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, ast_frame_subclass::format, ast_frame::frametype, IAX_FLAG_FULL, ast_frame_subclass::integer, memcpy_decrypt(), ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass().

Referenced by decrypt_frame(), and update_packet().

06316 {
06317    int padding;
06318    unsigned char *workspace;
06319 
06320    workspace = alloca(*datalen);
06321    memset(f, 0, sizeof(*f));
06322    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06323       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06324       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06325          return -1;
06326       /* Decrypt */
06327       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06328 
06329       padding = 16 + (workspace[15] & 0x0f);
06330       if (iaxdebug)
06331          ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06332       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06333          return -1;
06334 
06335       *datalen -= padding;
06336       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06337       f->frametype = fh->type;
06338       if (f->frametype == AST_FRAME_VIDEO) {
06339          ast_format_from_old_bitfield(&f->subclass.format, (uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1)));
06340       } else if (f->frametype == AST_FRAME_VOICE) {
06341          ast_format_from_old_bitfield(&f->subclass.format, uncompress_subclass(fh->csub));
06342       } else {
06343          f->subclass.integer = uncompress_subclass(fh->csub);
06344       }
06345    } else {
06346       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06347       if (iaxdebug)
06348          ast_debug(1, "Decoding mini with length %d\n", *datalen);
06349       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06350          return -1;
06351       /* Decrypt */
06352       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06353       padding = 16 + (workspace[15] & 0x0f);
06354       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06355          return -1;
06356       *datalen -= padding;
06357       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06358    }
06359    return 0;
06360 }

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

Definition at line 6403 of file chan_iax2.c.

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

Referenced by socket_process().

06404 {
06405    int res=-1;
06406    if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06407       /* Search for possible keys, given secrets */
06408       struct MD5Context md5;
06409       unsigned char digest[16];
06410       char *tmppw, *stringp;
06411       
06412       tmppw = ast_strdupa(iaxs[callno]->secret);
06413       stringp = tmppw;
06414       while ((tmppw = strsep(&stringp, ";"))) {
06415          MD5Init(&md5);
06416          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06417          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06418          MD5Final(digest, &md5);
06419          build_encryption_keys(digest, iaxs[callno]);
06420          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06421          if (!res) {
06422             ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06423             break;
06424          }
06425       }
06426    } else 
06427       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06428    return res;
06429 }

static void defer_full_frame ( struct iax2_thread from_here,
struct iax2_thread to_here 
) [static]

Queue the last read full frame for processing by a certain thread.

If there are already any full frames queued, they are sorted by sequence number.

Definition at line 9636 of file chan_iax2.c.

References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock, ast_mutex_unlock, iax2_thread::buf, iax2_pkt_buf::buf, iax2_thread::buf_len, iax2_thread::full_frames, iax2_pkt_buf::len, iax2_thread::lock, and ast_iax2_full_hdr::oseqno.

Referenced by socket_read().

09637 {
09638    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09639    struct ast_iax2_full_hdr *fh, *cur_fh;
09640 
09641    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09642       return;
09643 
09644    pkt_buf->len = from_here->buf_len;
09645    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09646 
09647    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09648    ast_mutex_lock(&to_here->lock);
09649    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09650       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09651       if (fh->oseqno < cur_fh->oseqno) {
09652          AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09653          break;
09654       }
09655    }
09656    AST_LIST_TRAVERSE_SAFE_END
09657 
09658    if (!cur_pkt_buf)
09659       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09660 
09661    ast_mutex_unlock(&to_here->lock);
09662 }

static void delete_users ( void   )  [static]

Definition at line 13014 of file chan_iax2.c.

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

13015 {
13016    struct iax2_registry *reg;
13017 
13018    ao2_callback(users, 0, user_delme_cb, NULL);
13019 
13020    AST_LIST_LOCK(&registrations);
13021    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
13022       if (sched) {
13023          AST_SCHED_DEL(sched, reg->expire);
13024       }
13025       if (reg->callno) {
13026          int callno = reg->callno;
13027          ast_mutex_lock(&iaxsl[callno]);
13028          if (iaxs[callno]) {
13029             iaxs[callno]->reg = NULL;
13030             iax2_destroy(callno);
13031          }
13032          ast_mutex_unlock(&iaxsl[callno]);
13033       }
13034       if (reg->dnsmgr)
13035          ast_dnsmgr_release(reg->dnsmgr);
13036       ast_free(reg);
13037    }
13038    AST_LIST_UNLOCK(&registrations);
13039 
13040    ao2_callback(peers, 0, peer_delme_cb, NULL);
13041 }

static void destroy_firmware ( struct iax_firmware cur  )  [static]

Definition at line 3069 of file chan_iax2.c.

References ast_free, ast_iax2_firmware_header::datalen, iax_firmware::fd, and iax_firmware::fwh.

Referenced by reload_firmware().

03070 {
03071    /* Close firmware */
03072    if (cur->fwh) {
03073       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
03074    }
03075    close(cur->fd);
03076    ast_free(cur);
03077 }

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

Definition at line 9291 of file chan_iax2.c.

References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_IAX, ast_ignore_pattern(), ast_matchmore_extension(), ast_mutex_lock, ast_mutex_unlock, ast_parking_ext_valid(), iax_ie_data::buf, IAX_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iax_ie_data::pos, and send_command().

Referenced by dp_lookup_thread(), and socket_process().

09292 {
09293    unsigned short dpstatus = 0;
09294    struct iax_ie_data ied1;
09295    int mm;
09296 
09297    memset(&ied1, 0, sizeof(ied1));
09298    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09299    /* Must be started */
09300    if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09301       dpstatus = IAX_DPSTATUS_EXISTS;
09302    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09303       dpstatus = IAX_DPSTATUS_CANEXIST;
09304    } else {
09305       dpstatus = IAX_DPSTATUS_NONEXISTENT;
09306    }
09307    if (ast_ignore_pattern(context, callednum))
09308       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09309    if (mm)
09310       dpstatus |= IAX_DPSTATUS_MATCHMORE;
09311    if (!skiplock)
09312       ast_mutex_lock(&iaxsl[callno]);
09313    if (iaxs[callno]) {
09314       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09315       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09316       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09317       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09318    }
09319    if (!skiplock)
09320       ast_mutex_unlock(&iaxsl[callno]);
09321 }

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

Definition at line 9323 of file chan_iax2.c.

References ast_free, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, and dp_lookup().

Referenced by spawn_dp_lookup().

09324 {
09325    /* Look up for dpreq */
09326    struct dpreq_data *dpr = data;
09327    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09328    if (dpr->callerid)
09329       ast_free(dpr->callerid);
09330    ast_free(dpr);
09331    return NULL;
09332 }

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

Definition at line 1539 of file chan_iax2.c.

References ast_str_append(), ast_str_set(), ast_str_strlen(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.

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

01540 {
01541    ast_str_set(&buf, 0, "(");
01542    if (e & IAX_ENCRYPT_AES128) {
01543       ast_str_append(&buf, 0, "aes128");
01544    }
01545    if (e & IAX_ENCRYPT_KEYROTATE) {
01546       ast_str_append(&buf, 0, ",keyrotate");
01547    }
01548    if (ast_str_strlen(buf) > 1) {
01549       ast_str_append(&buf, 0, ")");
01550    } else {
01551       ast_str_set(&buf, 0, "No");
01552    }
01553 }

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

Definition at line 6362 of file chan_iax2.c.

References ast_debug, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, IAX_FLAG_FULL, memcpy_encrypt(), ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.

Referenced by iax2_send(), and update_packet().

06363 {
06364    int padding;
06365    unsigned char *workspace;
06366    workspace = alloca(*datalen + 32);
06367    if (!workspace)
06368       return -1;
06369    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06370       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06371       if (iaxdebug)
06372          ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06373       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06374       padding = 16 + (padding & 0xf);
06375       memcpy(workspace, poo, padding);
06376       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06377       workspace[15] &= 0xf0;
06378       workspace[15] |= (padding & 0xf);
06379       if (iaxdebug)
06380          ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06381       *datalen += padding;
06382       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06383       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06384          memcpy(poo, workspace + *datalen - 32, 32);
06385    } else {
06386       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06387       if (iaxdebug)
06388          ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06389       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06390       padding = 16 + (padding & 0xf);
06391       memcpy(workspace, poo, padding);
06392       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06393       workspace[15] &= 0xf0;
06394       workspace[15] |= (padding & 0x0f);
06395       *datalen += padding;
06396       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06397       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06398          memcpy(poo, workspace + *datalen - 32, 32);
06399    }
06400    return 0;
06401 }

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

Definition at line 8709 of file chan_iax2.c.

References __expire_registry(), and schedule_action.

Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), realtime_peer(), reg_source_db(), and update_registry().

08710 {
08711 #ifdef SCHED_MULTITHREADED
08712    if (schedule_action(__expire_registry, data))
08713 #endif      
08714       __expire_registry(data);
08715    return 0;
08716 }

static struct iax2_dpcache* find_cache ( struct ast_channel chan,
const char *  data,
const char *  context,
const char *  exten,
int  priority 
) [static, read]

Definition at line 13701 of file chan_iax2.c.

References ARRAY_LEN, ast_calloc, ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_copy_string(), ast_free, ast_frfree, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_unlock, ast_read(), ast_test_flag, ast_tvcmp(), ast_tvnow(), ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, errno, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, iax2_dprequest(), IAX_STATE_STARTED, LOG_WARNING, iax2_dpcache::orig, iax2_dpcache::peercontext, and iax2_dpcache::waiters.

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

13702 {
13703    struct iax2_dpcache *dp = NULL;
13704    struct timeval now = ast_tvnow();
13705    int x, com[2], timeout, old = 0, outfd, doabort, callno;
13706    struct ast_channel *c = NULL;
13707    struct ast_frame *f = NULL;
13708 
13709    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13710       if (ast_tvcmp(now, dp->expiry) > 0) {
13711          AST_LIST_REMOVE_CURRENT(cache_list);
13712          if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13713             ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13714          else
13715             ast_free(dp);
13716          continue;
13717       }
13718       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13719          break;
13720    }
13721    AST_LIST_TRAVERSE_SAFE_END;
13722 
13723    if (!dp) {
13724       /* No matching entry.  Create a new one. */
13725       /* First, can we make a callno? */
13726       if ((callno = cache_get_callno_locked(data)) < 0) {
13727          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13728          return NULL;
13729       }
13730       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13731          ast_mutex_unlock(&iaxsl[callno]);
13732          return NULL;
13733       }
13734       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13735       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13736       dp->expiry = ast_tvnow();
13737       dp->orig = dp->expiry;
13738       /* Expires in 30 mins by default */
13739       dp->expiry.tv_sec += iaxdefaultdpcache;
13740       dp->flags = CACHE_FLAG_PENDING;
13741       for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13742          dp->waiters[x] = -1;
13743       /* Insert into the lists */
13744       AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13745       AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13746       /* Send the request if we're already up */
13747       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13748          iax2_dprequest(dp, callno);
13749       ast_mutex_unlock(&iaxsl[callno]);
13750    }
13751 
13752    /* By here we must have a dp */
13753    if (dp->flags & CACHE_FLAG_PENDING) {
13754       /* Okay, here it starts to get nasty.  We need a pipe now to wait
13755          for a reply to come back so long as it's pending */
13756       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13757          /* Find an empty slot */
13758          if (dp->waiters[x] < 0)
13759             break;
13760       }
13761       if (x >= ARRAY_LEN(dp->waiters)) {
13762          ast_log(LOG_WARNING, "No more waiter positions available\n");
13763          return NULL;
13764       }
13765       if (pipe(com)) {
13766          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13767          return NULL;
13768       }
13769       dp->waiters[x] = com[1];
13770       /* Okay, now we wait */
13771       timeout = iaxdefaulttimeout * 1000;
13772       /* Temporarily unlock */
13773       AST_LIST_UNLOCK(&dpcache);
13774       /* Defer any dtmf */
13775       if (chan)
13776          old = ast_channel_defer_dtmf(chan);
13777       doabort = 0;
13778       while(timeout) {
13779          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
13780          if (outfd > -1)
13781             break;
13782          if (!c)
13783             continue;
13784          if (!(f = ast_read(c))) {
13785             doabort = 1;
13786             break;
13787          }
13788          ast_frfree(f);
13789       }
13790       if (!timeout) {
13791          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13792       }
13793       AST_LIST_LOCK(&dpcache);
13794       dp->waiters[x] = -1;
13795       close(com[1]);
13796       close(com[0]);
13797       if (doabort) {
13798          /* Don't interpret anything, just abort.  Not sure what th epoint
13799            of undeferring dtmf on a hung up channel is but hey whatever */
13800          if (!old && chan)
13801             ast_channel_undefer_dtmf(chan);
13802          return NULL;
13803       }
13804       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13805          /* Now to do non-independent analysis the results of our wait */
13806          if (dp->flags & CACHE_FLAG_PENDING) {
13807             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
13808                pending.  Don't let it take as long to timeout. */
13809             dp->flags &= ~CACHE_FLAG_PENDING;
13810             dp->flags |= CACHE_FLAG_TIMEOUT;
13811             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
13812                systems without leaving it unavailable once the server comes back online */
13813             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13814             for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13815                if (dp->waiters[x] > -1) {
13816                   if (write(dp->waiters[x], "asdf", 4) < 0) {
13817                      ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13818                   }
13819                }
13820             }
13821          }
13822       }
13823       /* Our caller will obtain the rest */
13824       if (!old && chan)
13825          ast_channel_undefer_dtmf(chan);
13826    }
13827    return dp;  
13828 }

static int find_callno ( unsigned short  callno,
unsigned short  dcallno,
struct sockaddr_in *  sin,
int  new,
int  sockfd,
int  full_frame 
) [static]

Definition at line 2994 of file chan_iax2.c.

References __find_callno().

Referenced by iax2_poke_peer(), and socket_process().

02994                                                                                                                                     { 
02995    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02996 }

static int find_callno_locked ( unsigned short  callno,
unsigned short  dcallno,
struct sockaddr_in *  sin,
int  new,
int  sockfd,
int  full_frame 
) [static]

Definition at line 2998 of file chan_iax2.c.

References __find_callno().

Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process_meta().

02998                                                                                                                                            {
02999 
03000    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
03001 }

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

Definition at line 1393 of file chan_iax2.c.

References ast_atomic_fetchadd_int(), ast_calloc, ast_cond_destroy, ast_cond_init, ast_cond_wait, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, iax2_thread::cond, iax2_thread::ffinfo, iax2_process_thread(), IAX_THREAD_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, iax2_thread::init_cond, iax2_thread::init_lock, iax2_thread::lock, thread, iax2_thread::threadid, iax2_thread::threadnum, and iax2_thread::type.

Referenced by __schedule_action(), and socket_read().

01394 {
01395    struct iax2_thread *thread = NULL;
01396 
01397    /* Pop the head of the idle list off */
01398    AST_LIST_LOCK(&idle_list);
01399    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01400    AST_LIST_UNLOCK(&idle_list);
01401 
01402    /* If we popped a thread off the idle list, just return it */
01403    if (thread) {
01404       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01405       return thread;
01406    }
01407 
01408    /* Pop the head of the dynamic list off */
01409    AST_LIST_LOCK(&dynamic_list);
01410    thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01411    AST_LIST_UNLOCK(&dynamic_list);
01412 
01413    /* If we popped a thread off the dynamic list, just return it */
01414    if (thread) {
01415       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01416       return thread;
01417    }
01418 
01419    /* If we can't create a new dynamic thread for any reason, return no thread at all */
01420    if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01421       return NULL;
01422 
01423    /* Set default values */
01424    ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01425    thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01426    thread->type = IAX_THREAD_TYPE_DYNAMIC;
01427 
01428    /* Initialize lock and condition */
01429    ast_mutex_init(&thread->lock);
01430    ast_cond_init(&thread->cond, NULL);
01431    ast_mutex_init(&thread->init_lock);
01432    ast_cond_init(&thread->init_cond, NULL);
01433    ast_mutex_lock(&thread->init_lock);
01434 
01435    /* Create thread and send it on it's way */
01436    if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01437       ast_cond_destroy(&thread->cond);
01438       ast_mutex_destroy(&thread->lock);
01439       ast_mutex_unlock(&thread->init_lock);
01440       ast_cond_destroy(&thread->init_cond);
01441       ast_mutex_destroy(&thread->init_lock);
01442       ast_free(thread);
01443       return NULL;
01444    }
01445 
01446    /* this thread is not processing a full frame (since it is idle),
01447       so ensure that the field for the full frame call number is empty */
01448    memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01449 
01450    /* Wait for the thread to be ready before returning it to the caller */
01451    ast_cond_wait(&thread->init_cond, &thread->init_lock);
01452 
01453    /* Done with init_lock */
01454    ast_mutex_unlock(&thread->init_lock);
01455 
01456    return thread;
01457 }

static struct iax2_peer* find_peer ( const char *  name,
int  realtime 
) [static, read]

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

References ao2_find, OBJ_KEY, and realtime_peer().

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

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

Definition at line 6134 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_calloc, ast_debug, ast_inet_ntoa(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_init, ast_mutex_lock, ast_tvnow(), inaddrcmp(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lock, iax2_trunk_peer::sockfd, and iax2_trunk_peer::trunkact.

Referenced by iax2_trunk_queue(), and socket_process_meta().

06135 {
06136    struct iax2_trunk_peer *tpeer = NULL;
06137    
06138    /* Finds and locks trunk peer */
06139    AST_LIST_LOCK(&tpeers);
06140 
06141    AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06142       if (!inaddrcmp(&tpeer->addr, sin)) {
06143          ast_mutex_lock(&tpeer->lock);
06144          break;
06145       }
06146    }
06147 
06148    if (!tpeer) {
06149       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06150          ast_mutex_init(&tpeer->lock);
06151          tpeer->lastsent = 9999;
06152          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06153          tpeer->trunkact = ast_tvnow();
06154          ast_mutex_lock(&tpeer->lock);
06155          tpeer->sockfd = fd;
06156 #ifdef SO_NO_CHECK
06157          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06158 #endif
06159          ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06160          AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06161       }
06162    }
06163 
06164    AST_LIST_UNLOCK(&tpeers);
06165 
06166    return tpeer;
06167 }

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

Definition at line 1798 of file chan_iax2.c.

References ao2_find, and OBJ_KEY.

01799 {
01800    return ao2_find(users, name, OBJ_KEY);
01801 }

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

Definition at line 5946 of file chan_iax2.c.

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

Referenced by socket_process_meta().

05947 {
05948    long ms; /* NOT unsigned */
05949    if (ast_tvzero(iaxs[callno]->rxcore)) {
05950       /* Initialize rxcore time if appropriate */
05951       iaxs[callno]->rxcore = ast_tvnow();
05952       /* Round to nearest 20ms so traces look pretty */
05953       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05954    }
05955    /* Calculate difference between trunk and channel */
05956    ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05957    /* Return as the sum of trunk time and the difference between trunk and real time */
05958    return ms + ts;
05959 }

static void free_context ( struct iax2_context con  )  [static]

Definition at line 12161 of file chan_iax2.c.

References ast_free, and iax2_context::next.

Referenced by build_user(), and user_destructor().

12162 {
12163    struct iax2_context *conl;
12164    while(con) {
12165       conl = con;
12166       con = con->next;
12167       ast_free(conl);
12168    }
12169 }

static void free_signaling_queue_entry ( struct signaling_queue_entry s  )  [static]

Definition at line 1895 of file chan_iax2.c.

References ast_free, ast_frame::data, ast_frame::datalen, signaling_queue_entry::f, and ast_frame::ptr.

Referenced by pvt_destructor(), queue_signalling(), and send_signaling().

01896 {
01897    if (s->f.datalen) {
01898       ast_free(s->f.data.ptr);
01899    }
01900    ast_free(s);
01901 }

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

Definition at line 13951 of file chan_iax2.c.

References iax2_peer::addr, iax2_trunk_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_inet_ntoa(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_test_flag64, iax2_peer::callno, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), iax2_getformatname_multiple(), IAX_DYNAMIC, iax2_peer::mailbox, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.

13952 {
13953    struct iax2_peer *peer;
13954    char *peername, *colname;
13955 
13956    peername = ast_strdupa(data);
13957 
13958    /* if our channel, return the IP address of the endpoint of current channel */
13959    if (!strcmp(peername,"CURRENTCHANNEL")) {
13960            unsigned short callno;
13961       if (chan->tech != &iax2_tech)
13962          return -1;
13963       callno = PTR_TO_CALLNO(chan->tech_pvt);   
13964       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13965       return 0;
13966    }
13967 
13968    if ((colname = strchr(peername, ',')))
13969       *colname++ = '\0';
13970    else
13971       colname = "ip";
13972 
13973    if (!(peer = find_peer(peername, 1)))
13974       return -1;
13975 
13976    if (!strcasecmp(colname, "ip")) {
13977       ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
13978    } else  if (!strcasecmp(colname, "status")) {
13979       peer_status(peer, buf, len); 
13980    } else  if (!strcasecmp(colname, "mailbox")) {
13981       ast_copy_string(buf, peer->mailbox, len);
13982    } else  if (!strcasecmp(colname, "context")) {
13983       ast_copy_string(buf, peer->context, len);
13984    } else  if (!strcasecmp(colname, "expire")) {
13985       snprintf(buf, len, "%d", peer->expire);
13986    } else  if (!strcasecmp(colname, "dynamic")) {
13987       ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13988    } else  if (!strcasecmp(colname, "callerid_name")) {
13989       ast_copy_string(buf, peer->cid_name, len);
13990    } else  if (!strcasecmp(colname, "callerid_num")) {
13991       ast_copy_string(buf, peer->cid_num, len);
13992    } else  if (!strcasecmp(colname, "codecs")) {
13993       iax2_getformatname_multiple(buf, len -1, peer->capability);
13994    } else  if (!strncasecmp(colname, "codec[", 6)) {
13995       char *codecnum, *ptr;
13996       struct ast_format tmpfmt;
13997       codecnum = strchr(colname, '[');
13998       *codecnum = '\0';
13999       codecnum++;
14000       if ((ptr = strchr(codecnum, ']'))) {
14001          *ptr = '\0';
14002       }
14003       if((ast_codec_pref_index(&peer->prefs, atoi(codecnum), &tmpfmt))) {
14004          ast_copy_string(buf, ast_getformatname(&tmpfmt), len);
14005       } else {
14006          buf[0] = '\0';
14007       }
14008    } else {
14009       buf[0] = '\0';
14010    }
14011 
14012    peer_unref(peer);
14013 
14014    return 0;
14015 }

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

Definition at line 12314 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

12315 {
12316    int methods = 0;
12317    if (strstr(value, "rsa"))
12318       methods |= IAX_AUTH_RSA;
12319    if (strstr(value, "md5"))
12320       methods |= IAX_AUTH_MD5;
12321    if (strstr(value, "plaintext"))
12322       methods |= IAX_AUTH_PLAINTEXT;
12323    return methods;
12324 }

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

Definition at line 1555 of file chan_iax2.c.

References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.

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

01556 {
01557    int e;
01558    if (!strcasecmp(s, "aes128"))
01559       e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01560    else if (ast_true(s))
01561       e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01562    else
01563       e = 0;
01564    return e;
01565 }

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

Definition at line 4198 of file chan_iax2.c.

References __get_from_jb(), and schedule_action.

Referenced by update_jbsched().

04199 {
04200 #ifdef SCHED_MULTITHREADED
04201    if (schedule_action(__get_from_jb, data))
04202 #endif      
04203       __get_from_jb(data);
04204    return 0;
04205 }

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

Definition at line 2672 of file chan_iax2.c.

References ao2_container_count(), ao2_find, ao2_lock, ao2_unlock, ast_log(), LOG_WARNING, OBJ_CONTINUE, OBJ_POINTER, OBJ_UNLINK, and callno_entry::validated.

Referenced by __find_callno(), and make_trunk().

02673 {
02674    struct callno_entry *callno_entry = NULL;
02675    if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02676       ast_log(LOG_WARNING, "Out of CallNumbers\n");
02677       /* Minor optimization for the extreme case. */
02678       return NULL;
02679    }
02680 
02681    /* the callno_pool container is locked here primarily to ensure thread
02682     * safety of the total_nonval_callno_used check and increment */
02683    ao2_lock(callno_pool);
02684 
02685    /* only a certain number of nonvalidated call numbers should be allocated.
02686     * If there ever is an attack, this separates the calltoken validating
02687     * users from the non calltoken validating users. */
02688    if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02689       ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02690       ao2_unlock(callno_pool);
02691       return NULL;
02692    }
02693 
02694    /* unlink the object from the container, taking over ownership
02695     * of the reference the container had to the object */
02696    callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02697 
02698    if (callno_entry) {
02699       callno_entry->validated = validated;
02700       if (!validated) {
02701          total_nonval_callno_used++;
02702       }
02703    }
02704 
02705    ao2_unlock(callno_pool);
02706    return callno_entry;
02707 }

static int handle_call_token ( struct ast_iax2_full_hdr fh,
struct iax_ies ies,
struct sockaddr_in *  sin,
int  fd 
) [static]

Definition at line 4934 of file chan_iax2.c.

References ast_inet_ntoa(), ast_log(), ast_sha1_hash(), ast_str_alloca, ast_str_buffer(), ast_str_set(), iax_ie_data::buf, iax_ies::calltoken, CALLTOKEN_HASH_FORMAT, CALLTOKEN_IE_FORMAT, calltoken_required(), iax_ies::calltokendata, ast_iax2_full_hdr::csub, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, iax_ie_append_str(), IAX_IE_CALLTOKEN, ast_iax2_full_hdr::iseqno, LOG_ERROR, LOG_WARNING, requirecalltoken_mark_auto(), S_OR, ast_iax2_full_hdr::scallno, send_apathetic_reply(), ast_iax2_full_hdr::ts, uncompress_subclass(), and iax_ies::username.

Referenced by socket_process().

04936 {
04937 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"  /* address + port + ts + randomcalldata */
04938 #define CALLTOKEN_IE_FORMAT   "%u?%s"     /* time + ? + (40 char hash) */
04939    struct ast_str *buf = ast_str_alloca(256);
04940    time_t t = time(NULL);
04941    char hash[41]; /* 40 char sha1 hash */
04942    int subclass = uncompress_subclass(fh->csub);
04943 
04944    /* ----- Case 1 ----- */
04945    if (ies->calltoken && !ies->calltokendata) {  /* empty calltoken is provided, client supports calltokens */
04946       struct iax_ie_data ied = {
04947          .buf = { 0 },
04948          .pos = 0,
04949       };
04950 
04951       /* create the hash with their address data and our timestamp */
04952       ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04953       ast_sha1_hash(hash, ast_str_buffer(buf));
04954 
04955       ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04956       iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04957       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04958 
04959       return 1;
04960 
04961    /* ----- Case 2 ----- */
04962    } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */
04963       char *rec_hash = NULL;    /* the received hash, make sure it matches with ours. */
04964       char *rec_ts = NULL;      /* received timestamp */
04965       unsigned int rec_time;  /* received time_t */
04966 
04967       /* split the timestamp from the hash data */
04968       rec_hash = strchr((char *) ies->calltokendata, '?');
04969       if (rec_hash) {
04970          *rec_hash++ = '\0';
04971          rec_ts = (char *) ies->calltokendata;
04972       }
04973 
04974       /* check that we have valid data before we do any comparisons */
04975       if (!rec_hash || !rec_ts) {
04976          goto reject;
04977       } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04978          goto reject;
04979       }
04980 
04981       /* create a hash with their address and the _TOKEN'S_ timestamp */
04982       ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04983       ast_sha1_hash(hash, ast_str_buffer(buf));
04984 
04985       /* compare hashes and then check timestamp delay */
04986       if (strcmp(hash, rec_hash)) {
04987          ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04988          goto reject; /* received hash does not match ours, reject */
04989       } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04990          ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04991          goto reject; /* too much delay, reject */
04992       }
04993 
04994       /* at this point the call token is valid, returning 0 
04995        * will allow socket_process to continue as usual */
04996       requirecalltoken_mark_auto(ies->username, subclass);
04997       return 0;
04998 
04999    /* ----- Case 3 ----- */
05000    } else { /* calltokens are not supported for this client, how do we respond? */
05001       if (calltoken_required(sin, ies->username, subclass)) {
05002          ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenoptional list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), S_OR(ies->username, "guest"));
05003          goto reject;
05004       }
05005       return 0; /* calltoken is not required for this addr, so permit it. */
05006    }
05007 
05008 reject:
05009    /* received frame has failed calltoken inspection, send apathetic reject messages */
05010    if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
05011       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
05012    } else {
05013       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
05014    }
05015 
05016    return 1;
05017 }

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

Definition at line 12008 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, iax2_provision(), iax_prov_complete_template(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

12009 {
12010    int force = 0;
12011    int res;
12012 
12013    switch (cmd) {
12014    case CLI_INIT:
12015       e->command = "iax2 provision";
12016       e->usage = 
12017          "Usage: iax2 provision <host> <template> [forced]\n"
12018          "       Provisions the given peer or IP address using a template\n"
12019          "       matching either 'template' or '*' if the template is not\n"
12020          "       found.  If 'forced' is specified, even empty provisioning\n"
12021          "       fields will be provisioned as empty fields.\n";
12022       return NULL;
12023    case CLI_GENERATE:
12024       if (a->pos == 3)
12025          return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
12026       return NULL;
12027    }
12028 
12029    if (a->argc < 4)
12030       return CLI_SHOWUSAGE;
12031    if (a->argc > 4) {
12032       if (!strcasecmp(a->argv[4], "forced"))
12033          force = 1;
12034       else
12035          return CLI_SHOWUSAGE;
12036    }
12037    res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
12038    if (res < 0)
12039       ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
12040    else if (res < 1)
12041       ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
12042    else
12043       ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
12044    return CLI_SUCCESS;
12045 }

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

Definition at line 3627 of file chan_iax2.c.

References ao2_unlink, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), ast_set_flag64, ast_test_flag64, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), expire_registry(), ast_cli_args::fd, find_peer(), find_user(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, ast_cli_args::line, ast_cli_args::n, peer_ref(), peer_unref(), ast_cli_args::pos, prune_peers(), prune_users(), ast_cli_entry::usage, user_unref(), and ast_cli_args::word.

03628 {
03629    struct iax2_peer *peer = NULL;
03630    struct iax2_user *user = NULL;
03631    static const char * const choices[] = { "all", NULL };
03632    char *cmplt;
03633 
03634    switch (cmd) {
03635    case CLI_INIT:
03636       e->command = "iax2 prune realtime";
03637       e->usage =
03638          "Usage: iax2 prune realtime [<peername>|all]\n"
03639          "       Prunes object(s) from the cache\n";
03640       return NULL;
03641    case CLI_GENERATE:
03642       if (a->pos == 3) {
03643          cmplt = ast_cli_complete(a->word, choices, a->n);
03644          if (!cmplt)
03645             cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03646          return cmplt;
03647       }
03648       return NULL;
03649    }
03650    if (a->argc != 4)
03651       return CLI_SHOWUSAGE;
03652    if (!strcmp(a->argv[3], "all")) {
03653       prune_users();
03654       prune_peers();
03655       ast_cli(a->fd, "Cache flushed successfully.\n");
03656       return CLI_SUCCESS;
03657    }
03658    peer = find_peer(a->argv[3], 0);
03659    user = find_user(a->argv[3]);
03660    if (peer || user) {
03661       if (peer) {
03662          if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
03663             ast_set_flag64(peer, IAX_RTAUTOCLEAR);
03664             expire_registry(peer_ref(peer));
03665             ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03666          } else {
03667             ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03668          }
03669          peer_unref(peer);
03670       }
03671       if (user) {
03672          if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
03673             ast_set_flag64(user, IAX_RTAUTOCLEAR);
03674             ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03675          } else {
03676             ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03677          }
03678          ao2_unlink(users,user);
03679          user_unref(user);
03680       }
03681    } else {
03682       ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03683    }
03684 
03685    return CLI_SUCCESS;
03686 }

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

Definition at line 13605 of file chan_iax2.c.

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

13606 {
13607    switch (cmd) {
13608    case CLI_INIT:
13609       e->command = "iax2 reload";
13610       e->usage =
13611          "Usage: iax2 reload\n"
13612          "       Reloads IAX configuration from iax.conf\n";
13613       return NULL;
13614    case CLI_GENERATE:
13615       return NULL;
13616    }
13617 
13618    reload_config();
13619 
13620    return CLI_SUCCESS;
13621 }

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

Definition at line 7408 of file chan_iax2.c.

References iax2_peer::addr, ao2_ref, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_inet_ntoa(), ast_sockaddr_to_sin, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), debugaddr, ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

07409 {
07410    switch (cmd) {
07411    case CLI_INIT:
07412       e->command = "iax2 set debug {on|off|peer}";
07413       e->usage =
07414          "Usage: iax2 set debug {on|off|peer peername}\n"
07415          "       Enables/Disables dumping of IAX packets for debugging purposes.\n";
07416       return NULL;
07417    case CLI_GENERATE:
07418       if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07419          return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07420       return NULL;
07421    }
07422 
07423    if (a->argc < e->args  || a->argc > e->args + 1)
07424       return CLI_SHOWUSAGE;
07425 
07426    if (!strcasecmp(a->argv[3], "peer")) {
07427       struct iax2_peer *peer;
07428       struct sockaddr_in peer_addr;
07429 
07430 
07431       if (a->argc != e->args + 1)
07432          return CLI_SHOWUSAGE;
07433 
07434       peer = find_peer(a->argv[4], 1);
07435 
07436       if (!peer) {
07437          ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07438          return CLI_FAILURE;
07439       }
07440 
07441       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07442 
07443       debugaddr.sin_addr = peer_addr.sin_addr;
07444       debugaddr.sin_port = peer_addr.sin_port;
07445 
07446       ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07447          ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07448 
07449       ao2_ref(peer, -1);
07450    } else if (!strncasecmp(a->argv[3], "on", 2)) {
07451       iaxdebug = 1;
07452       ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07453    } else {
07454       iaxdebug = 0;
07455       memset(&debugaddr, 0, sizeof(debugaddr));
07456       ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07457    }
07458    return CLI_SUCCESS;
07459 }

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

Definition at line 7487 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), and ast_cli_entry::usage.

07488 {
07489    switch (cmd) {
07490    case CLI_INIT:
07491       e->command = "iax2 set debug jb {on|off}";
07492       e->usage =
07493          "Usage: iax2 set debug jb {on|off}\n"
07494          "       Enables/Disables jitterbuffer debugging information\n";
07495       return NULL;
07496    case CLI_GENERATE:
07497       return NULL;
07498    }
07499 
07500    if (a->argc != e->args)
07501       return CLI_SHOWUSAGE;
07502    
07503    if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07504       jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07505       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07506    } else {
07507       jb_setoutput(jb_error_output, jb_warning_output, NULL);
07508       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07509    }
07510    return CLI_SUCCESS;
07511 }

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

Definition at line 7461 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

07462 {
07463    switch (cmd) {
07464    case CLI_INIT:
07465       e->command = "iax2 set debug trunk {on|off}";
07466       e->usage =
07467          "Usage: iax2 set debug trunk {on|off}\n"
07468          "       Enables/Disables debugging of IAX trunking\n";
07469       return NULL;
07470    case CLI_GENERATE:
07471       return NULL;
07472    }
07473 
07474    if (a->argc != e->args)
07475       return CLI_SHOWUSAGE;
07476 
07477    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07478       iaxtrunkdebug = 1;
07479       ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07480    } else {
07481       iaxtrunkdebug = 0;
07482       ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07483    }
07484    return CLI_SUCCESS;
07485 }

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

Set trunk MTU from CLI.

Definition at line 3955 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, MAX_TRUNK_MTU, and ast_cli_entry::usage.

03956 {
03957    int mtuv;
03958 
03959    switch (cmd) {
03960    case CLI_INIT:
03961       e->command = "iax2 set mtu";
03962       e->usage =
03963          "Usage: iax2 set mtu <value>\n"
03964          "       Set the system-wide IAX IP mtu to <value> bytes net or\n"
03965          "       zero to disable. Disabling means that the operating system\n"
03966          "       must handle fragmentation of UDP packets when the IAX2 trunk\n"
03967          "       packet exceeds the UDP payload size. This is substantially\n"
03968          "       below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03969          "       greater for G.711 samples.\n";
03970       return NULL;
03971    case CLI_GENERATE:
03972       return NULL;
03973    }
03974 
03975    if (a->argc != 4)
03976       return CLI_SHOWUSAGE; 
03977    if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03978       mtuv = MAX_TRUNK_MTU;
03979    else
03980       mtuv = atoi(a->argv[3]);
03981 
03982    if (mtuv == 0) {
03983       ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 
03984       global_max_trunk_mtu = 0; 
03985       return CLI_SUCCESS; 
03986    }
03987    if (mtuv < 172 || mtuv > 4000) {
03988       ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 
03989       return CLI_SHOWUSAGE; 
03990    }
03991    ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 
03992    global_max_trunk_mtu = mtuv; 
03993    return CLI_SUCCESS;
03994 }

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

Definition at line 3996 of file chan_iax2.c.

References ARRAY_LEN, ast_cli(), ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_tvnow(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, CACHE_FLAG_TRANSMITTED, CACHE_FLAG_UNKNOWN, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, iax2_dpcache::expiry, iax2_dpcache::exten, ast_cli_args::fd, iax2_dpcache::flags, iax2_dpcache::peercontext, ast_cli_entry::usage, and iax2_dpcache::waiters.

03997 {
03998    struct iax2_dpcache *dp = NULL;
03999    char tmp[1024], *pc = NULL;
04000    int s, x, y;
04001    struct timeval now = ast_tvnow();
04002 
04003    switch (cmd) {
04004    case CLI_INIT:
04005       e->command = "iax2 show cache";
04006       e->usage =
04007          "Usage: iax2 show cache\n"
04008          "       Display currently cached IAX Dialplan results.\n";
04009       return NULL;
04010    case CLI_GENERATE:
04011       return NULL;
04012    }
04013 
04014    AST_LIST_LOCK(&dpcache);
04015 
04016    ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
04017 
04018    AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
04019       s = dp->expiry.tv_sec - now.tv_sec;
04020       tmp[0] = '\0';
04021       if (dp->flags & CACHE_FLAG_EXISTS)
04022          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
04023       if (dp->flags & CACHE_FLAG_NONEXISTENT)
04024          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
04025       if (dp->flags & CACHE_FLAG_CANEXIST)
04026          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
04027       if (dp->flags & CACHE_FLAG_PENDING)
04028          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
04029       if (dp->flags & CACHE_FLAG_TIMEOUT)
04030          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
04031       if (dp->flags & CACHE_FLAG_TRANSMITTED)
04032          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
04033       if (dp->flags & CACHE_FLAG_MATCHMORE)
04034          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
04035       if (dp->flags & CACHE_FLAG_UNKNOWN)
04036          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
04037       /* Trim trailing pipe */
04038       if (!ast_strlen_zero(tmp)) {
04039          tmp[strlen(tmp) - 1] = '\0';
04040       } else {
04041          ast_copy_string(tmp, "(none)", sizeof(tmp));
04042       }
04043       y = 0;
04044       pc = strchr(dp->peercontext, '@');
04045       if (!pc) {
04046          pc = dp->peercontext;
04047       } else {
04048          pc++;
04049       }
04050       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
04051          if (dp->waiters[x] > -1)
04052             y++;
04053       }
04054       if (s > 0) {
04055          ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
04056       } else {
04057          ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
04058       }
04059    }
04060 
04061    AST_LIST_UNLOCK(&dpcache);
04062 
04063    return CLI_SUCCESS;
04064 }

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

Definition at line 2613 of file chan_iax2.c.

References peercnt::addr, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_inet_ntoa(), CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, peercnt::cur, ast_cli_args::fd, peercnt::limit, and ast_cli_entry::usage.

02614 {
02615    struct ao2_iterator i;
02616    struct peercnt *peercnt;
02617    struct sockaddr_in sin;
02618    int found = 0;
02619 
02620    switch (cmd) {
02621    case CLI_INIT:
02622       e->command = "iax2 show callnumber usage";
02623       e->usage =
02624          "Usage: iax2 show callnumber usage [IP address]\n"
02625          "       Shows current IP addresses which are consuming iax2 call numbers\n";
02626       return NULL;
02627    case CLI_GENERATE:
02628       return NULL;
02629    case CLI_HANDLER:
02630       if (a->argc < 4 || a->argc > 5)
02631          return CLI_SHOWUSAGE;
02632 
02633       ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02634       i = ao2_iterator_init(peercnts, 0);
02635       while ((peercnt = ao2_iterator_next(&i))) {
02636          sin.sin_addr.s_addr = peercnt->addr;
02637          if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02638                ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02639                ao2_ref(peercnt, -1);
02640                found = 1;
02641                break;
02642          } else {
02643             ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02644          }
02645          ao2_ref(peercnt, -1);
02646       }
02647       ao2_iterator_destroy(&i);
02648 
02649       if (a->argc == 4) {
02650          ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
02651                           "Non-CallToken Validated Callno Used:   %d\n",
02652             global_maxcallno_nonval,
02653             total_nonval_callno_used);
02654 
02655          ast_cli(a->fd,   "Total Available Callno:                %d\n"
02656                           "Regular Callno Available:              %d\n"
02657                           "Trunk Callno Available:                %d\n",
02658             ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk),
02659             ao2_container_count(callno_pool),
02660             ao2_container_count(callno_pool_trunk));
02661       } else if (a->argc == 5 && !found) {
02662          ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02663       }
02664 
02665 
02666       return CLI_SUCCESS;
02667    default:
02668       return NULL;
02669    }
02670 }

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

Definition at line 7235 of file chan_iax2.c.

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

07236 {
07237 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s  %s  %9s\n"
07238 #define FORMAT  "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-4.4dms  %-6.6s  %s%s  %3s%s\n"
07239 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
07240    int x;
07241    int numchans = 0;
07242    char first_message[10] = { 0, };
07243    char last_message[10] = { 0, };
07244 
07245    switch (cmd) {
07246    case CLI_INIT:
07247       e->command = "iax2 show channels";
07248       e->usage =
07249          "Usage: iax2 show channels\n"
07250          "       Lists all currently active IAX channels.\n";
07251       return NULL;
07252    case CLI_GENERATE:
07253       return NULL;
07254    }
07255 
07256    if (a->argc != 3)
07257       return CLI_SHOWUSAGE;
07258    ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07259    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07260       ast_mutex_lock(&iaxsl[x]);
07261       if (iaxs[x]) {
07262          int lag, jitter, localdelay;
07263          jb_info jbinfo;
07264          if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07265             jb_getinfo(iaxs[x]->jb, &jbinfo);
07266             jitter = jbinfo.jitter;
07267             localdelay = jbinfo.current - jbinfo.min;
07268          } else {
07269             jitter = -1;
07270             localdelay = 0;
07271          }
07272 
07273          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07274          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07275          lag = iaxs[x]->remote_rr.delay;
07276          ast_cli(a->fd, FORMAT,
07277             iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
07278             ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07279             S_OR(iaxs[x]->username, "(None)"),
07280             iaxs[x]->callno, iaxs[x]->peercallno,
07281             iaxs[x]->oseqno, iaxs[x]->iseqno,
07282             lag,
07283             jitter,
07284             localdelay,
07285             iax2_getformatname(iaxs[x]->voiceformat),
07286             (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07287             first_message,
07288             (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07289             last_message);
07290          numchans++;
07291       }
07292       ast_mutex_unlock(&iaxsl[x]);
07293    }
07294    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07295    return CLI_SUCCESS;
07296 #undef FORMAT
07297 #undef FORMAT2
07298 #undef FORMATB
07299 }

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

Definition at line 7021 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, ast_cli_args::fd, iax_firmware::fwh, ast_cli_entry::usage, and ast_iax2_firmware_header::version.

07022 {
07023    struct iax_firmware *cur = NULL;
07024 
07025    switch (cmd) {
07026    case CLI_INIT:
07027       e->command = "iax2 show firmware";
07028       e->usage =
07029          "Usage: iax2 show firmware\n"
07030          "       Lists all known IAX firmware images.\n";
07031       return NULL;
07032    case CLI_GENERATE:
07033       return NULL;
07034    }
07035 
07036    if (a->argc != 3 && a->argc != 4)
07037       return CLI_SHOWUSAGE;
07038 
07039    ast_cli(a->fd, "%-15.15s  %-15.15s %-15.15s\n", "Device", "Version", "Size");
07040    AST_LIST_LOCK(&firmwares);
07041    AST_LIST_TRAVERSE(&firmwares, cur, list) {
07042       if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname)))  {
07043          ast_cli(a->fd, "%-15.15s  %-15d %-15d\n", cur->fwh->devname, 
07044             ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
07045       }
07046    }
07047    AST_LIST_UNLOCK(&firmwares);
07048 
07049    return CLI_SUCCESS;
07050 }

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

Definition at line 7385 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli(), ast_cli_netstats(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

07386 {
07387    int numchans = 0;
07388 
07389    switch (cmd) {
07390    case CLI_INIT:
07391       e->command = "iax2 show netstats";
07392       e->usage =
07393          "Usage: iax2 show netstats\n"
07394          "       Lists network status for all currently active IAX channels.\n";
07395       return NULL;
07396    case CLI_GENERATE:
07397       return NULL;
07398    }
07399    if (a->argc != 3)
07400       return CLI_SHOWUSAGE;
07401    ast_cli(a->fd, "                           -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
07402    ast_cli(a->fd, "Channel               RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts FirstMsg    LastMsg\n");
07403    numchans = ast_cli_netstats(NULL, a->fd, 1);
07404    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07405    return CLI_SUCCESS;
07406 }

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

Show one peer in detail.

Definition at line 3802 of file chan_iax2.c.

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

03803 {
03804    char status[30];
03805    char cbuf[256];
03806    struct iax2_peer *peer;
03807    char codec_buf[512];
03808    struct ast_str *encmethods = ast_str_alloca(256);
03809    int x = 0, load_realtime = 0;
03810 
03811    switch (cmd) {
03812    case CLI_INIT:
03813       e->command = "iax2 show peer";
03814       e->usage =
03815          "Usage: iax2 show peer <name>\n"
03816          "       Display details on specific IAX peer\n";
03817       return NULL;
03818    case CLI_GENERATE:
03819       if (a->pos == 3)
03820          return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03821       return NULL;
03822    }
03823 
03824    if (a->argc < 4)
03825       return CLI_SHOWUSAGE;
03826 
03827    load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03828 
03829    peer = find_peer(a->argv[3], load_realtime);
03830    if (peer) {
03831       struct sockaddr_in peer_addr;
03832 
03833       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
03834 
03835       encmethods_to_str(peer->encmethods, encmethods);
03836       ast_cli(a->fd, "\n\n");
03837       ast_cli(a->fd, "  * Name       : %s\n", peer->name);
03838       ast_cli(a->fd, "  Description  : %s\n", peer->description);
03839       ast_cli(a->fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03840       ast_cli(a->fd, "  Context      : %s\n", peer->context);
03841       ast_cli(a->fd, "  Parking lot  : %s\n", peer->parkinglot);
03842       ast_cli(a->fd, "  Mailbox      : %s\n", peer->mailbox);
03843       ast_cli(a->fd, "  Dynamic      : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
03844       ast_cli(a->fd, "  Callnum limit: %d\n", peer->maxcallno);
03845       ast_cli(a->fd, "  Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03846       ast_cli(a->fd, "  Trunk        : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
03847       ast_cli(a->fd, "  Encryption   : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03848       ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03849       ast_cli(a->fd, "  Expire       : %d\n", peer->expire);
03850       ast_cli(a->fd, "  ACL          : %s\n", (peer->ha ? "Yes" : "No"));
03851       ast_cli(a->fd, "  Addr->IP     : %s Port %d\n",  peer_addr.sin_addr.s_addr ? ast_inet_ntoa(peer_addr.sin_addr) : "(Unspecified)", ntohs(peer_addr.sin_port));
03852       ast_cli(a->fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03853       ast_cli(a->fd, "  Username     : %s\n", peer->username);
03854       ast_cli(a->fd, "  Codecs       : ");
03855       iax2_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03856       ast_cli(a->fd, "%s\n", codec_buf);
03857 
03858       ast_cli(a->fd, "  Codec Order  : (");
03859       for(x = 0; x < AST_CODEC_PREF_SIZE; x++) {
03860          struct ast_format tmpfmt;
03861          if(!(ast_codec_pref_index(&peer->prefs, x, &tmpfmt)))
03862             break;
03863          ast_cli(a->fd, "%s", ast_getformatname(&tmpfmt));
03864          if(x < 31 && ast_codec_pref_index(&peer->prefs, x+1, &tmpfmt))
03865             ast_cli(a->fd, "|");
03866       }
03867 
03868       if (!x)
03869          ast_cli(a->fd, "none");
03870       ast_cli(a->fd, ")\n");
03871 
03872       ast_cli(a->fd, "  Status       : ");
03873       peer_status(peer, status, sizeof(status));   
03874       ast_cli(a->fd, "%s\n",status);
03875       ast_cli(a->fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
03876       ast_cli(a->fd, "\n");
03877       peer_unref(peer);
03878    } else {
03879       ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03880       ast_cli(a->fd, "\n");
03881    }
03882 
03883    return CLI_SUCCESS;
03884 }

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

Definition at line 6989 of file chan_iax2.c.

References __iax2_show_peers(), ast_cli_args::argc, ast_cli_args::argv, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, RESULT_FAILURE, RESULT_SHOWUSAGE, and ast_cli_entry::usage.

06990 {
06991    switch (cmd) {
06992    case CLI_INIT:
06993       e->command = "iax2 show peers";
06994       e->usage =
06995          "Usage: iax2 show peers [registered] [like <pattern>]\n"
06996          "       Lists all known IAX2 peers.\n"
06997          "       Optional 'registered' argument lists only peers with known addresses.\n"
06998          "       Optional regular expression pattern is used to filter the peer list.\n";
06999       return NULL;
07000    case CLI_GENERATE:
07001       return NULL;
07002    }
07003 
07004    switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
07005    case RESULT_SHOWUSAGE:
07006       return CLI_SHOWUSAGE;
07007    case RESULT_FAILURE:
07008       return CLI_FAILURE;
07009    default:
07010       return CLI_SUCCESS;
07011    }
07012 }

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

Definition at line 7144 of file chan_iax2.c.

References iax2_registry::addr, ast_cli_args::argc, ast_cli(), ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_registry::dnsmgr, ast_cli_args::fd, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), iax2_registry::us, ast_cli_entry::usage, and iax2_registry::username.

07145 {
07146 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
07147 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
07148    struct iax2_registry *reg = NULL;
07149    char host[80];
07150    char perceived[80];
07151    int counter = 0;
07152 
07153    switch (cmd) {
07154    case CLI_INIT:
07155       e->command = "iax2 show registry";
07156       e->usage =
07157          "Usage: iax2 show registry\n"
07158          "       Lists all registration requests and status.\n";
07159       return NULL;
07160    case CLI_GENERATE:
07161       return NULL;
07162    }
07163    if (a->argc != 3)
07164       return CLI_SHOWUSAGE;
07165    ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07166    AST_LIST_LOCK(&registrations);
07167    AST_LIST_TRAVERSE(&registrations, reg, entry) {
07168       snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
07169       if (reg->us.sin_addr.s_addr) 
07170          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07171       else
07172          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07173       ast_cli(a->fd, FORMAT, host, 
07174                (reg->dnsmgr) ? "Y" : "N", 
07175                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07176       counter++;
07177    }
07178    AST_LIST_UNLOCK(&registrations);
07179    ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07180    return CLI_SUCCESS;
07181 #undef FORMAT
07182 #undef FORMAT2
07183 }

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

Definition at line 3909 of file chan_iax2.c.

References ast_cli_args::argc, ARRAY_LEN, ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, iax_frame::final, frame_queue, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iax_frame::retries, and ast_cli_entry::usage.

03910 {
03911    struct iax_frame *cur;
03912    int cnt = 0, dead = 0, final = 0, i = 0;
03913 
03914    switch (cmd) {
03915    case CLI_INIT:
03916       e->command = "iax2 show stats";
03917       e->usage =
03918          "Usage: iax2 show stats\n"
03919          "       Display statistics on IAX channel driver.\n";
03920       return NULL;
03921    case CLI_GENERATE:
03922       return NULL;
03923    }
03924 
03925    if (a->argc != 3)
03926       return CLI_SHOWUSAGE;
03927 
03928    for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
03929       ast_mutex_lock(&iaxsl[i]);
03930       AST_LIST_TRAVERSE(&frame_queue[i], cur, list) {
03931          if (cur->retries < 0)
03932             dead++;
03933          if (cur->final)
03934             final++;
03935          cnt++;
03936       }
03937       ast_mutex_unlock(&iaxsl[i]);
03938    }
03939 
03940    ast_cli(a->fd, "    IAX Statistics\n");
03941    ast_cli(a->fd, "---------------------\n");
03942    ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03943    ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03944       trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03945    ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03946 
03947    trunk_timed = trunk_untimed = 0;
03948    if (trunk_maxmtu > trunk_nmaxmtu)
03949       trunk_nmaxmtu = trunk_maxmtu;
03950 
03951    return CLI_SUCCESS;
03952 }

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

Definition at line 6855 of file chan_iax2.c.

References iax2_thread::actions, ast_cli_args::argc, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_thread::checktime, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_thread::curfunc, ast_cli_args::fd, IAX_THREAD_TYPE_DYNAMIC, iaxthreadcount, iax2_thread::iostate, thread, iax2_thread::threadnum, iax2_thread::type, and ast_cli_entry::usage.

06856 {
06857    struct iax2_thread *thread = NULL;
06858    time_t t;
06859    int threadcount = 0, dynamiccount = 0;
06860    char type;
06861 
06862    switch (cmd) {
06863    case CLI_INIT:
06864       e->command = "iax2 show threads";
06865       e->usage =
06866          "Usage: iax2 show threads\n"
06867          "       Lists status of IAX helper threads\n";
06868       return NULL;
06869    case CLI_GENERATE:
06870       return NULL;
06871    }
06872    if (a->argc != 3)
06873       return CLI_SHOWUSAGE;
06874       
06875    ast_cli(a->fd, "IAX2 Thread Information\n");
06876    time(&t);
06877    ast_cli(a->fd, "Idle Threads:\n");
06878    AST_LIST_LOCK(&idle_list);
06879    AST_LIST_TRAVERSE(&idle_list, thread, list) {
06880 #ifdef DEBUG_SCHED_MULTITHREAD
06881       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 
06882          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06883 #else
06884       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
06885          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06886 #endif
06887       threadcount++;
06888    }
06889    AST_LIST_UNLOCK(&idle_list);
06890    ast_cli(a->fd, "Active Threads:\n");
06891    AST_LIST_LOCK(&active_list);
06892    AST_LIST_TRAVERSE(&active_list, thread, list) {
06893       if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06894          type = 'D';
06895       else
06896          type = 'P';
06897 #ifdef DEBUG_SCHED_MULTITHREAD
06898       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 
06899          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06900 #else
06901       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
06902          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06903 #endif
06904       threadcount++;
06905    }
06906    AST_LIST_UNLOCK(&active_list);
06907    ast_cli(a->fd, "Dynamic Threads:\n");
06908    AST_LIST_LOCK(&dynamic_list);
06909    AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06910 #ifdef DEBUG_SCHED_MULTITHREAD
06911       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06912          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06913 #else
06914       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06915          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06916 #endif
06917       dynamiccount++;
06918    }
06919    AST_LIST_UNLOCK(&dynamic_list);
06920    ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06921    return CLI_SUCCESS;
06922 }

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

Definition at line 6643 of file chan_iax2.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_strlen_zero(), ast_test_flag64, iax2_user::authmethods, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_context::context, iax2_user::contexts, DEFAULT_CONTEXT, ast_cli_args::fd, FORMAT, FORMAT2, iax2_user::ha, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, iax2_user::inkeys, iax2_user::name, iax2_user::secret, ast_cli_entry::usage, and user_unref().

06644 {
06645    regex_t regexbuf;
06646    int havepattern = 0;
06647 
06648 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
06649 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
06650 
06651    struct iax2_user *user = NULL;
06652    char auth[90];
06653    char *pstr = "";
06654    struct ao2_iterator i;
06655 
06656    switch (cmd) {
06657    case CLI_INIT:
06658       e->command = "iax2 show users [like]";
06659       e->usage =
06660          "Usage: iax2 show users [like <pattern>]\n"
06661          "       Lists all known IAX2 users.\n"
06662          "       Optional regular expression pattern is used to filter the user list.\n";
06663       return NULL;
06664    case CLI_GENERATE:
06665       return NULL;
06666    }
06667 
06668    switch (a->argc) {
06669    case 5:
06670       if (!strcasecmp(a->argv[3], "like")) {
06671          if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06672             return CLI_SHOWUSAGE;
06673          havepattern = 1;
06674       } else
06675          return CLI_SHOWUSAGE;
06676    case 3:
06677       break;
06678    default:
06679       return CLI_SHOWUSAGE;
06680    }
06681 
06682    ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06683    i = ao2_iterator_init(users, 0);
06684    for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
06685       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
06686          continue;
06687 
06688       if (!ast_strlen_zero(user->secret)) {
06689          ast_copy_string(auth,user->secret, sizeof(auth));
06690       } else if (!ast_strlen_zero(user->inkeys)) {
06691          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06692       } else
06693          ast_copy_string(auth, "-no secret-", sizeof(auth));
06694 
06695       if(ast_test_flag64(user, IAX_CODEC_NOCAP))
06696          pstr = "REQ Only";
06697       else if(ast_test_flag64(user, IAX_CODEC_NOPREFS))
06698          pstr = "Disabled";
06699       else
06700          pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06701 
06702       ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 
06703          user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06704          user->ha ? "Yes" : "No", pstr);
06705    }
06706    ao2_iterator_destroy(&i);
06707 
06708    if (havepattern)
06709       regfree(&regexbuf);
06710 
06711    return CLI_SUCCESS;
06712 #undef FORMAT
06713 #undef FORMAT2
06714 }

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

Definition at line 3688 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.

03689 {
03690    switch (cmd) {
03691    case CLI_INIT:
03692       e->command = "iax2 test losspct";
03693       e->usage =
03694          "Usage: iax2 test losspct <percentage>\n"
03695          "       For testing, throws away <percentage> percent of incoming packets\n";
03696       return NULL;
03697    case CLI_GENERATE:
03698       return NULL;
03699    }
03700    if (a->argc != 4)
03701       return CLI_SHOWUSAGE;
03702 
03703    test_losspct = atoi(a->argv[3]);
03704 
03705    return CLI_SUCCESS;
03706 }

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

Definition at line 6924 of file chan_iax2.c.

References ao2_find, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_unregister(), iax2_peer::expire, expire_registry(), ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, OBJ_KEY, peer_ref(), peer_unref(), ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

06925 {
06926    struct iax2_peer *p;
06927 
06928    switch (cmd) {
06929    case CLI_INIT:
06930       e->command = "iax2 unregister";
06931       e->usage =
06932          "Usage: iax2 unregister <peername>\n"
06933          "       Unregister (force expiration) an IAX2 peer from the registry.\n";
06934       return NULL;
06935    case CLI_GENERATE:
06936       return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06937    }
06938 
06939    if (a->argc != 3)
06940       return CLI_SHOWUSAGE;
06941 
06942    p = find_peer(a->argv[2], 1);
06943    if (p) {
06944       if (p->expire > 0) {
06945          struct iax2_peer *peer;
06946 
06947          peer = ao2_find(peers, a->argv[2], OBJ_KEY);
06948          if (peer) {
06949             expire_registry(peer_ref(peer)); /* will release its own reference when done */
06950             peer_unref(peer); /* ref from ao2_find() */
06951             ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06952          } else {
06953             ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06954          }
06955       } else {
06956          ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06957       }
06958    } else {
06959       ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06960    }
06961    return CLI_SUCCESS;
06962 }

static void handle_deferred_full_frames ( struct iax2_thread thread  )  [static]

Handle any deferred full frames for this thread.

Definition at line 9606 of file chan_iax2.c.

References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock, ast_mutex_unlock, iax2_pkt_buf::buf, iax2_thread::buf, iax2_thread::buf_len, iax2_thread::buf_size, iax2_thread::full_frames, iax2_pkt_buf::len, iax2_thread::lock, and socket_process().

Referenced by iax2_process_thread().

09607 {
09608    struct iax2_pkt_buf *pkt_buf;
09609 
09610    ast_mutex_lock(&thread->lock);
09611 
09612    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09613       ast_mutex_unlock(&thread->lock);
09614 
09615       thread->buf = pkt_buf->buf;
09616       thread->buf_len = pkt_buf->len;
09617       thread->buf_size = pkt_buf->len + 1;
09618       
09619       socket_process(thread);
09620 
09621       thread->buf = NULL;
09622       ast_free(pkt_buf);
09623 
09624       ast_mutex_lock(&thread->lock);
09625    }
09626 
09627    ast_mutex_unlock(&thread->lock);
09628 }

static int handle_error ( void   )  [static]

Definition at line 3343 of file chan_iax2.c.

References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, and netsocket.

Referenced by send_packet(), socket_read(), and transmit_trunk().

03344 {
03345    /* XXX Ideally we should figure out why an error occurred and then abort those
03346       rather than continuing to try.  Unfortunately, the published interface does
03347       not seem to work XXX */
03348 #if 0
03349    struct sockaddr_in *sin;
03350    int res;
03351    struct msghdr m;
03352    struct sock_extended_err e;
03353    m.msg_name = NULL;
03354    m.msg_namelen = 0;
03355    m.msg_iov = NULL;
03356    m.msg_control = &e;
03357    m.msg_controllen = sizeof(e);
03358    m.msg_flags = 0;
03359    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03360    if (res < 0)
03361       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03362    else {
03363       if (m.msg_controllen) {
03364          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03365          if (sin) 
03366             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03367          else
03368             ast_log(LOG_WARNING, "No address detected??\n");
03369       } else {
03370          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03371       }
03372    }
03373 #endif
03374    return 0;
03375 }

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

Acknowledgment received for OUR registration.

Definition at line 8503 of file chan_iax2.c.

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

Referenced by socket_process().

08504 {
08505    struct iax2_registry *reg;
08506    /* Start pessimistic */
08507    char peer[256] = "";
08508    char msgstatus[60];
08509    int refresh = 60;
08510    char ourip[256] = "<Unspecified>";
08511    struct sockaddr_in oldus;
08512    struct sockaddr_in us;
08513    int oldmsgs;
08514    struct sockaddr_in reg_addr;
08515 
08516    memset(&us, 0, sizeof(us));
08517    if (ies->apparent_addr) {
08518       memmove(&us, ies->apparent_addr, sizeof(us));
08519    }
08520    if (ies->username) {
08521       ast_copy_string(peer, ies->username, sizeof(peer));
08522    }
08523    if (ies->refresh) {
08524       refresh = ies->refresh;
08525    }
08526    if (ies->calling_number) {
08527       /* We don't do anything with it really, but maybe we should */
08528    }
08529    reg = iaxs[callno]->reg;
08530    if (!reg) {
08531       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08532       return -1;
08533    }
08534    memcpy(&oldus, &reg->us, sizeof(oldus));
08535    oldmsgs = reg->messages;
08536    ast_sockaddr_to_sin(&reg->addr, &reg_addr);
08537    if (inaddrcmp(&reg_addr, sin)) {
08538       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08539       return -1;
08540    }
08541    memcpy(&reg->us, &us, sizeof(reg->us));
08542    if (ies->msgcount >= 0) {
08543       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
08544    }
08545    /* always refresh the registration at the interval requested by the server
08546       we are registering to
08547    */
08548    reg->refresh = refresh;
08549    reg->expire = iax2_sched_replace(reg->expire, sched,
08550       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08551    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
08552       if (reg->messages > 255) {
08553          snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08554       } else if (reg->messages > 1) {
08555          snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
08556       } else if (reg->messages > 0) {
08557          ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
08558       } else {
08559          ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
08560       }
08561       snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08562       ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08563       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08564    }
08565    reg->regstate = REG_STATE_REGISTERED;
08566    return 0;
08567 }

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

Definition at line 2808 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_FWDOWNL, IAX_COMMAND_NEW, IAX_COMMAND_POKE, IAX_COMMAND_REGREL, and IAX_COMMAND_REGREQ.

Referenced by resend_with_token(), and socket_process().

02809 {
02810    if (frametype != AST_FRAME_IAX) {
02811       return 0;
02812    }
02813    switch (subclass) {
02814    case IAX_COMMAND_NEW:
02815    case IAX_COMMAND_REGREQ:
02816    case IAX_COMMAND_FWDOWNL:
02817    case IAX_COMMAND_REGREL:
02818       return 1;
02819    case IAX_COMMAND_POKE:
02820       if (!inbound) {
02821          return 1;
02822       }
02823       break;
02824    }
02825    return 0;
02826 }

static void iax2_ami_channelupdate ( struct chan_iax2_pvt pvt  )  [static]

Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers.

Definition at line 1322 of file chan_iax2.c.

References ast_channel_name(), chan_iax2_pvt::callno, EVENT_FLAG_SYSTEM, manager_event, chan_iax2_pvt::owner, chan_iax2_pvt::peer, and chan_iax2_pvt::peercallno.

Referenced by ast_iax2_new(), and iax2_answer().

01323 {
01324    manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01325       "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01326       pvt->owner ? ast_channel_name(pvt->owner) : "",
01327       pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01328 }

static int iax2_answer ( struct ast_channel c  )  [static]

Definition at line 5686 of file chan_iax2.c.

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

05687 {
05688    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05689    ast_debug(1, "Answering IAX2 call\n");
05690    ast_mutex_lock(&iaxsl[callno]);
05691    if (iaxs[callno])
05692       iax2_ami_channelupdate(iaxs[callno]);
05693    ast_mutex_unlock(&iaxsl[callno]);
05694    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05695 }

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

Definition at line 8569 of file chan_iax2.c.

References iax2_registry::addr, ast_calloc, ast_copy_string(), ast_dnsmgr_lookup(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_sockaddr_set_port, iax2_registry::dnsmgr, iax2_registry::expire, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, iax2_registry::refresh, iax2_registry::secret, ast_sockaddr::ss, and iax2_registry::username.

Referenced by iax2_register().

08571 {
08572    struct iax2_registry *reg;
08573 
08574    if (!(reg = ast_calloc(1, sizeof(*reg))))
08575       return -1;
08576 
08577    reg->addr.ss.ss_family = AF_INET;
08578    if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08579       ast_free(reg);
08580       return -1;
08581    }
08582 
08583    ast_copy_string(reg->username, username, sizeof(reg->username));
08584 
08585    if (secret)
08586       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08587 
08588    reg->expire = -1;
08589    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08590    ast_sockaddr_set_port(&reg->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08591 
08592    AST_LIST_LOCK(&registrations);
08593    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
08594    AST_LIST_UNLOCK(&registrations);
08595    
08596    return 0;
08597 }

static iax2_format iax2_best_codec ( iax2_format  formats  )  [static]

Definition at line 1655 of file chan_iax2.c.

References ast_best_codec(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_cap_from_old_bitfield(), ast_format_clear(), and ast_format_to_old_bitfield().

Referenced by socket_process().

01656 {
01657    struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
01658    struct ast_format tmpfmt;
01659    if (!cap) {
01660       return 0;
01661    }
01662 
01663    ast_format_clear(&tmpfmt);
01664    ast_format_cap_from_old_bitfield(cap, formats);
01665    ast_best_codec(cap, &tmpfmt);
01666    cap = ast_format_cap_destroy(cap);
01667    return ast_format_to_old_bitfield(&tmpfmt);
01668 }

static enum ast_bridge_result iax2_bridge ( struct ast_channel c0,
struct ast_channel c1,
int  flags,
struct ast_frame **  fo,
struct ast_channel **  rc,
int  timeoutms 
) [static]

Definition at line 5531 of file chan_iax2.c.

References ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_check_hangup(), AST_CONTROL_SRCUPDATE, ast_format_cap_identical(), AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_read(), AST_SOFTHANGUP_DEV, ast_test_flag64, ast_tvnow(), ast_tvzero(), ast_verb, ast_waitfor_n(), ast_write(), chan_iax2_pvt::bridgecallno, buf1, f, ast_frame::frametype, iax2_start_transfer(), IAX_LINGER_TIMEOUT, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, ast_frame_subclass::integer, lock_both(), LOG_WARNING, ast_channel::nativeformats, PTR_TO_CALLNO, ast_frame::subclass, ast_channel::tech, ast_channel::tech_pvt, TRANSFER_RELEASED, and unlock_both().

05532 {
05533    struct ast_channel *cs[3];
05534    struct ast_channel *who, *other;
05535    int to = -1;
05536    int res = -1;
05537    int transferstarted=0;
05538    struct ast_frame *f;
05539    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05540    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05541    struct timeval waittimer = {0, 0};
05542 
05543    /* We currently do not support native bridging if a timeoutms value has been provided */
05544    if (timeoutms > 0) {
05545       return AST_BRIDGE_FAILED;
05546    }
05547 
05548    timeoutms = -1;
05549 
05550    lock_both(callno0, callno1);
05551    if (!iaxs[callno0] || !iaxs[callno1]) {
05552       unlock_both(callno0, callno1);
05553       return AST_BRIDGE_FAILED;
05554    }
05555    /* Put them in native bridge mode */
05556    if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05557       iaxs[callno0]->bridgecallno = callno1;
05558       iaxs[callno1]->bridgecallno = callno0;
05559    }
05560    unlock_both(callno0, callno1);
05561 
05562    /* If not, try to bridge until we can execute a transfer, if we can */
05563    cs[0] = c0;
05564    cs[1] = c1;
05565    for (/* ever */;;) {
05566       /* Check in case we got masqueraded into */
05567       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05568          ast_verb(3, "Can't masquerade, we're different...\n");
05569          /* Remove from native mode */
05570          if (c0->tech == &iax2_tech) {
05571             ast_mutex_lock(&iaxsl[callno0]);
05572             iaxs[callno0]->bridgecallno = 0;
05573             ast_mutex_unlock(&iaxsl[callno0]);
05574          }
05575          if (c1->tech == &iax2_tech) {
05576             ast_mutex_lock(&iaxsl[callno1]);
05577             iaxs[callno1]->bridgecallno = 0;
05578             ast_mutex_unlock(&iaxsl[callno1]);
05579          }
05580          return AST_BRIDGE_FAILED_NOWARN;
05581       }
05582       if (!(ast_format_cap_identical(c0->nativeformats, c1->nativeformats))) {
05583          char buf0[256];
05584          char buf1[256];
05585          ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05586          ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05587          ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05588          /* Remove from native mode */
05589          lock_both(callno0, callno1);
05590          if (iaxs[callno0])
05591             iaxs[callno0]->bridgecallno = 0;
05592          if (iaxs[callno1])
05593             iaxs[callno1]->bridgecallno = 0;
05594          unlock_both(callno0, callno1);
05595          return AST_BRIDGE_FAILED_NOWARN;
05596       }
05597       /* check if transfered and if we really want native bridging */
05598       if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05599          /* Try the transfer */
05600          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05601                      ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05602             ast_log(LOG_WARNING, "Unable to start the transfer\n");
05603          transferstarted = 1;
05604       }
05605       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05606          /* Call has been transferred.  We're no longer involved */
05607          struct timeval now = ast_tvnow();
05608          if (ast_tvzero(waittimer)) {
05609             waittimer = now;
05610          } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05611             c0->_softhangup |= AST_SOFTHANGUP_DEV;
05612             c1->_softhangup |= AST_SOFTHANGUP_DEV;
05613             *fo = NULL;
05614             *rc = c0;
05615             res = AST_BRIDGE_COMPLETE;
05616             break;
05617          }
05618       }
05619       to = 1000;
05620       who = ast_waitfor_n(cs, 2, &to);
05621       if (timeoutms > -1) {
05622          timeoutms -= (1000 - to);
05623          if (timeoutms < 0)
05624             timeoutms = 0;
05625       }
05626       if (!who) {
05627          if (!timeoutms) {
05628             res = AST_BRIDGE_RETRY;
05629             break;
05630          }
05631          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05632             res = AST_BRIDGE_FAILED;
05633             break;
05634          }
05635          continue;
05636       }
05637       f = ast_read(who);
05638       if (!f) {
05639          *fo = NULL;
05640          *rc = who;
05641          res = AST_BRIDGE_COMPLETE;
05642          break;
05643       }
05644       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) {
05645          *fo = f;
05646          *rc = who;
05647          res =  AST_BRIDGE_COMPLETE;
05648          break;
05649       }
05650       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
05651       if ((f->frametype == AST_FRAME_VOICE) ||
05652          (f->frametype == AST_FRAME_TEXT) ||
05653          (f->frametype == AST_FRAME_VIDEO) || 
05654          (f->frametype == AST_FRAME_IMAGE) ||
05655          (f->frametype == AST_FRAME_DTMF) ||
05656          (f->frametype == AST_FRAME_CONTROL)) {
05657          /* monitored dtmf take out of the bridge.
05658           * check if we monitor the specific source.
05659           */
05660          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05661          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05662             *rc = who;
05663             *fo = f;
05664             res = AST_BRIDGE_COMPLETE;
05665             /* Remove from native mode */
05666             break;
05667          }
05668          /* everything else goes to the other side */
05669          ast_write(other, f);
05670       }
05671       ast_frfree(f);
05672       /* Swap who gets priority */
05673       cs[2] = cs[0];
05674       cs[0] = cs[1];
05675       cs[1] = cs[2];
05676    }
05677    lock_both(callno0, callno1);
05678    if(iaxs[callno0])
05679       iaxs[callno0]->bridgecallno = 0;
05680    if(iaxs[callno1])
05681       iaxs[callno1]->bridgecallno = 0;
05682    unlock_both(callno0, callno1);
05683    return res;
05684 }

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

Definition at line 5077 of file chan_iax2.c.

References ast_channel::_state, add_empty_calltoken_ie(), create_addr_info::adsi, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_party_connected_line::ani, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, ast_channel_datastore_find(), ast_channel_language(), ast_channel_name(), ast_copy_string(), ast_debug, ast_format_cap_to_old_bitfield(), AST_FRAME_IAX, AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_party_id_presentation(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_name(), ast_var_value(), auto_congest(), iax_ie_data::buf, CALLNO_TO_PTR, ast_channel::connected, context, create_addr_info::context, ast_channel::context, parsed_dial_string::context, create_addr(), ast_datastore::data, ast_channel::dialed, chan_iax2_pvt::encmethods, create_addr_info::encmethods, parsed_dial_string::exten, ast_party_redirecting::from, ast_channel::hangupcause, iax2_datetime(), iax2_sched_add(), IAX_COMMAND_NEW, IAX_FORCE_ENCRYPT, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_raw(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CAPABILITY2, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_LANGUAGE, IAX_IE_OSPTOKEN, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VARIABLE, IAX_IE_VERSION, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPTOKEN_SIZE, IAX_PROTO_VERSION, IAX_SENDANI, ast_party_connected_line::id, chan_iax2_pvt::initid, parsed_dial_string::key, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_party_id::name, ast_channel::nativeformats, ast_party_dialed::number, ast_party_id::number, parsed_dial_string::options, create_addr_info::outkey, parse_dial_string(), parsed_dial_string::password, pbx_builtin_getvar_helper(), parsed_dial_string::peer, create_addr_info::peercontext, chan_iax2_pvt::pingtime, ast_party_number::plan, parsed_dial_string::port, iax_ie_data::pos, create_addr_info::prefs, PTR_TO_CALLNO, ast_channel::redirecting, secret, create_addr_info::secret, send_command(), create_addr_info::sockfd, chan_iax2_pvt::sockfd, ast_party_dialed::str, ast_party_name::str, ast_party_number::str, ast_channel::tech_pvt, create_addr_info::timezone, ast_party_dialed::transit_network_select, create_addr_info::username, parsed_dial_string::username, ast_party_name::valid, ast_party_number::valid, and var.

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

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

part of the IAX2 dial plan switch interface

Definition at line 13854 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_CANEXIST, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.

13855 {
13856    int res = 0;
13857    struct iax2_dpcache *dp = NULL;
13858 #if 0
13859    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13860 #endif
13861    if ((priority != 1) && (priority != 2))
13862       return 0;
13863 
13864    AST_LIST_LOCK(&dpcache);
13865    if ((dp = find_cache(chan, data, context, exten, priority))) {
13866       if (dp->flags & CACHE_FLAG_CANEXIST)
13867          res = 1;
13868    } else {
13869       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13870    }
13871    AST_LIST_UNLOCK(&dpcache);
13872 
13873    return res;
13874 }

static iax2_format iax2_codec_choose ( struct ast_codec_pref pref,
iax2_format  formats,
int  find_best 
) [static]

Definition at line 1639 of file chan_iax2.c.

References ast_codec_choose(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_cap_from_old_bitfield(), ast_format_clear(), ast_format_to_old_bitfield(), and format.

Referenced by socket_process().

01640 {
01641    struct ast_format_cap *cap;
01642    struct ast_format tmpfmt;
01643    iax2_format format = 0;
01644    if ((cap = ast_format_cap_alloc_nolock())) {
01645       ast_format_clear(&tmpfmt);
01646       ast_format_cap_from_old_bitfield(cap, formats);
01647       ast_codec_choose(pref, cap, find_best, &tmpfmt);
01648       format = ast_format_to_old_bitfield(&tmpfmt);
01649       cap = ast_format_cap_destroy(cap);
01650    }
01651 
01652    return format;
01653 }

static int iax2_data_add_codecs ( struct ast_data root,
const char *  node_name,
iax2_format  formats 
) [static]

Definition at line 1710 of file chan_iax2.c.

References ast_data_add_codecs(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), and ast_format_cap_from_old_bitfield().

Referenced by peers_data_provider_get(), and users_data_provider_get().

01711 {
01712    int res;
01713    struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
01714    if (!cap) {
01715       return -1;
01716    }
01717    ast_format_cap_from_old_bitfield(cap, formats);
01718    res = ast_data_add_codecs(root, node_name, cap);
01719    cap = ast_format_cap_destroy(cap);
01720    return res;
01721 }

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

Definition at line 4750 of file chan_iax2.c.

References ast_localtime(), ast_strlen_zero(), ast_tvnow(), ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, and ast_tm::tm_year.

Referenced by iax2_call(), and update_registry().

04751 {
04752    struct timeval t = ast_tvnow();
04753    struct ast_tm tm;
04754    unsigned int tmp;
04755    ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04756    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
04757    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
04758    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
04759    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
04760    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
04761    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
04762    return tmp;
04763 }

static void iax2_destroy ( int  callno  )  [static]

Definition at line 3449 of file chan_iax2.c.

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

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

03450 {
03451    struct chan_iax2_pvt *pvt = NULL;
03452    struct ast_channel *owner = NULL;
03453 
03454 retry:
03455    if ((pvt = iaxs[callno])) {
03456 #if 0
03457       /* iax2_destroy_helper gets called from this function later on.  When
03458        * called twice, we get the (previously) familiar FRACK! errors in
03459        * devmode, from the scheduler.  An alternative to this approach is to
03460        * reset the scheduler entries to -1 when they're deleted in
03461        * iax2_destroy_helper().  That approach was previously decided to be
03462        * "wrong" because "the memory is going to be deallocated anyway.  Why
03463        * should we be resetting those values?" */
03464       iax2_destroy_helper(pvt);
03465 #endif
03466    }
03467 
03468    owner = pvt ? pvt->owner : NULL;
03469 
03470    if (owner) {
03471       if (ast_channel_trylock(owner)) {
03472          ast_debug(3, "Avoiding IAX destroy deadlock\n");
03473          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03474          goto retry;
03475       }
03476    }
03477 
03478    if (!owner) {
03479       iaxs[callno] = NULL;
03480    }
03481 
03482    if (pvt) {
03483       if (!owner) {
03484          pvt->owner = NULL;
03485       } else {
03486          /* If there's an owner, prod it to give up */
03487          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
03488           * because we already hold the owner channel lock. */
03489          ast_queue_hangup(owner);
03490       }
03491 
03492       if (pvt->peercallno) {
03493          remove_by_peercallno(pvt);
03494       }
03495 
03496       if (pvt->transfercallno) {
03497          remove_by_transfercallno(pvt);
03498       }
03499 
03500       if (!owner) {
03501          ao2_ref(pvt, -1);
03502          pvt = NULL;
03503       }
03504    }
03505 
03506    if (owner) {
03507       ast_channel_unlock(owner);
03508    }
03509 
03510    if (callno & 0x4000) {
03511       update_max_trunk();
03512    }
03513 }

static void iax2_destroy_helper ( struct chan_iax2_pvt pvt  )  [static]

Note:
Assumes the lock on the pvt is already held, when iax2_destroy_helper() is called.

Definition at line 1851 of file chan_iax2.c.

References ao2_find, ast_atomic_fetchadd_int(), ast_clear_flag64, AST_SCHED_DEL, AST_SCHED_DEL_SPINLOCK, ast_test_flag64, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::callno, iax2_user::curauthreq, DONT_RESCHEDULE, IAX_MAXAUTHREQ, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, OBJ_KEY, chan_iax2_pvt::pingid, user_unref(), and chan_iax2_pvt::username.

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

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

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

Part of the device state notification system ---.

Definition at line 14058 of file chan_iax2.c.

References iax2_peer::addr, ast_debug, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log(), ast_sockaddr_ipv4(), ast_strdupa, ast_strlen_zero(), iax2_peer::defaddr, find_peer(), iax2_peer::historicms, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, parse_dial_string(), parsed_dial_string::peer, and peer_unref().

14059 {
14060    struct parsed_dial_string pds;
14061    char *tmp = ast_strdupa(data);
14062    struct iax2_peer *p;
14063    int res = AST_DEVICE_INVALID;
14064 
14065    memset(&pds, 0, sizeof(pds));
14066    parse_dial_string(tmp, &pds);
14067 
14068    if (ast_strlen_zero(pds.peer)) {
14069       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
14070       return res;
14071    }
14072 
14073    ast_debug(3, "Checking device state for device %s\n", pds.peer);
14074 
14075    /* SLD: FIXME: second call to find_peer during registration */
14076    if (!(p = find_peer(pds.peer, 1)))
14077       return res;
14078 
14079    res = AST_DEVICE_UNAVAILABLE;
14080    ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
14081       pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
14082 
14083    if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
14084        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
14085       /* Peer is registered, or have default IP address
14086          and a valid registration */
14087       if (p->historicms == 0 || p->historicms <= p->maxms)
14088          /* let the core figure out whether it is in use or not */
14089          res = AST_DEVICE_UNKNOWN;
14090    }
14091 
14092    peer_unref(p);
14093 
14094    return res;
14095 }

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

Definition at line 4342 of file chan_iax2.c.

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

04343 {
04344    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04345 }

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

Definition at line 4347 of file chan_iax2.c.

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

04348 {
04349    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04350 }

static int iax2_do_register ( struct iax2_registry reg  )  [static]

Definition at line 11866 of file chan_iax2.c.

References add_empty_calltoken_ie(), iax2_registry::addr, ast_debug, ast_dnsmgr_changed(), ast_dnsmgr_refresh(), AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_ipv4(), ast_sockaddr_to_sin, iax_ie_data::buf, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno_locked(), iax2_destroy(), iax2_do_register_s(), iax2_sched_replace(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, LOG_WARNING, NEW_FORCE, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, send_command(), and iax2_registry::username.

Referenced by __iax2_do_register_s(), load_module(), network_change_event_sched_cb(), and reload_config().

11867 {
11868    struct iax_ie_data ied;
11869    if (iaxdebug)
11870       ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11871 
11872    if (reg->dnsmgr &&
11873        ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(&reg->addr))) {
11874       /* Maybe the IP has changed, force DNS refresh */
11875       ast_dnsmgr_refresh(reg->dnsmgr);
11876    }
11877 
11878    /*
11879     * if IP has Changed, free allocated call to create a new one with new IP
11880     * call has the pointer to IP and must be updated to the new one
11881     */
11882    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11883       int callno = reg->callno;
11884       ast_mutex_lock(&iaxsl[callno]);
11885       iax2_destroy(callno);
11886       ast_mutex_unlock(&iaxsl[callno]);
11887       reg->callno = 0;
11888    }
11889    if (!ast_sockaddr_ipv4(&reg->addr)) {
11890       if (iaxdebug)
11891          ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11892       /* Setup the next registration attempt */
11893       reg->expire = iax2_sched_replace(reg->expire, sched,
11894          (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11895       return -1;
11896    }
11897 
11898    if (!reg->callno) {
11899       struct sockaddr_in reg_addr;
11900 
11901       ast_debug(3, "Allocate call number\n");
11902 
11903       ast_sockaddr_to_sin(&reg->addr, &reg_addr);
11904 
11905       reg->callno = find_callno_locked(0, 0, &reg_addr, NEW_FORCE, defaultsockfd, 0);
11906       if (reg->callno < 1) {
11907          ast_log(LOG_WARNING, "Unable to create call for registration\n");
11908          return -1;
11909       } else
11910          ast_debug(3, "Registration created on call %d\n", reg->callno);
11911       iaxs[reg->callno]->reg = reg;
11912       ast_mutex_unlock(&iaxsl[reg->callno]);
11913    }
11914    /* Setup the next registration a little early */
11915    reg->expire = iax2_sched_replace(reg->expire, sched,
11916       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11917    /* Send the request */
11918    memset(&ied, 0, sizeof(ied));
11919    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11920    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11921    add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */
11922    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11923    reg->regstate = REG_STATE_REGSENT;
11924    return 0;
11925 }

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

Definition at line 8350 of file chan_iax2.c.

References __iax2_do_register_s(), and schedule_action.

Referenced by iax2_ack_registry(), and iax2_do_register().

08351 {
08352 #ifdef SCHED_MULTITHREADED
08353    if (schedule_action(__iax2_do_register_s, data))
08354 #endif      
08355       __iax2_do_register_s(data);
08356    return 0;
08357 }

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

Definition at line 9125 of file chan_iax2.c.

References AST_FRAME_IAX, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_replace(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iax_ie_data::pos, and send_command().

Referenced by find_cache(), and socket_process().

09126 {
09127    struct iax_ie_data ied;
09128    /* Auto-hangup with 30 seconds of inactivity */
09129    iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
09130       sched, 30000, auto_hangup, (void *)(long)callno);
09131    memset(&ied, 0, sizeof(ied));
09132    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09133    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09134    dp->flags |= CACHE_FLAG_TRANSMITTED;
09135 }

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

Definition at line 1336 of file chan_iax2.c.

References ast_calloc, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_var_assign(), ast_var_name(), ast_var_value(), ast_var_t::entries, and LOG_ERROR.

01337 {
01338    AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01339    struct ast_var_t *oldvar, *newvar;
01340 
01341    newlist = ast_calloc(sizeof(*newlist), 1);
01342    if (!newlist) {
01343       ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01344       return NULL;
01345    }
01346 
01347    AST_LIST_HEAD_INIT(newlist);
01348    AST_LIST_LOCK(oldlist);
01349    AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01350       newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01351       if (newvar)
01352          AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01353       else
01354          ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01355    }
01356    AST_LIST_UNLOCK(oldlist);
01357    return newlist;
01358 }

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

Execute IAX2 dialplan switch.

Definition at line 13900 of file chan_iax2.c.

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_verb, CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_exec(), and pbx_findapp().

13901 {
13902    char odata[256];
13903    char req[256];
13904    char *ncontext;
13905    struct iax2_dpcache *dp = NULL;
13906    struct ast_app *dial = NULL;
13907 #if 0
13908    ast_log(LOG_NOTICE, "iax2_exec: con: %s, exten: %s, pri: %d, cid: %s, data: %s, newstack: %d\n", context, exten, priority, callerid ? callerid : "<unknown>", data, newstack);
13909 #endif
13910    if (priority == 2) {
13911       /* Indicate status, can be overridden in dialplan */
13912       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13913       if (dialstatus) {
13914          dial = pbx_findapp(dialstatus);
13915          if (dial) 
13916             pbx_exec(chan, dial, "");
13917       }
13918       return -1;
13919    } else if (priority != 1)
13920       return -1;
13921 
13922    AST_LIST_LOCK(&dpcache);
13923    if ((dp = find_cache(chan, data, context, exten, priority))) {
13924       if (dp->flags & CACHE_FLAG_EXISTS) {
13925          ast_copy_string(odata, data, sizeof(odata));
13926          ncontext = strchr(odata, '/');
13927          if (ncontext) {
13928             *ncontext = '\0';
13929             ncontext++;
13930             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13931          } else {
13932             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13933          }
13934          ast_verb(3, "Executing Dial('%s')\n", req);
13935       } else {
13936          AST_LIST_UNLOCK(&dpcache);
13937          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13938          return -1;
13939       }
13940    }
13941    AST_LIST_UNLOCK(&dpcache);
13942 
13943    if ((dial = pbx_findapp("Dial")))
13944       return pbx_exec(chan, dial, req);
13945    else
13946       ast_log(LOG_WARNING, "No dial application registered\n");
13947 
13948    return -1;
13949 }

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

Part of the IAX2 switch interface.

Definition at line 13831 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.

13832 {
13833    int res = 0;
13834    struct iax2_dpcache *dp = NULL;
13835 #if 0
13836    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13837 #endif
13838    if ((priority != 1) && (priority != 2))
13839       return 0;
13840 
13841    AST_LIST_LOCK(&dpcache);
13842    if ((dp = find_cache(chan, data, context, exten, priority))) {
13843       if (dp->flags & CACHE_FLAG_EXISTS)
13844          res = 1;
13845    } else {
13846       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13847    }
13848    AST_LIST_UNLOCK(&dpcache);
13849 
13850    return res;
13851 }

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

Definition at line 4369 of file chan_iax2.c.

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

04370 {
04371    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04372    ast_mutex_lock(&iaxsl[callno]);
04373    if (iaxs[callno])
04374       iaxs[callno]->owner = newchan;
04375    else
04376       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04377    ast_mutex_unlock(&iaxsl[callno]);
04378    return 0;
04379 }

static void iax2_frame_free ( struct iax_frame fr  )  [static]

static void iax2_free_variable_datastore ( void *  old  )  [static]

Definition at line 1360 of file chan_iax2.c.

References ast_free, AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and ast_var_t::entries.

01361 {
01362    AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01363    struct ast_var_t *oldvar;
01364 
01365    AST_LIST_LOCK(oldlist);
01366    while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01367       ast_free(oldvar);
01368    }
01369    AST_LIST_UNLOCK(oldlist);
01370    AST_LIST_HEAD_DESTROY(oldlist);
01371    ast_free(oldlist);
01372 }

const char* iax2_getformatname ( iax2_format  format  ) 

iax2 wrapper function for ast_getformatname

Definition at line 1670 of file chan_iax2.c.

References ast_format_from_old_bitfield(), and ast_getformatname().

Referenced by dump_versioned_codec(), handle_cli_iax2_show_channels(), iax_show_provisioning(), and socket_process().

01671 {
01672    struct ast_format tmpfmt;
01673    if (!(ast_format_from_old_bitfield(&tmpfmt, format))) {
01674       return "Unknown";
01675    }
01676 
01677    return ast_getformatname(&tmpfmt);
01678 }

static char* iax2_getformatname_multiple ( char *  codec_buf,
size_t  len,
iax2_format  format 
) [static]

Definition at line 1680 of file chan_iax2.c.

References ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_cap_from_old_bitfield(), and ast_getformatname_multiple().

Referenced by function_iaxpeer(), handle_cli_iax2_show_peer(), and socket_process().

01681 {
01682    struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
01683 
01684    if (!cap) {
01685       return "(Nothing)";
01686    }
01687    ast_format_cap_from_old_bitfield(cap, format);
01688    ast_getformatname_multiple(codec_buf, len, cap);
01689    cap = ast_format_cap_destroy(cap);
01690 
01691    return codec_buf;
01692 }

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

Definition at line 1814 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), ast_sockaddr_to_sin, iax2_peer::name, peer_unref(), and realtime_peer().

Referenced by __find_callno().

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

static int iax2_getpeertrunk ( struct sockaddr_in  sin  )  [static]

Definition at line 5761 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_sockaddr_to_sin, ast_test_flag64, IAX_TRUNK, and peer_unref().

Referenced by check_access().

05762 {
05763    struct iax2_peer *peer;
05764    int res = 0;
05765    struct ao2_iterator i;
05766 
05767    i = ao2_iterator_init(peers, 0);
05768    while ((peer = ao2_iterator_next(&i))) {
05769       struct sockaddr_in peer_addr;
05770 
05771       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05772 
05773       if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05774           (peer_addr.sin_port == sin.sin_port)) {
05775          res = ast_test_flag64(peer, IAX_TRUNK);
05776          peer_unref(peer);
05777          break;
05778       }
05779       peer_unref(peer);
05780    }
05781    ao2_iterator_destroy(&i);
05782 
05783    return res;
05784 }

static int iax2_hangup ( struct ast_channel c  )  [static]

Definition at line 5288 of file chan_iax2.c.

References ast_channel_name(), ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_add(), ast_test_flag64, ast_verb, iax_ie_data::buf, CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, LOG_ERROR, LOG_WARNING, iax_ie_data::pos, PTR_TO_CALLNO, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.

05289 {
05290    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05291    struct iax_ie_data ied;
05292    int alreadygone;
05293    memset(&ied, 0, sizeof(ied));
05294    ast_mutex_lock(&iaxsl[callno]);
05295    if (callno && iaxs[callno]) {
05296       ast_debug(1, "We're hanging up %s now...\n", ast_channel_name(c));
05297       alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
05298       /* Send the hangup unless we have had a transmission error or are already gone */
05299       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05300       if (!iaxs[callno]->error && !alreadygone) {
05301          if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05302             ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05303          }
05304          if (!iaxs[callno]) {
05305             ast_mutex_unlock(&iaxsl[callno]);
05306             return 0;
05307          }
05308       }
05309       /* Explicitly predestroy it */
05310       iax2_predestroy(callno);
05311       /* If we were already gone to begin with, destroy us now */
05312       if (iaxs[callno] && alreadygone) {
05313          ast_debug(1, "Really destroying %s now...\n", ast_channel_name(c));
05314          iax2_destroy(callno);
05315       } else if (iaxs[callno]) {
05316          if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05317             ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!!  Destroying immediately.\n", callno);
05318             iax2_destroy(callno);
05319          }
05320       }
05321    } else if (c->tech_pvt) {
05322       /* If this call no longer exists, but the channel still
05323        * references it we need to set the channel's tech_pvt to null
05324        * to avoid ast_channel_free() trying to free it.
05325        */
05326       c->tech_pvt = NULL;
05327    }
05328    ast_mutex_unlock(&iaxsl[callno]);
05329    ast_verb(3, "Hungup '%s'\n", ast_channel_name(c));
05330    return 0;
05331 }

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

Definition at line 5697 of file chan_iax2.c.

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

05698 {
05699    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05700    struct chan_iax2_pvt *pvt;
05701    int res = 0;
05702 
05703    if (iaxdebug)
05704       ast_debug(1, "Indicating condition %d\n", condition);
05705 
05706    ast_mutex_lock(&iaxsl[callno]);
05707    pvt = iaxs[callno];
05708 
05709    if (wait_for_peercallno(pvt)) {
05710       res = -1;
05711       goto done;
05712    }
05713 
05714    switch (condition) {
05715    case AST_CONTROL_HOLD:
05716       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05717          ast_moh_start(c, data, pvt->mohinterpret);
05718          goto done;
05719       }
05720       break;
05721    case AST_CONTROL_UNHOLD:
05722       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05723          ast_moh_stop(c);
05724          goto done;
05725       }
05726       break;
05727    case AST_CONTROL_CONNECTED_LINE:
05728       if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
05729          goto done;
05730       break;
05731    }
05732 
05733    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05734 
05735 done:
05736    ast_mutex_unlock(&iaxsl[callno]);
05737 
05738    return res;
05739 }

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

Definition at line 5450 of file chan_iax2.c.

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

Referenced by iax2_send().

05451 {
05452    int res = 0;
05453    struct chan_iax2_pvt *pvt = (void *) vpvt;
05454    struct MD5Context md5;
05455    char key[17] = "";
05456    struct iax_ie_data ied = {
05457       .pos = 0,
05458    };
05459 
05460    ast_mutex_lock(&iaxsl[pvt->callno]);
05461    pvt->keyrotateid = ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05462 
05463    snprintf(key, sizeof(key), "%lX", ast_random());
05464 
05465    MD5Init(&md5);
05466    MD5Update(&md5, (unsigned char *) key, strlen(key));
05467    MD5Final((unsigned char *) key, &md5);
05468 
05469    IAX_DEBUGDIGEST("Sending", key);
05470 
05471    iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05472 
05473    res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05474 
05475    build_ecx_key((unsigned char *) key, pvt);
05476 
05477    ast_mutex_unlock(&iaxsl[pvt->callno]);
05478 
05479    return res;
05480 }

static void iax2_lock_owner ( int  callno  )  [static]

Definition at line 1259 of file chan_iax2.c.

References ast_channel_trylock, and DEADLOCK_AVOIDANCE.

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

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

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

Part of the IAX2 Switch interface.

Definition at line 13877 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_MATCHMORE, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.

13878 {
13879    int res = 0;
13880    struct iax2_dpcache *dp = NULL;
13881 #if 0
13882    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13883 #endif
13884    if ((priority != 1) && (priority != 2))
13885       return 0;
13886 
13887    AST_LIST_LOCK(&dpcache);
13888    if ((dp = find_cache(chan, data, context, exten, priority))) {
13889       if (dp->flags & CACHE_FLAG_MATCHMORE)
13890          res = 1;
13891    } else {
13892       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13893    }
13894    AST_LIST_UNLOCK(&dpcache);
13895 
13896    return res;
13897 }

static int iax2_parse_allow_disallow ( struct ast_codec_pref pref,
iax2_format formats,
const char *  list,
int  allowing 
) [static]

Definition at line 1694 of file chan_iax2.c.

References ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_cap_from_old_bitfield(), ast_format_cap_to_old_bitfield(), and ast_parse_allow_disallow().

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

01695 {
01696    int res;
01697    struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
01698    if (!cap) {
01699       return 1;
01700    }
01701 
01702    ast_format_cap_from_old_bitfield(cap, *formats);
01703    res = ast_parse_allow_disallow(pref, cap, list, allowing);
01704    *formats = ast_format_cap_to_old_bitfield(cap);
01705    cap = ast_format_cap_destroy(cap);
01706 
01707    return res;
01708 }

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

Definition at line 12070 of file chan_iax2.c.

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

Referenced by iax2_poke_peer().

12071 {
12072    struct iax2_peer *peer = (struct iax2_peer *)data;
12073    peer->pokeexpire = -1;
12074 #ifdef SCHED_MULTITHREADED
12075    if (schedule_action(__iax2_poke_noanswer, data))
12076 #endif      
12077       __iax2_poke_noanswer(data);
12078    peer_unref(peer);
12079    return 0;
12080 }

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

Definition at line 12091 of file chan_iax2.c.

References add_empty_calltoken_ie(), iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_SCHED_DEL, ast_sockaddr_ipv4(), ast_sockaddr_to_sin, iax_ie_data::buf, iax2_peer::callno, DEFAULT_MAXMS, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax_ie_data::pos, send_command(), and iax2_peer::sockfd.

Referenced by __iax2_poke_peer_s(), iax2_poke_peer_cb(), poke_all_peers(), reg_source_db(), and update_registry().

12092 {
12093    int callno;
12094    struct sockaddr_in peer_addr;
12095 
12096    if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
12097       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
12098         immediately after clearing things out */
12099       peer->lastms = 0;
12100       peer->historicms = 0;
12101       peer->pokeexpire = -1;
12102       peer->callno = 0;
12103       return 0;
12104    }
12105 
12106    ast_sockaddr_to_sin(&peer->addr, &peer_addr);
12107 
12108    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
12109    if ((callno = peer->callno) > 0) {
12110       ast_log(LOG_NOTICE, "Still have a callno...\n");
12111       ast_mutex_lock(&iaxsl[callno]);
12112       iax2_destroy(callno);
12113       ast_mutex_unlock(&iaxsl[callno]);
12114    }
12115    if (heldcall)
12116       ast_mutex_unlock(&iaxsl[heldcall]);
12117    callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
12118    if (heldcall)
12119       ast_mutex_lock(&iaxsl[heldcall]);
12120    if (peer->callno < 1) {
12121       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12122       return -1;
12123    }
12124 
12125    /* Speed up retransmission times for this qualify call */
12126    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
12127    iaxs[peer->callno]->peerpoke = peer;
12128 
12129    if (peer->pokeexpire > -1) {
12130       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
12131          peer->pokeexpire = -1;
12132          peer_unref(peer);
12133       }
12134    }
12135 
12136    /* Queue up a new task to handle no reply */
12137    /* If the host is already unreachable then use the unreachable interval instead */
12138    if (peer->lastms < 0)
12139       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
12140    else
12141       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
12142 
12143    if (peer->pokeexpire == -1)
12144       peer_unref(peer);
12145 
12146    /* And send the poke */
12147    ast_mutex_lock(&iaxsl[callno]);
12148    if (iaxs[callno]) {
12149       struct iax_ie_data ied = {
12150          .buf = { 0 },
12151          .pos = 0,
12152       };
12153       add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
12154       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12155    }
12156    ast_mutex_unlock(&iaxsl[callno]);
12157 
12158    return 0;
12159 }

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

Definition at line 12082 of file chan_iax2.c.

References iax2_poke_peer().

Referenced by load_module().

12083 {
12084    struct iax2_peer *peer = obj;
12085 
12086    iax2_poke_peer(peer, 0);
12087 
12088    return 0;
12089 }

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

Definition at line 9162 of file chan_iax2.c.

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

Referenced by __iax2_poke_noanswer(), and socket_process().

09163 {
09164    struct iax2_peer *peer = (struct iax2_peer *)data;
09165    peer->pokeexpire = -1;
09166 #ifdef SCHED_MULTITHREADED
09167    if (schedule_action(__iax2_poke_peer_s, data))
09168 #endif      
09169       __iax2_poke_peer_s(data);
09170    return 0;
09171 }

static int iax2_predestroy ( int  callno  )  [static]

Note:
Since this function calls iax2_queue_hangup(), the pvt struct for the given call number may disappear during its execution.

Definition at line 3426 of file chan_iax2.c.

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

Referenced by iax2_hangup(), and send_command_final().

03427 {
03428    struct ast_channel *c = NULL;
03429    struct chan_iax2_pvt *pvt = iaxs[callno];
03430 
03431    if (!pvt)
03432       return -1;
03433 
03434    if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
03435       iax2_destroy_helper(pvt);
03436       ast_set_flag64(pvt, IAX_ALREADYGONE);
03437    }
03438 
03439    if ((c = pvt->owner)) {
03440       c->tech_pvt = NULL;
03441       iax2_queue_hangup(callno);
03442       pvt->owner = NULL;
03443       ast_module_unref(ast_module_info->self);
03444    }
03445 
03446    return 0;
03447 }

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

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

References iax2_thread::actions, ast_atomic_fetchadd_int(), ast_cond_timedwait, ast_cond_wait, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), iax2_thread::checktime, iax2_thread::cond, iax2_thread::curfunc, handle_deferred_full_frames(), iax2_process_thread_cleanup(), IAX_IOSTATE_IDLE, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_READY, IAX_IOSTATE_SCHEDREADY, IAX_THREAD_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, iax2_thread::init_cond, iax2_thread::init_lock, insert_idle_thread(), iax2_thread::iostate, iax2_thread::lock, iax2_thread::scheddata, iax2_thread::schedfunc, signal_condition(), socket_process(), iax2_thread::stop, thread, and iax2_thread::type.

Referenced by find_idle_thread(), and start_network_thread().

11722 {
11723    struct iax2_thread *thread = data;
11724    struct timeval wait;
11725    struct timespec ts;
11726    int put_into_idle = 0;
11727    int first_time = 1;
11728    int old_state;
11729 
11730    ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11731 
11732    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11733    pthread_cleanup_push(iax2_process_thread_cleanup, data);
11734 
11735    for (;;) {
11736       /* Wait for something to signal us to be awake */
11737       ast_mutex_lock(&thread->lock);
11738 
11739       if (thread->stop) {
11740          ast_mutex_unlock(&thread->lock);
11741          break;
11742       }
11743 
11744       /* Flag that we're ready to accept signals */
11745       if (first_time) {
11746          signal_condition(&thread->init_lock, &thread->init_cond);
11747          first_time = 0;
11748       }
11749 
11750       /* Put into idle list if applicable */
11751       if (put_into_idle) {
11752          insert_idle_thread(thread);
11753       }
11754 
11755       if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11756          struct iax2_thread *t = NULL;
11757          /* Wait to be signalled or time out */
11758          wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11759          ts.tv_sec = wait.tv_sec;
11760          ts.tv_nsec = wait.tv_usec * 1000;
11761          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11762             /* This thread was never put back into the available dynamic
11763              * thread list, so just go away. */
11764             if (!put_into_idle || thread->stop) {
11765                ast_mutex_unlock(&thread->lock);
11766                break;
11767             }
11768             AST_LIST_LOCK(&dynamic_list);
11769             /* Account for the case where this thread is acquired *right* after a timeout */
11770             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11771                ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11772             AST_LIST_UNLOCK(&dynamic_list);
11773             if (t) {
11774                /* This dynamic thread timed out waiting for a task and was
11775                 * not acquired immediately after the timeout, 
11776                 * so it's time to go away. */
11777                ast_mutex_unlock(&thread->lock);
11778                break;
11779             }
11780             /* Someone grabbed our thread *right* after we timed out.
11781              * Wait for them to set us up with something to do and signal
11782              * us to continue. */
11783             wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11784             ts.tv_sec = wait.tv_sec;
11785             ts.tv_nsec = wait.tv_usec * 1000;
11786             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11787                ast_mutex_unlock(&thread->lock);
11788                break;
11789             }
11790          }
11791       } else {
11792          ast_cond_wait(&thread->cond, &thread->lock);
11793       }
11794 
11795       /* Go back into our respective list */
11796       put_into_idle = 1;
11797 
11798       ast_mutex_unlock(&thread->lock);
11799 
11800       if (thread->stop) {
11801          break;
11802       }
11803 
11804       if (thread->iostate == IAX_IOSTATE_IDLE)
11805          continue;
11806 
11807       /* See what we need to do */
11808       switch (thread->iostate) {
11809       case IAX_IOSTATE_READY:
11810          thread->actions++;
11811          thread->iostate = IAX_IOSTATE_PROCESSING;
11812          socket_process(thread);
11813          handle_deferred_full_frames(thread);
11814          break;
11815       case IAX_IOSTATE_SCHEDREADY:
11816          thread->actions++;
11817          thread->iostate = IAX_IOSTATE_PROCESSING;
11818 #ifdef SCHED_MULTITHREADED
11819          thread->schedfunc(thread->scheddata);
11820 #endif      
11821       default:
11822          break;
11823       }
11824       time(&thread->checktime);
11825       thread->iostate = IAX_IOSTATE_IDLE;
11826 #ifdef DEBUG_SCHED_MULTITHREAD
11827       thread->curfunc[0]='\0';
11828 #endif      
11829 
11830       /* The network thread added us to the active_thread list when we were given
11831        * frames to process, Now that we are done, we must remove ourselves from
11832        * the active list, and return to the idle list */
11833       AST_LIST_LOCK(&active_list);
11834       AST_LIST_REMOVE(&active_list, thread, list);
11835       AST_LIST_UNLOCK(&active_list);
11836 
11837       /* Make sure another frame didn't sneak in there after we thought we were done. */
11838       handle_deferred_full_frames(thread);
11839    }
11840 
11841    /*!
11842     * \note For some reason, idle threads are exiting without being removed
11843     * from an idle list, which is causing memory corruption.  Forcibly remove
11844     * it from the list, if it's there.
11845     */
11846    AST_LIST_LOCK(&idle_list);
11847    AST_LIST_REMOVE(&idle_list, thread, list);
11848    AST_LIST_UNLOCK(&idle_list);
11849 
11850    AST_LIST_LOCK(&dynamic_list);
11851    AST_LIST_REMOVE(&dynamic_list, thread, list);
11852    AST_LIST_UNLOCK(&dynamic_list);
11853 
11854    if (!thread->stop) {
11855       /* Nobody asked me to stop so nobody is waiting to join me. */
11856       pthread_detach(pthread_self());
11857    }
11858 
11859    /* I am exiting here on my own volition, I need to clean up my own data structures
11860    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
11861    */
11862    pthread_cleanup_pop(1);
11863    return NULL;
11864 }

static void iax2_process_thread_cleanup ( void *  data  )  [static]

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

Definition at line 11927 of file chan_iax2.c.

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

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

11928 {
11929    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
11930       is found for template */
11931    struct iax_ie_data provdata;
11932    struct iax_ie_data ied;
11933    unsigned int sig;
11934    struct sockaddr_in sin;
11935    int callno;
11936    struct create_addr_info cai;
11937 
11938    memset(&cai, 0, sizeof(cai));
11939 
11940    ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11941 
11942    if (iax_provision_build(&provdata, &sig, template, force)) {
11943       ast_debug(1, "No provisioning found for template '%s'\n", template);
11944       return 0;
11945    }
11946 
11947    if (end) {
11948       memcpy(&sin, end, sizeof(sin));
11949       cai.sockfd = sockfd;
11950    } else if (create_addr(dest, NULL, &sin, &cai))
11951       return -1;
11952 
11953    /* Build the rest of the message */
11954    memset(&ied, 0, sizeof(ied));
11955    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11956 
11957    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11958    if (!callno)
11959       return -1;
11960 
11961    if (iaxs[callno]) {
11962       /* Schedule autodestruct in case they don't ever give us anything back */
11963       iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
11964          sched, 15000, auto_hangup, (void *)(long)callno);
11965       ast_set_flag64(iaxs[callno], IAX_PROVISION);
11966       /* Got a call number now, so go ahead and send the provisioning information */
11967       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11968    }
11969    ast_mutex_unlock(&iaxsl[callno]);
11970 
11971    return 1;
11972 }

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

Definition at line 5427 of file chan_iax2.c.

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

05428 {
05429    switch (option) {
05430    case AST_OPTION_SECURE_SIGNALING:
05431    case AST_OPTION_SECURE_MEDIA:
05432    {
05433       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05434       ast_mutex_lock(&iaxsl[callno]);
05435       *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05436       ast_mutex_unlock(&iaxsl[callno]);
05437       return 0;
05438    }
05439    default:
05440       return -1;
05441    }
05442 }

static int iax2_queue_control_data ( int  callno,
enum ast_control_frame_type  control,
const void *  data,
size_t  datalen 
) [static]

Queue a control frame on the ast_channel owner.

This function queues a control frame on the owner of the IAX2 pvt struct that is active for the given call number.

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

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

Referenced by socket_process().

03061 {
03062    iax2_lock_owner(callno);
03063    if (iaxs[callno] && iaxs[callno]->owner) {
03064       ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
03065       ast_channel_unlock(iaxs[callno]->owner);
03066    }
03067    return 0;
03068 }

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

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

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

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

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

03014 {
03015    iax2_lock_owner(callno);
03016    if (iaxs[callno] && iaxs[callno]->owner) {
03017       ast_queue_frame(iaxs[callno]->owner, f);
03018       ast_channel_unlock(iaxs[callno]->owner);
03019    }
03020    return 0;
03021 }

static int iax2_queue_hangup ( int  callno  )  [static]

Queue a hangup frame on the ast_channel owner.

This function queues a hangup frame on the owner of the IAX2 pvt struct that is active for the given call number.

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

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

Referenced by iax2_predestroy().

03037 {
03038    iax2_lock_owner(callno);
03039    if (iaxs[callno] && iaxs[callno]->owner) {
03040       ast_queue_hangup(iaxs[callno]->owner);
03041       ast_channel_unlock(iaxs[callno]->owner);
03042    }
03043    return 0;
03044 }

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

Definition at line 5444 of file chan_iax2.c.

References ast_debug, and ast_null_frame.

05445 {
05446    ast_debug(1, "I should never be called!\n");
05447    return &ast_null_frame;
05448 }

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

Definition at line 8599 of file chan_iax2.c.

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

Referenced by set_config().

08600 {
08601    char copy[256];
08602    char *username, *hostname, *secret;
08603    char *porta;
08604    char *stringp=NULL;
08605    
08606    if (!value)
08607       return -1;
08608 
08609    ast_copy_string(copy, value, sizeof(copy));
08610    stringp = copy;
08611    username = strsep(&stringp, "@");
08612    hostname = strsep(&stringp, "@");
08613 
08614    if (!hostname) {
08615       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08616       return -1;
08617    }
08618 
08619    stringp = username;
08620    username = strsep(&stringp, ":");
08621    secret = strsep(&stringp, ":");
08622    stringp = hostname;
08623    hostname = strsep(&stringp, ":");
08624    porta = strsep(&stringp, ":");
08625    
08626    if (porta && !atoi(porta)) {
08627       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08628       return -1;
08629    }
08630 
08631    return iax2_append_register(hostname, username, secret, porta);
08632 }

static struct ast_channel * iax2_request ( const char *  type,
struct ast_format_cap cap,
const struct ast_channel requestor,
const char *  data,
int *  cause 
) [static, read]

Definition at line 12171 of file chan_iax2.c.

References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_channel_linkedid(), ast_channel_name(), ast_copy_flags64, ast_format_cap_copy(), ast_format_cap_destroy(), ast_format_cap_joint(), ast_format_cap_set(), ast_format_copy(), ast_getformatname_multiple(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_unlock, AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_translator_best_choice(), create_addr_info::capability, create_addr(), find_callno_locked(), create_addr_info::found, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, LOG_WARNING, make_trunk(), create_addr_info::maxtime, chan_iax2_pvt::maxtime, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), parsed_dial_string::peer, parsed_dial_string::port, ast_channel::readformat, create_addr_info::sockfd, and ast_channel::writeformat.

12172 {
12173    int callno;
12174    int res;
12175    struct sockaddr_in sin;
12176    struct ast_channel *c;
12177    struct parsed_dial_string pds;
12178    struct create_addr_info cai;
12179    char *tmpstr;
12180 
12181    memset(&pds, 0, sizeof(pds));
12182    tmpstr = ast_strdupa(data);
12183    parse_dial_string(tmpstr, &pds);
12184 
12185    if (ast_strlen_zero(pds.peer)) {
12186       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
12187       return NULL;
12188    }
12189    memset(&cai, 0, sizeof(cai));
12190    cai.capability = iax2_capability;
12191 
12192    ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12193 
12194    /* Populate our address from the given */
12195    if (create_addr(pds.peer, NULL, &sin, &cai)) {
12196       *cause = AST_CAUSE_UNREGISTERED;
12197       return NULL;
12198    }
12199 
12200    if (pds.port)
12201       sin.sin_port = htons(atoi(pds.port));
12202 
12203    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12204    if (callno < 1) {
12205       ast_log(LOG_WARNING, "Unable to create call\n");
12206       *cause = AST_CAUSE_CONGESTION;
12207       return NULL;
12208    }
12209 
12210    /* If this is a trunk, update it now */
12211    ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12212    if (ast_test_flag64(&cai, IAX_TRUNK)) {
12213       int new_callno;
12214       if ((new_callno = make_trunk(callno, 1)) != -1)
12215          callno = new_callno;
12216    }
12217    iaxs[callno]->maxtime = cai.maxtime;
12218    if (cai.found)
12219       ast_string_field_set(iaxs[callno], host, pds.peer);
12220 
12221    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? ast_channel_linkedid(requestor) : NULL);
12222 
12223    ast_mutex_unlock(&iaxsl[callno]);
12224 
12225    if (c) {
12226       struct ast_format_cap *joint;
12227 
12228       /* Choose a format we can live with */
12229       if ((joint = ast_format_cap_joint(c->nativeformats, cap))) {
12230          ast_format_cap_copy(c->nativeformats, joint);
12231          joint = ast_format_cap_destroy(joint);
12232       } else {
12233          struct ast_format best_fmt_cap;
12234          struct ast_format best_fmt_native;
12235          res = ast_translator_best_choice(cap, c->nativeformats, &best_fmt_cap, &best_fmt_native);
12236          if (res < 0) {
12237             char tmp[256];
12238             char tmp2[256];
12239             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12240                ast_getformatname_multiple(tmp, sizeof(tmp), c->nativeformats), ast_getformatname_multiple(tmp2, sizeof(tmp2), cap), ast_channel_name(c));
12241             ast_hangup(c);
12242             return NULL;
12243          }
12244          ast_format_cap_set(c->nativeformats, &best_fmt_native);
12245       }
12246       ast_best_codec(c->nativeformats, &c->readformat);
12247       ast_format_copy(&c->writeformat, &c->readformat);
12248    }
12249 
12250    return c;
12251 }

static int iax2_sched_add ( struct ast_sched_context sched,
int  when,
ast_sched_cb  callback,
const void *  data 
) [static]

static int iax2_sched_replace ( int  id,
struct ast_sched_context con,
int  when,
ast_sched_cb  callback,
const void *  data 
) [static]

Definition at line 1488 of file chan_iax2.c.

References ast_sched_replace().

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

01490 {
01491    return ast_sched_replace(id, con, when, callback, data);
01492 }

static int iax2_send ( struct chan_iax2_pvt pvt,
struct ast_frame f,
unsigned int  ts,
int  seqno,
int  now,
int  transfer,
int  final 
) [static]

Definition at line 6431 of file chan_iax2.c.

References chan_iax2_pvt::addr, iax_frame::af, chan_iax2_pvt::aseqno, ast_format_get_video_mark(), ast_format_id_from_old_bitfield(), ast_format_to_old_bitfield(), AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag64, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, iax_frame::datalen, ast_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, iax_frame::ecx, chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_frame::encmethods, encrypt_frame(), iax_frame::final, chan_iax2_pvt::first_iax_message, ast_frame_subclass::format, ast_frame::frametype, iax2_key_rotate(), iax2_transmit(), iax2_trunk_queue(), IAX_CALLENCRYPTED, IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_outputframe(), IAX_TRUNK, ast_format::id, ast_frame_subclass::integer, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::last_iax_message, chan_iax2_pvt::lastsent, iax2_trunk_peer::lastsent, chan_iax2_pvt::lastvsent, LOG_NOTICE, LOG_WARNING, MARK_IAX_SUBCLASS_TX, MAX_RETRY_TIME, MIN_RETRY_TIME, chan_iax2_pvt::mydcx, iax_frame::mydcx, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, ast_frame::ptr, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, iax_frame::semirand, chan_iax2_pvt::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, iax_frame::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.

Referenced by __send_command(), iax2_write(), send_signaling(), and socket_process().

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

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

Definition at line 4364 of file chan_iax2.c.

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

04365 {
04366    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04367 }

static int iax2_sendimage ( struct ast_channel c,
struct ast_frame img 
) [static]

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

Definition at line 4352 of file chan_iax2.c.

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

04353 {
04354    
04355    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04356       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04357 }

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

Definition at line 5355 of file chan_iax2.c.

References ast_clear_flag64, AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_free, ast_malloc, ast_mutex_lock, ast_mutex_unlock, AST_OPTION_AUDIO_MODE, AST_OPTION_DIGIT_DETECT, AST_OPTION_FAX_DETECT, AST_OPTION_FLAG_REQUEST, AST_OPTION_OPRMODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_set_flag64, ast_option_header::data, errno, IAX_FORCE_ENCRYPT, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().

05356 {
05357    struct ast_option_header *h;
05358    int res;
05359 
05360    switch (option) {
05361    case AST_OPTION_TXGAIN:
05362    case AST_OPTION_RXGAIN:
05363       /* these two cannot be sent, because they require a result */
05364       errno = ENOSYS;
05365       return -1;
05366    case AST_OPTION_OPRMODE:
05367       errno = EINVAL;
05368       return -1;
05369    case AST_OPTION_SECURE_SIGNALING:
05370    case AST_OPTION_SECURE_MEDIA:
05371    {
05372       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05373       ast_mutex_lock(&iaxsl[callno]);
05374       if ((*(int *) data)) {
05375          ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05376       } else {
05377          ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05378       }
05379       ast_mutex_unlock(&iaxsl[callno]);
05380       return 0;
05381    }
05382    /* These options are sent to the other side across the network where
05383     * they will be passed to whatever channel is bridged there. Don't
05384     * do anything silly like pass an option that transmits pointers to
05385     * memory on this machine to a remote machine to use */
05386    case AST_OPTION_TONE_VERIFY:
05387    case AST_OPTION_TDD:
05388    case AST_OPTION_RELAXDTMF:
05389    case AST_OPTION_AUDIO_MODE:
05390    case AST_OPTION_DIGIT_DETECT:
05391    case AST_OPTION_FAX_DETECT:
05392    {
05393       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05394       struct chan_iax2_pvt *pvt;
05395 
05396       ast_mutex_lock(&iaxsl[callno]);
05397       pvt = iaxs[callno];
05398 
05399       if (wait_for_peercallno(pvt)) {
05400          ast_mutex_unlock(&iaxsl[callno]);
05401          return -1;
05402       }
05403 
05404       ast_mutex_unlock(&iaxsl[callno]);
05405 
05406       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05407          return -1;
05408       }
05409 
05410       h->flag = AST_OPTION_FLAG_REQUEST;
05411       h->option = htons(option);
05412       memcpy(h->data, data, datalen);
05413       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05414                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
05415                  datalen + sizeof(*h), -1);
05416       ast_free(h);
05417       return res;
05418    }
05419    default:
05420       return -1;
05421    }
05422 
05423    /* Just in case someone does a break instead of a return */
05424    return -1;
05425 }

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

Definition at line 5482 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_debug, AST_FRAME_IAX, ast_random(), ast_set_flag64, iax_ie_data::buf, IAX_CALLENCRYPTED, IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, IAX_NOTRANSFER, iax_ie_data::pos, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.

Referenced by iax2_bridge().

05483 {
05484    int res;
05485    struct iax_ie_data ied0;
05486    struct iax_ie_data ied1;
05487    unsigned int transferid = (unsigned int)ast_random();
05488 
05489    if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05490       ast_debug(1, "transfers are not supported for encrypted calls at this time");
05491       ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05492       ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05493       return 0;
05494    }
05495 
05496    memset(&ied0, 0, sizeof(ied0));
05497    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05498    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05499    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05500 
05501    memset(&ied1, 0, sizeof(ied1));
05502    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05503    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05504    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05505 
05506    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05507    if (res)
05508       return -1;
05509    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05510    if (res)
05511       return -1;
05512    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05513    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05514    return 0;
05515 }

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

Definition at line 5741 of file chan_iax2.c.

References ast_channel_name(), AST_CONTROL_TRANSFER, ast_copy_string(), ast_debug, AST_FRAME_IAX, ast_queue_control_data(), AST_TRANSFER_SUCCESS, iax_ie_data::buf, chan_iax2_pvt::callno, context, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, iax_ie_data::pos, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

05742 {
05743    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05744    struct iax_ie_data ied = { "", };
05745    char tmp[256], *context;
05746    enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05747    ast_copy_string(tmp, dest, sizeof(tmp));
05748    context = strchr(tmp, '@');
05749    if (context) {
05750       *context = '\0';
05751       context++;
05752    }
05753    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05754    if (context)
05755       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05756    ast_debug(1, "Transferring '%s' to '%s'\n", ast_channel_name(c), dest);
05757    ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05758    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05759 }

static int iax2_transmit ( struct iax_frame fr  )  [static]

Definition at line 4335 of file chan_iax2.c.

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

Referenced by iax2_send().

04336 {
04337    fr->sentyet = 0;
04338 
04339    return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04340 }

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

Definition at line 9216 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

09217 {
09218    /* Drop when trunk is about 5 seconds idle */
09219    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
09220       return 1;
09221    return 0;
09222 }

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

Definition at line 6169 of file chan_iax2.c.

References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_unlock, ast_realloc, ast_test_flag64, ast_tvnow(), ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, ast_frame::data, ast_frame::datalen, DEFAULT_TRUNKDATA, f, find_tpeer(), IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, ast_frame::ptr, send_trunk(), chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.

Referenced by iax2_send().

06170 {
06171    struct ast_frame *f;
06172    struct iax2_trunk_peer *tpeer;
06173    void *tmp, *ptr;
06174    struct timeval now;
06175    struct ast_iax2_meta_trunk_entry *met;
06176    struct ast_iax2_meta_trunk_mini *mtm;
06177 
06178    f = &fr->af;
06179    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06180    if (tpeer) {
06181       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06182          /* Need to reallocate space */
06183          if (tpeer->trunkdataalloc < trunkmaxsize) {
06184             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06185                ast_mutex_unlock(&tpeer->lock);
06186                return -1;
06187             }
06188 
06189             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06190             tpeer->trunkdata = tmp;
06191             ast_debug(1, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
06192          } else {
06193             ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06194             ast_mutex_unlock(&tpeer->lock);
06195             return -1;
06196          }
06197       }
06198 
06199       /* Append to meta frame */
06200       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06201       if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06202          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06203          mtm->len = htons(f->datalen);
06204          mtm->mini.callno = htons(pvt->callno);
06205          mtm->mini.ts = htons(0xffff & fr->ts);
06206          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06207          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06208       } else {
06209          met = (struct ast_iax2_meta_trunk_entry *)ptr;
06210          /* Store call number and length in meta header */
06211          met->callno = htons(pvt->callno);
06212          met->len = htons(f->datalen);
06213          /* Advance pointers/decrease length past trunk entry header */
06214          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06215          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06216       }
06217       /* Copy actual trunk data */
06218       memcpy(ptr, f->data.ptr, f->datalen);
06219       tpeer->trunkdatalen += f->datalen;
06220 
06221       tpeer->calls++;
06222 
06223       /* track the largest mtu we actually have sent */
06224       if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 
06225          trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 
06226 
06227       /* if we have enough for a full MTU, ship it now without waiting */
06228       if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06229          now = ast_tvnow();
06230          send_trunk(tpeer, &now); 
06231          trunk_untimed ++; 
06232       }
06233 
06234       ast_mutex_unlock(&tpeer->lock);
06235    }
06236    return 0;
06237 }

static int iax2_vnak ( int  callno  )  [static]

Definition at line 9137 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_VNAK, and send_command_immediate().

Referenced by socket_process(), and socket_process_meta().

09138 {
09139    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09140 }

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

Definition at line 7513 of file chan_iax2.c.

References ast_debug, AST_FRAME_NULL, AST_FRAME_VOICE, ast_mutex_lock, ast_mutex_unlock, ast_test_flag, ast_test_flag64, errno, ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, PTR_TO_CALLNO, and ast_channel::tech_pvt.

07514 {
07515    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07516    int res = -1;
07517    ast_mutex_lock(&iaxsl[callno]);
07518    if (iaxs[callno]) {
07519    /* If there's an outstanding error, return failure now */
07520       if (!iaxs[callno]->error) {
07521          if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07522             res = 0;
07523             /* Don't waste bandwidth sending null frames */
07524          else if (f->frametype == AST_FRAME_NULL)
07525             res = 0;
07526          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07527             res = 0;
07528          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07529             res = 0;
07530          else
07531          /* Simple, just queue for transmission */
07532             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07533       } else {
07534          ast_debug(1, "Write error: %s\n", strerror(errno));
07535       }
07536    }
07537    /* If it's already gone, just return */
07538    ast_mutex_unlock(&iaxsl[callno]);
07539    return res;
07540 }

static int iax_check_version ( char *  dev  )  [static]

Definition at line 3218 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_iax2_firmware_header::devname, iax_firmware::fwh, and ast_iax2_firmware_header::version.

Referenced by update_registry().

03219 {
03220    int res = 0;
03221    struct iax_firmware *cur = NULL;
03222 
03223    if (ast_strlen_zero(dev))
03224       return 0;
03225 
03226    AST_LIST_LOCK(&firmwares);
03227    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03228       if (!strcmp(dev, (char *)cur->fwh->devname)) {
03229          res = ntohs(cur->fwh->version);
03230          break;
03231       }
03232    }
03233    AST_LIST_UNLOCK(&firmwares);
03234 
03235    return res;
03236 }

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

Definition at line 1117 of file chan_iax2.c.

References ast_verbose.

Referenced by load_module().

01118 {
01119    if (iaxdebug)
01120       ast_verbose("%s", data);
01121 }

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

Definition at line 1123 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

01124 {
01125    ast_log(LOG_WARNING, "%s", data);
01126 }

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

Definition at line 3238 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, iax_firmware::fwh, iax_ie_append(), iax_ie_append_int(), iax_ie_append_raw(), IAX_IE_FWBLOCKDATA, and IAX_IE_FWBLOCKDESC.

Referenced by socket_process().

03239 {
03240    int res = -1;
03241    unsigned int bs = desc & 0xff;
03242    unsigned int start = (desc >> 8) & 0xffffff;
03243    unsigned int bytes;
03244    struct iax_firmware *cur;
03245 
03246    if (ast_strlen_zero((char *)dev) || !bs)
03247       return -1;
03248 
03249    start *= bs;
03250    
03251    AST_LIST_LOCK(&firmwares);
03252    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03253       if (strcmp((char *)dev, (char *)cur->fwh->devname))
03254          continue;
03255       iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03256       if (start < ntohl(cur->fwh->datalen)) {
03257          bytes = ntohl(cur->fwh->datalen) - start;
03258          if (bytes > bs)
03259             bytes = bs;
03260          iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03261       } else {
03262          bytes = 0;
03263          iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03264       }
03265       if (bytes == bs)
03266          res = 0;
03267       else
03268          res = 1;
03269       break;
03270    }
03271    AST_LIST_UNLOCK(&firmwares);
03272 
03273    return res;
03274 }

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

Definition at line 1100 of file chan_iax2.c.

References debugaddr, and iax_showframe().

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

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

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

DO NOT hold any locks while calling iax_park

Definition at line 9386 of file chan_iax2.c.

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

Referenced by socket_process().

09387 {
09388    struct iax_dual *d;
09389    struct ast_channel *chan1m, *chan2m;/* Chan2m: The transferer, chan1m: The transferee */
09390    pthread_t th;
09391 
09392    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, ast_channel_accountcode(chan2), chan1->exten, chan1->context, ast_channel_linkedid(chan1), chan1->amaflags, "Parking/%s", ast_channel_name(chan1));
09393    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, ast_channel_accountcode(chan2), chan2->exten, chan2->context, ast_channel_linkedid(chan2), chan2->amaflags, "IAXPeer/%s", ast_channel_name(chan2));
09394    d = ast_calloc(1, sizeof(*d));
09395    if (!chan1m || !chan2m || !d) {
09396       if (chan1m) {
09397          ast_hangup(chan1m);
09398       }
09399       if (chan2m) {
09400          ast_hangup(chan2m);
09401       }
09402       ast_free(d);
09403       return -1;
09404    }
09405    d->park_exten = ast_strdup(park_exten);
09406    d->park_context = ast_strdup(park_context);
09407    if (!d->park_exten || !d->park_context) {
09408       ast_hangup(chan1m);
09409       ast_hangup(chan2m);
09410       ast_free(d->park_exten);
09411       ast_free(d->park_context);
09412       ast_free(d);
09413       return -1;
09414    }
09415 
09416    /* Make formats okay */
09417    chan1m->readformat = chan1->readformat;
09418    chan1m->writeformat = chan1->writeformat;
09419 
09420    /* Prepare for taking over the channel */
09421    if (ast_channel_masquerade(chan1m, chan1)) {
09422       ast_hangup(chan1m);
09423       ast_hangup(chan2m);
09424       ast_free(d->park_exten);
09425       ast_free(d->park_context);
09426       ast_free(d);
09427       return -1;
09428    }
09429 
09430    /* Setup the extensions and such */
09431    ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09432    ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09433    chan1m->priority = chan1->priority;
09434 
09435    ast_do_masquerade(chan1m);
09436 
09437    /* We make a clone of the peer channel too, so we can play
09438       back the announcement */
09439 
09440    /* Make formats okay */
09441    chan2m->readformat = chan2->readformat;
09442    chan2m->writeformat = chan2->writeformat;
09443    ast_channel_parkinglot_set(chan2m, ast_channel_parkinglot(chan2));
09444 
09445    /* Prepare for taking over the channel */
09446    if (ast_channel_masquerade(chan2m, chan2)) {
09447       ast_hangup(chan1m);
09448       ast_hangup(chan2m);
09449       ast_free(d->park_exten);
09450       ast_free(d->park_context);
09451       ast_free(d);
09452       return -1;
09453    }
09454 
09455    /* Setup the extensions and such */
09456    ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09457    ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09458    chan2m->priority = chan2->priority;
09459 
09460    ast_do_masquerade(chan2m);
09461 
09462    d->chan1 = chan1m;   /* Transferee */
09463    d->chan2 = chan2m;   /* Transferer */
09464    if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) {
09465       /* Could not start thread */
09466       ast_hangup(chan1m);
09467       ast_hangup(chan2m);
09468       ast_free(d->park_exten);
09469       ast_free(d->park_context);
09470       ast_free(d);
09471       return -1;
09472    }
09473    return 0;
09474 }

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

Definition at line 9359 of file chan_iax2.c.

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

Referenced by iax_park().

09360 {
09361    struct iax_dual *d;
09362    int res;
09363    int ext = 0;
09364 
09365    d = stuff;
09366 
09367    ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n",
09368       ast_channel_name(d->chan2), ast_channel_name(d->chan1));
09369 
09370    res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext);
09371    if (res) {
09372       /* Parking failed. */
09373       ast_hangup(d->chan1);
09374    } else {
09375       ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09376    }
09377    ast_hangup(d->chan2);
09378 
09379    ast_free(d->park_exten);
09380    ast_free(d->park_context);
09381    ast_free(d);
09382    return NULL;
09383 }

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

Definition at line 2031 of file chan_iax2.c.

References iax_frame::af, iax_frame::afdatalen, iax_frame::cacheable, ast_frame::datalen, DIRECTION_INGRESS, iax_frame_new(), and iax_frame_wrap().

Referenced by socket_process(), and socket_process_meta().

02032 {
02033    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
02034    if (new) {
02035       size_t afdatalen = new->afdatalen;
02036       memcpy(new, fr, sizeof(*new));
02037       iax_frame_wrap(new, &fr->af);
02038       new->afdatalen = afdatalen;
02039       new->data = NULL;
02040       new->datalen = 0;
02041       new->direction = DIRECTION_INGRESS;
02042       new->retrans = -1;
02043    }
02044    return new;
02045 }

static void insert_idle_thread ( struct iax2_thread thread  )  [static]

Definition at line 1378 of file chan_iax2.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_THREAD_TYPE_DYNAMIC, and iax2_thread::type.

Referenced by iax2_process_thread().

01379 {
01380    if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01381       AST_LIST_LOCK(&dynamic_list);
01382       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01383       AST_LIST_UNLOCK(&dynamic_list);
01384    } else {
01385       AST_LIST_LOCK(&idle_list);
01386       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01387       AST_LIST_UNLOCK(&idle_list);
01388    }
01389 
01390    return;
01391 }

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

Definition at line 1152 of file chan_iax2.c.

References args, and ast_verbose.

Referenced by handle_cli_iax2_set_debug_jb().

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

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

Definition at line 1128 of file chan_iax2.c.

References args, ast_log(), and LOG_ERROR.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

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

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

Definition at line 1140 of file chan_iax2.c.

References args, ast_log(), and LOG_WARNING.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

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

static int load_module ( void   )  [static]

Load IAX2 module, load configuraiton ---.

Definition at line 14759 of file chan_iax2.c.

References __unload_module(), ao2_callback, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, ast_format_cap_add_all(), ast_format_cap_alloc(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_mutex_init, ast_netsock_init(), ast_netsock_list_alloc(), ast_random(), ast_realtime_require_field(), ast_register_application_xml, ast_register_switch(), ast_sched_context_create(), ast_sched_context_destroy(), ast_sched_start_thread(), AST_TEST_REGISTER, ast_timer_close(), ast_timer_open(), ast_timer_set_rate(), ast_verb, ast_channel_tech::capabilities, config, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax_debug_output(), iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), io_context_create(), io_context_destroy(), jb_error_output(), jb_setoutput(), jb_warning_output(), load_objects(), LOG_ERROR, manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), network_change_event_subscribe(), peer_set_sock_cb(), reload_firmware(), RQ_CHAR, RQ_UINTEGER2, SENTINEL, set_config(), and start_network_thread().

14760 {
14761    static const char config[] = "iax.conf";
14762    int x = 0;
14763    struct iax2_registry *reg = NULL;
14764 
14765    if (!(iax2_tech.capabilities = ast_format_cap_alloc())) {
14766       return AST_MODULE_LOAD_FAILURE;
14767    }
14768    ast_format_cap_add_all(iax2_tech.capabilities);
14769 
14770    if (load_objects()) {
14771       return AST_MODULE_LOAD_FAILURE;
14772    }
14773 
14774    memset(iaxs, 0, sizeof(iaxs));
14775 
14776    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14777       ast_mutex_init(&iaxsl[x]);
14778    }
14779 
14780    if (!(sched = ast_sched_context_create())) {
14781       ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14782       return AST_MODULE_LOAD_FAILURE;
14783    }
14784 
14785    if (ast_sched_start_thread(sched)) {
14786       ast_sched_context_destroy(sched);
14787       sched = NULL;
14788       return AST_MODULE_LOAD_FAILURE;
14789    }
14790 
14791    if (!(io = io_context_create())) {
14792       ast_log(LOG_ERROR, "Failed to create I/O context\n");
14793       ast_sched_context_destroy(sched);
14794       sched = NULL;
14795       return AST_MODULE_LOAD_FAILURE;
14796    }
14797 
14798    if (!(netsock = ast_netsock_list_alloc())) {
14799       ast_log(LOG_ERROR, "Failed to create netsock list\n");
14800       io_context_destroy(io);
14801       ast_sched_context_destroy(sched);
14802       sched = NULL;
14803       return AST_MODULE_LOAD_FAILURE;
14804    }
14805    ast_netsock_init(netsock);
14806    
14807    outsock = ast_netsock_list_alloc();
14808    if (!outsock) {
14809       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14810       io_context_destroy(io);
14811       ast_sched_context_destroy(sched);
14812       sched = NULL;
14813       return AST_MODULE_LOAD_FAILURE;
14814    }
14815    ast_netsock_init(outsock);
14816 
14817    randomcalltokendata = ast_random();
14818 
14819    iax_set_output(iax_debug_output);
14820    iax_set_error(iax_error_output);
14821    jb_setoutput(jb_error_output, jb_warning_output, NULL);
14822    
14823    if ((timer = ast_timer_open())) {
14824       ast_timer_set_rate(timer, trunkfreq);
14825    }
14826 
14827    if (set_config(config, 0) == -1) {
14828       if (timer) {
14829          ast_timer_close(timer);
14830       }
14831       return AST_MODULE_LOAD_DECLINE;
14832    }
14833 
14834 #ifdef TEST_FRAMEWORK
14835    AST_TEST_REGISTER(test_iax2_peers_get);
14836    AST_TEST_REGISTER(test_iax2_users_get);
14837 #endif
14838 
14839    /* Register AstData providers */
14840    ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
14841    ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14842 
14843    ast_register_application_xml(papp, iax2_prov_app);
14844 
14845    ast_custom_function_register(&iaxpeer_function);
14846    ast_custom_function_register(&iaxvar_function);
14847 
14848    ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
14849    ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
14850    ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
14851    ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
14852 
14853    if (ast_channel_register(&iax2_tech)) {
14854       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
14855       __unload_module();
14856       return AST_MODULE_LOAD_FAILURE;
14857    }
14858 
14859    if (ast_register_switch(&iax2_switch)) {
14860       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
14861    }
14862 
14863    if (start_network_thread()) {
14864       ast_log(LOG_ERROR, "Unable to start network thread\n");
14865       __unload_module();
14866       return AST_MODULE_LOAD_FAILURE;
14867    } else {
14868       ast_verb(2, "IAX Ready and Listening\n");
14869    }
14870 
14871    AST_LIST_LOCK(&registrations);
14872    AST_LIST_TRAVERSE(&registrations, reg, entry)
14873       iax2_do_register(reg);
14874    AST_LIST_UNLOCK(&registrations); 
14875    
14876    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
14877    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
14878 
14879 
14880    reload_firmware(0);
14881    iax_provision_reload(0);
14882 
14883    ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
14884 
14885    network_change_event_subscribe();
14886 
14887    return AST_MODULE_LOAD_SUCCESS;
14888 }

static int load_objects ( void   )  [static]

Definition at line 14521 of file chan_iax2.c.

References addr_range_cmp_cb(), addr_range_hash_cb(), ao2_container_alloc, ao2_ref, AST_MODULE_LOAD_FAILURE, ast_taskprocessor_get(), create_callno_pools(), MAX_PEER_BUCKETS, MAX_USER_BUCKETS, peer_cmp_cb(), peer_hash_cb(), peercnt_cmp_cb(), peercnt_hash_cb(), pvt_cmp_cb(), pvt_hash_cb(), TPS_REF_DEFAULT, transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), and user_hash_cb().

Referenced by load_module().

14522 {
14523    peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14524    peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14525 
14526    if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14527       goto container_fail;
14528    } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14529       goto container_fail;
14530    } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14531       goto container_fail;
14532    } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14533       goto container_fail;
14534    } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14535       goto container_fail;
14536    } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14537       goto container_fail;
14538    } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14539       goto container_fail;
14540    } else if (create_callno_pools()) {
14541       goto container_fail;
14542    } else if  (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14543       goto container_fail;
14544    }
14545 
14546    return 0;
14547 
14548 container_fail:
14549    if (peers) {
14550       ao2_ref(peers, -1);
14551    }
14552    if (users) {
14553       ao2_ref(users, -1);
14554    }
14555    if (iax_peercallno_pvts) {
14556       ao2_ref(iax_peercallno_pvts, -1);
14557    }
14558    if (iax_transfercallno_pvts) {
14559       ao2_ref(iax_transfercallno_pvts, -1);
14560    }
14561    if (peercnts) {
14562       ao2_ref(peercnts, -1);
14563    }
14564    if (callno_limits) {
14565       ao2_ref(callno_limits, -1);
14566    }
14567    if (calltoken_ignores) {
14568       ao2_ref(calltoken_ignores, -1);
14569    }
14570    if (callno_pool) {
14571       ao2_ref(callno_pool, -1);
14572    }
14573    if (callno_pool_trunk) {
14574       ao2_ref(callno_pool_trunk, -1);
14575    }
14576    return AST_MODULE_LOAD_FAILURE;
14577 }

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

Definition at line 5517 of file chan_iax2.c.

References ast_mutex_lock, ast_mutex_trylock, and DEADLOCK_AVOIDANCE.

Referenced by iax2_bridge().

05518 {
05519    ast_mutex_lock(&iaxsl[callno0]);
05520    while (ast_mutex_trylock(&iaxsl[callno1])) {
05521       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05522    }
05523 }

static void log_jitterstats ( unsigned short  callno  )  [static]

Definition at line 9546 of file chan_iax2.c.

References ast_channel_name(), ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, jb_info::current, iax_rr::delay, iax_rr::dropped, EVENT_FLAG_REPORTING, jb_info::frames_dropped, jb_info::frames_in, jb_info::frames_lost, jb_info::frames_ooo, IAX_USEJITTERBUF, ast_channel::jb, jb_getinfo(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, manager_event, jb_info::min, iax_rr::ooo, iax_rr::packets, and chan_iax2_pvt::remote_rr.

Referenced by socket_process().

09547 {
09548    int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09549    jb_info jbinfo;
09550 
09551    ast_mutex_lock(&iaxsl[callno]);
09552    if (iaxs[callno] && iaxs[callno]->owner && ast_channel_name(iaxs[callno]->owner)) {
09553       if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09554          jb_getinfo(iaxs[callno]->jb, &jbinfo);
09555          localjitter = jbinfo.jitter;
09556          localdelay = jbinfo.current - jbinfo.min;
09557          locallost = jbinfo.frames_lost;
09558          locallosspct = jbinfo.losspct/1000;
09559          localdropped = jbinfo.frames_dropped;
09560          localooo = jbinfo.frames_ooo;
09561          localpackets = jbinfo.frames_in;
09562       }
09563       ast_debug(3, "JB STATS:%s ping=%d ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n",
09564          ast_channel_name(iaxs[callno]->owner),
09565          iaxs[callno]->pingtime,
09566          localjitter,
09567          localdelay,
09568          locallost,
09569          locallosspct,
09570          localdropped,
09571          localooo,
09572          localpackets,
09573          iaxs[callno]->remote_rr.jitter,
09574          iaxs[callno]->remote_rr.delay,
09575          iaxs[callno]->remote_rr.losscnt,
09576          iaxs[callno]->remote_rr.losspct/1000,
09577          iaxs[callno]->remote_rr.dropped,
09578          iaxs[callno]->remote_rr.ooo,
09579          iaxs[callno]->remote_rr.packets);
09580       manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %d\r\nLocalJitter: %d\r\nLocalJBDelay: %d\r\nLocalTotalLost: %d\r\nLocalLossPercent: %d\r\nLocalDropped: %d\r\nLocalooo: %d\r\nLocalReceived: %d\r\nRemoteJitter: %d\r\nRemoteJBDelay: %d\r\nRemoteTotalLost: %d\r\nRemoteLossPercent: %d\r\nRemoteDropped: %d\r\nRemoteooo: %d\r\nRemoteReceived: %d\r\n",
09581          ast_channel_name(iaxs[callno]->owner),
09582          iaxs[callno]->pingtime,
09583          localjitter,
09584          localdelay,
09585          locallost,
09586          locallosspct,
09587          localdropped,
09588          localooo,
09589          localpackets,
09590          iaxs[callno]->remote_rr.jitter,
09591          iaxs[callno]->remote_rr.delay,
09592          iaxs[callno]->remote_rr.losscnt,
09593          iaxs[callno]->remote_rr.losspct/1000,
09594          iaxs[callno]->remote_rr.dropped,
09595          iaxs[callno]->remote_rr.ooo,
09596          iaxs[callno]->remote_rr.packets);
09597    }
09598    ast_mutex_unlock(&iaxsl[callno]);
09599 }

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

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

Definition at line 2111 of file chan_iax2.c.

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

Referenced by iax2_request(), and socket_process().

02112 {
02113    int x;
02114    int res= 0;
02115    struct callno_entry *callno_entry;
02116    if (iaxs[callno]->oseqno) {
02117       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
02118       return -1;
02119    }
02120    if (callno & TRUNK_CALL_START) {
02121       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
02122       return -1;
02123    }
02124 
02125    if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
02126       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
02127       return -1;
02128    }
02129 
02130    x = callno_entry->callno;
02131    ast_mutex_lock(&iaxsl[x]);
02132 
02133    /*!
02134     * \note We delete these before switching the slot, because if
02135     * they fire in the meantime, they will generate a warning.
02136     */
02137    AST_SCHED_DEL(sched, iaxs[callno]->pingid);
02138    AST_SCHED_DEL(sched, iaxs[callno]->lagid);
02139    iaxs[callno]->lagid = iaxs[callno]->pingid = -1;
02140    iaxs[x] = iaxs[callno];
02141    iaxs[x]->callno = x;
02142 
02143    /* since we copied over the pvt from a different callno, make sure the old entry is replaced
02144     * before assigning the new one */
02145    if (iaxs[x]->callno_entry) {
02146       iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
02147    }
02148    iaxs[x]->callno_entry = callno_entry;
02149 
02150    iaxs[callno] = NULL;
02151    /* Update the two timers that should have been started */
02152    iaxs[x]->pingid = iax2_sched_add(sched, 
02153       ping_time * 1000, send_ping, (void *)(long)x);
02154    iaxs[x]->lagid = iax2_sched_add(sched, 
02155       lagrq_time * 1000, send_lagrq, (void *)(long)x);
02156 
02157    if (locked)
02158       ast_mutex_unlock(&iaxsl[callno]);
02159    res = x;
02160    if (!locked)
02161       ast_mutex_unlock(&iaxsl[x]);
02162 
02163    ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
02164    /* We move this call from a non-trunked to a trunked call */
02165    update_max_trunk();
02166    update_max_nontrunk();
02167    return res;
02168 }

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

Definition at line 7014 of file chan_iax2.c.

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

Referenced by load_module().

07015 {
07016    ast_cli_netstats(s, -1, 0);
07017    astman_append(s, "\r\n");
07018    return RESULT_SUCCESS;
07019 }

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

callback to display iax peers in manager format

Definition at line 7077 of file chan_iax2.c.

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

Referenced by load_module().

07078 {
07079    struct iax2_peer *peer = NULL;
07080    int peer_count = 0;
07081    char nm[20];
07082    char status[20];
07083    const char *id = astman_get_header(m,"ActionID");
07084    char idtext[256] = "";
07085    struct ast_str *encmethods = ast_str_alloca(256);
07086    struct ao2_iterator i;
07087 
07088    if (!ast_strlen_zero(id))
07089       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07090 
07091    astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
07092 
07093 
07094    i = ao2_iterator_init(peers, 0);
07095    for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
07096       encmethods_to_str(peer->encmethods, encmethods);
07097       astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
07098       if (!ast_strlen_zero(peer->username)) {
07099          astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
07100       } else {
07101          astman_append(s, "ObjectName: %s\r\n", peer->name);
07102       }
07103       astman_append(s, "ChanObjectType: peer\r\n");
07104       astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
07105       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
07106       astman_append(s, "Mask: %s\r\n", nm);
07107       astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
07108       astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
07109       astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
07110       astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
07111       peer_status(peer, status, sizeof(status));
07112       astman_append(s, "Status: %s\r\n\r\n", status);
07113       peer_count++;
07114    }
07115    ao2_iterator_destroy(&i);
07116 
07117    astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07118    return RESULT_SUCCESS;
07119 }

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

callback to display iax peers in manager

Definition at line 7053 of file chan_iax2.c.

References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), and total.

Referenced by load_module().

07054 {
07055    static const char * const a[] = { "iax2", "show", "peers" };
07056    const char *id = astman_get_header(m,"ActionID");
07057    char idtext[256] = "";
07058    int total = 0;
07059 
07060    if (!ast_strlen_zero(id))
07061       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07062 
07063    astman_send_listack(s, m, "Peer status list will follow", "start");
07064         /* List the peers in separate manager events */
07065    __iax2_show_peers(-1, &total, s, 3, a);
07066         /* Send final confirmation */
07067         astman_append(s,
07068         "Event: PeerlistComplete\r\n"
07069         "EventList: Complete\r\n"
07070         "ListItems: %d\r\n"
07071         "%s"
07072         "\r\n", total, idtext);
07073         return 0;
07074 }

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

Definition at line 7185 of file chan_iax2.c.

References iax2_registry::addr, ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_stringify(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), iax2_registry::dnsmgr, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), total, iax2_registry::us, and iax2_registry::username.

Referenced by load_module().

07186 {
07187    const char *id = astman_get_header(m, "ActionID");
07188    struct iax2_registry *reg = NULL;
07189    char idtext[256] = "";
07190    char host[80] = "";
07191    char perceived[80] = "";
07192    int total = 0;
07193 
07194    if (!ast_strlen_zero(id))
07195       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07196 
07197    astman_send_listack(s, m, "Registrations will follow", "start");
07198 
07199    AST_LIST_LOCK(&registrations);
07200    AST_LIST_TRAVERSE(&registrations, reg, entry) {
07201       snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
07202       
07203       if (reg->us.sin_addr.s_addr) {
07204          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07205       } else {
07206          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07207       }
07208       
07209       astman_append(s,
07210          "Event: RegistryEntry\r\n"
07211          "%s"
07212          "Host: %s\r\n"
07213          "DNSmanager: %s\r\n"
07214          "Username: %s\r\n"
07215          "Perceived: %s\r\n"
07216          "Refresh: %d\r\n"
07217          "State: %s\r\n"
07218          "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 
07219          reg->refresh, regstate2str(reg->regstate));
07220 
07221       total++;
07222    }
07223    AST_LIST_UNLOCK(&registrations);
07224 
07225    astman_append(s,
07226       "Event: RegistrationsComplete\r\n"
07227       "EventList: Complete\r\n"
07228       "ListItems: %d\r\n"
07229       "%s"
07230       "\r\n", total, idtext);
07231    
07232    return 0;
07233 }

static int match ( struct sockaddr_in *  sin,
unsigned short  callno,
unsigned short  dcallno,
const struct chan_iax2_pvt cur,
int  check_dcallno 
) [static]

Definition at line 2060 of file chan_iax2.c.

References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.

Referenced by __find_callno(), __get_header(), ast_parse_device_state(), ast_srtp_add_stream(), ast_srtp_change_source(), check_blacklist(), find_by_name(), find_command(), handle_updates(), internal_ao2_callback(), lua_find_extension(), misdn_update_redirecting(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), and transfercallno_pvt_cmp_cb().

02061 {
02062    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
02063       (cur->addr.sin_port == sin->sin_port)) {
02064       /* This is the main host */
02065       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
02066           (check_dcallno ? dcallno == cur->callno : 1) ) {
02067          /* That's us.  Be sure we keep track of the peer call number */
02068          return 1;
02069       }
02070    }
02071    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
02072        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
02073       /* We're transferring */
02074       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
02075          return 1;
02076    }
02077    return 0;
02078 }

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

Definition at line 6267 of file chan_iax2.c.

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

Referenced by decode_frame().

06268 {
06269 #if 0
06270    /* Debug with "fake encryption" */
06271    int x;
06272    if (len % 16)
06273       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06274    for (x=0;x<len;x++)
06275       dst[x] = src[x] ^ 0xff;
06276 #else 
06277    unsigned char lastblock[16] = { 0 };
06278    int x;
06279    while(len > 0) {
06280       ast_aes_decrypt(src, dst, dcx);
06281       for (x=0;x<16;x++)
06282          dst[x] ^= lastblock[x];
06283       memcpy(lastblock, src, sizeof(lastblock));
06284       dst += 16;
06285       src += 16;
06286       len -= 16;
06287    }
06288 #endif
06289 }

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

Definition at line 6291 of file chan_iax2.c.

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

Referenced by encrypt_frame().

06292 {
06293 #if 0
06294    /* Debug with "fake encryption" */
06295    int x;
06296    if (len % 16)
06297       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06298    for (x=0;x<len;x++)
06299       dst[x] = src[x] ^ 0xff;
06300 #else
06301    unsigned char curblock[16] = { 0 };
06302    int x;
06303    while(len > 0) {
06304       for (x=0;x<16;x++)
06305          curblock[x] ^= src[x];
06306       ast_aes_encrypt(curblock, dst, ecx);
06307       memcpy(curblock, dst, sizeof(curblock)); 
06308       dst += 16;
06309       src += 16;
06310       len -= 16;
06311    }
06312 #endif
06313 }

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

Definition at line 7854 of file chan_iax2.c.

References chan_iax2_pvt::encmethods, IAX_ENCRYPT_AES128, IAX_ENCRYPT_KEYROTATE, and chan_iax2_pvt::keyrotateid.

Referenced by authenticate_reply(), and socket_process().

07855 {
07856    /* Select exactly one common encryption if there are any */
07857    p->encmethods &= enc;
07858    if (p->encmethods) {
07859       if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */
07860          p->keyrotateid = -2;
07861       }
07862       if (p->encmethods & IAX_ENCRYPT_AES128)
07863          p->encmethods = IAX_ENCRYPT_AES128;
07864       else
07865          p->encmethods = 0;
07866    }
07867 }

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

Definition at line 1275 of file chan_iax2.c.

01276 {
01277    /* The MWI subscriptions exist just so the core knows we care about those
01278     * mailboxes.  However, we just grab the events out of the cache when it
01279     * is time to send MWI, since it is only sent with a REGACK. */
01280 }

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

Definition at line 1310 of file chan_iax2.c.

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

Referenced by network_change_event_subscribe().

01311 {
01312    ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n");
01313    if (network_change_event_sched_id == -1) {
01314       network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
01315    }
01316 
01317 }

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

Definition at line 1297 of file chan_iax2.c.

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

Referenced by network_change_event_cb().

01298 {
01299    struct iax2_registry *reg;
01300    network_change_event_sched_id = -1;
01301    AST_LIST_LOCK(&registrations);
01302    AST_LIST_TRAVERSE(&registrations, reg, entry) {
01303       iax2_do_register(reg);
01304    }
01305    AST_LIST_UNLOCK(&registrations);
01306 
01307    return 0;
01308 }

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

References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), ast_timer_fd(), and timing_read().

Referenced by start_network_thread().

12254 {
12255    if (timer) {
12256       ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12257    }
12258 
12259    for (;;) {
12260       pthread_testcancel();
12261       /* Wake up once a second just in case SIGURG was sent while
12262        * we weren't in poll(), to make sure we don't hang when trying
12263        * to unload. */
12264       ast_io_wait(io, 1000);
12265    }
12266 
12267    return NULL;
12268 }

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

Definition at line 1989 of file chan_iax2.c.

References ao2_alloc, ao2_ref, AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_string_field_set, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::dpentries, exten, chan_iax2_pvt::hold_signaling, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_new(), jb_setconf(), chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, chan_iax2_pvt::pingid, prefs, chan_iax2_pvt::prefs, pvt_destructor(), jb_conf::resync_threshold, chan_iax2_pvt::signaling_queue, and jb_conf::target_extra.

Referenced by __find_callno().

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

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

Parses an IAX dial string into its component parts.

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

References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, strsep(), and parsed_dial_string::username.

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

05038 {
05039    if (ast_strlen_zero(data))
05040       return;
05041 
05042    pds->peer = strsep(&data, "/");
05043    pds->exten = strsep(&data, "/");
05044    pds->options = data;
05045 
05046    if (pds->exten) {
05047       data = pds->exten;
05048       pds->exten = strsep(&data, "@");
05049       pds->context = data;
05050    }
05051 
05052    if (strchr(pds->peer, '@')) {
05053       data = pds->peer;
05054       pds->username = strsep(&data, "@");
05055       pds->peer = data;
05056    }
05057 
05058    if (pds->username) {
05059       data = pds->username;
05060       pds->username = strsep(&data, ":");
05061       pds->password = data;
05062    }
05063 
05064    data = pds->peer;
05065    pds->peer = strsep(&data, ":");
05066    pds->port = data;
05067 
05068    /* check for a key name wrapped in [] in the secret position, if found,
05069       move it to the key field instead
05070    */
05071    if (pds->password && (pds->password[0] == '[')) {
05072       pds->key = ast_strip_quoted(pds->password, "[", "]");
05073       pds->password = NULL;
05074    }
05075 }

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

Note:
The only member of the peer passed here guaranteed to be set is the name field

Definition at line 1737 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, iax2_peer::name, name, and OBJ_KEY.

Referenced by load_module(), and load_objects().

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

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

Definition at line 12996 of file chan_iax2.c.

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

12997 {
12998    struct iax2_peer *peer = obj;
12999 
13000    ast_set_flag64(peer, IAX_DELME);
13001 
13002    return 0;
13003 }

static void peer_destructor ( void *  obj  )  [static]

Definition at line 12430 of file chan_iax2.c.

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

Referenced by build_peer().

12431 {
12432    struct iax2_peer *peer = obj;
12433    int callno = peer->callno;
12434 
12435    ast_free_ha(peer->ha);
12436 
12437    if (callno > 0) {
12438       ast_mutex_lock(&iaxsl[callno]);
12439       iax2_destroy(callno);
12440       ast_mutex_unlock(&iaxsl[callno]);
12441    }
12442 
12443    register_peer_exten(peer, 0);
12444 
12445    if (peer->dnsmgr)
12446       ast_dnsmgr_release(peer->dnsmgr);
12447 
12448    if (peer->mwi_event_sub)
12449       ast_event_unsubscribe(peer->mwi_event_sub);
12450 
12451    ast_string_field_free_memory(peer);
12452 }

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

Note:
The only member of the peer passed here guaranteed to be set is the name field

Definition at line 1726 of file chan_iax2.c.

References ast_str_hash(), iax2_peer::name, name, and OBJ_KEY.

Referenced by load_module(), and load_objects().

01727 {
01728    const struct iax2_peer *peer = obj;
01729    const char *name = obj;
01730 
01731    return ast_str_hash(flags & OBJ_KEY ? name : peer->name);
01732 }

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

Definition at line 1786 of file chan_iax2.c.

References ao2_ref.

Referenced by __iax2_poke_noanswer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), iax2_poke_peer(), realtime_peer(), reg_source_db(), socket_process(), and update_registry().

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

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

Definition at line 14475 of file chan_iax2.c.

References iax2_peer::sockfd.

Referenced by load_module().

14476 {
14477    struct iax2_peer *peer = obj;
14478 
14479    if (peer->sockfd < 0)
14480       peer->sockfd = defaultsockfd;
14481 
14482    return 0;
14483 }

static int peer_set_srcaddr ( struct iax2_peer peer,
const char *  srcaddr 
) [static]

Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found.

Definition at line 12355 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_debug, ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_sockaddr_to_sin, ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, LOG_WARNING, iax2_peer::name, qos, socket_read(), iax2_peer::sockfd, iax2_trunk_peer::sockfd, ast_sockaddr::ss, and strsep().

Referenced by build_peer().

12356 {
12357    struct sockaddr_in sin;
12358    struct ast_sockaddr sin_tmp;
12359    int nonlocal = 1;
12360    int port = IAX_DEFAULT_PORTNO;
12361    int sockfd = defaultsockfd;
12362    char *tmp;
12363    char *addr;
12364    char *portstr;
12365 
12366    if (!(tmp = ast_strdupa(srcaddr)))
12367       return -1;
12368 
12369    addr = strsep(&tmp, ":");
12370    portstr = tmp;
12371 
12372    if (portstr) {
12373       port = atoi(portstr);
12374       if (port < 1)
12375          port = IAX_DEFAULT_PORTNO;
12376    }
12377 
12378    sin_tmp.ss.ss_family = AF_INET;
12379    if (!ast_get_ip(&sin_tmp, addr)) {
12380       struct ast_netsock *sock;
12381       int res;
12382 
12383       ast_sockaddr_to_sin(&sin_tmp, &sin);
12384       sin.sin_port = 0;
12385       sin.sin_family = AF_INET;
12386       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12387       if (res == 0) {
12388          /* ip address valid. */
12389          sin.sin_port = htons(port);
12390          if (!(sock = ast_netsock_find(netsock, &sin)))
12391             sock = ast_netsock_find(outsock, &sin);
12392          if (sock) {
12393             sockfd = ast_netsock_sockfd(sock);
12394             nonlocal = 0;
12395          } else {
12396             unsigned int orig_saddr = sin.sin_addr.s_addr;
12397             /* INADDR_ANY matches anyway! */
12398             sin.sin_addr.s_addr = INADDR_ANY;
12399             if (ast_netsock_find(netsock, &sin)) {
12400                sin.sin_addr.s_addr = orig_saddr;
12401                sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12402                if (sock) {
12403                   sockfd = ast_netsock_sockfd(sock);
12404                   ast_netsock_unref(sock);
12405                   nonlocal = 0;
12406                } else {
12407                   nonlocal = 2;
12408                }
12409             }
12410          }
12411       }
12412    }
12413 
12414    peer->sockfd = sockfd;
12415 
12416    if (nonlocal == 1) {
12417       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12418          srcaddr, peer->name);
12419       return -1;
12420         } else if (nonlocal == 2) {
12421       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12422          srcaddr, peer->name);
12423          return -1;
12424    } else {
12425       ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12426       return 0;
12427    }
12428 }

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

peer_status: Report Peer status in character string

Definition at line 3779 of file chan_iax2.c.

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

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

03780 {
03781    int res = 0;
03782    if (peer->maxms) {
03783       if (peer->lastms < 0) {
03784          ast_copy_string(status, "UNREACHABLE", statuslen);
03785       } else if (peer->lastms > peer->maxms) {
03786          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03787          res = 1;
03788       } else if (peer->lastms) {
03789          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03790          res = 1;
03791       } else {
03792          ast_copy_string(status, "UNKNOWN", statuslen);
03793       }
03794    } else { 
03795       ast_copy_string(status, "Unmonitored", statuslen);
03796       res = -1;
03797    }
03798    return res;
03799 }

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

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

Definition at line 2408 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

02409 {
02410    struct peercnt *peercnt;
02411    unsigned long addr = sin->sin_addr.s_addr;
02412    int res = 0;
02413    struct peercnt tmp = {
02414       .addr = addr,
02415    };
02416 
02417    /* Reasoning for peercnts container lock:  Two identical ip addresses
02418     * could be added by different threads at the "same time". Without the container
02419     * lock, both threads could alloc space for the same object and attempt
02420     * to link to table.  With the lock, one would create the object and link
02421     * to table while the other would find the already created peercnt object
02422     * rather than creating a new one. */
02423    ao2_lock(peercnts);
02424    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02425       ao2_lock(peercnt);
02426    } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02427       ao2_lock(peercnt);
02428       /* create and set defaults */
02429       peercnt->addr = addr;
02430       set_peercnt_limit(peercnt);
02431       /* guarantees it does not go away after unlocking table
02432        * ao2_find automatically adds this */
02433       ao2_link(peercnts, peercnt);
02434    } else {
02435       ao2_unlock(peercnts);
02436       return -1;
02437    }
02438 
02439    /* check to see if the address has hit its callno limit.  If not increment cur. */
02440    if (peercnt->limit > peercnt->cur) {
02441       peercnt->cur++;
02442       ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02443    } else { /* max num call numbers for this peer has been reached! */
02444       ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02445       res = -1;
02446    }
02447 
02448    /* clean up locks and ref count */
02449    ao2_unlock(peercnt);
02450    ao2_unlock(peercnts);
02451    ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */
02452 
02453    return res;
02454 }

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

Definition at line 2238 of file chan_iax2.c.

References peercnt::addr, CMP_MATCH, and CMP_STOP.

Referenced by load_objects().

02239 {
02240    struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02241    return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02242 }

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

Definition at line 2232 of file chan_iax2.c.

References peercnt::addr.

Referenced by load_objects().

02233 {
02234    const struct peercnt *peercnt = obj;
02235    return abs((int) peercnt->addr);
02236 }

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

Definition at line 2375 of file chan_iax2.c.

References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), ast_sockaddr_to_sin, peercnt::limit, OBJ_POINTER, peercnt::reg, and set_peercnt_limit().

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

02376 {
02377    /* this function turns off and on custom callno limits set by peer registration */
02378    struct peercnt *peercnt;
02379    struct peercnt tmp = {
02380       .addr = 0,
02381    };
02382    struct sockaddr_in sin;
02383 
02384    ast_sockaddr_to_sin(sockaddr, &sin);
02385 
02386    tmp.addr = sin.sin_addr.s_addr;
02387 
02388    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02389       peercnt->reg = reg;
02390       if (limit) {
02391          peercnt->limit = limit;
02392       } else {
02393          set_peercnt_limit(peercnt);
02394       }
02395       ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg);
02396       ao2_ref(peercnt, -1); /* decrement ref from find */
02397    }
02398 }

static void peercnt_remove ( struct peercnt peercnt  )  [static]

Definition at line 2460 of file chan_iax2.c.

References peercnt::addr, ao2_lock, ao2_unlink, ao2_unlock, ast_debug, ast_inet_ntoa(), and peercnt::cur.

Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().

02461 {
02462    struct sockaddr_in sin = {
02463       .sin_addr.s_addr = peercnt->addr,
02464    };
02465 
02466    if (peercnt) {
02467       /* Container locked here since peercnt may be unlinked from list.  If left unlocked,
02468        * peercnt_add could try and grab this entry from the table and modify it at the
02469        * "same time" this thread attemps to unlink it.*/
02470       ao2_lock(peercnts);
02471       peercnt->cur--;
02472       ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02473       /* if this was the last connection from the peer remove it from table */
02474       if (peercnt->cur == 0) {
02475          ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */
02476       }
02477       ao2_unlock(peercnts);
02478    }
02479 }

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

Definition at line 2499 of file chan_iax2.c.

References peercnt::addr, ao2_find, ao2_ref, OBJ_POINTER, and peercnt_remove().

Referenced by __find_callno(), and complete_transfer().

02500 {
02501    struct peercnt *peercnt;
02502    struct peercnt tmp = {
02503       .addr = sin->sin_addr.s_addr,
02504    };
02505 
02506    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02507       peercnt_remove(peercnt);
02508       ao2_ref(peercnt, -1); /* decrement ref from find */
02509    }
02510    return 0;
02511 }

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

Definition at line 2485 of file chan_iax2.c.

References ao2_ref, and peercnt_remove().

Referenced by sched_delay_remove().

02486 {
02487    struct peercnt *peercnt = (struct peercnt *) obj;
02488 
02489    peercnt_remove(peercnt);
02490    ao2_ref(peercnt, -1); /* decrement ref from scheduler */
02491 
02492    return 0;
02493 }

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

Definition at line 14609 of file chan_iax2.c.

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

14611 {
14612    struct ast_data *data_peer;
14613    struct iax2_peer *peer;
14614    struct ao2_iterator i;
14615    char status[20];
14616    struct ast_str *encmethods = ast_str_alloca(256);
14617 
14618    i = ao2_iterator_init(peers, 0);
14619    while ((peer = ao2_iterator_next(&i))) {
14620       data_peer = ast_data_add_node(data_root, "peer");
14621       if (!data_peer) {
14622          peer_unref(peer);
14623          continue;
14624       }
14625 
14626       ast_data_add_structure(iax2_peer, data_peer, peer);
14627 
14628       iax2_data_add_codecs(data_peer, "codecs", peer->capability);
14629 
14630       peer_status(peer, status, sizeof(status));
14631       ast_data_add_str(data_peer, "status", status);
14632 
14633       ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14634 
14635       ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14636 
14637       ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14638 
14639       ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14640 
14641       ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14642 
14643       encmethods_to_str(peer->encmethods, encmethods);
14644       ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14645 
14646       peer_unref(peer);
14647 
14648       if (!ast_data_search_match(search, data_peer)) {
14649          ast_data_remove_node(data_root, data_peer);
14650       }
14651    }
14652    ao2_iterator_destroy(&i);
14653 
14654    return 0;
14655 }

static void poke_all_peers ( void   )  [static]

Definition at line 13562 of file chan_iax2.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, iax2_poke_peer(), and peer_unref().

Referenced by reload_config().

13563 {
13564    struct ao2_iterator i;
13565    struct iax2_peer *peer;
13566 
13567    i = ao2_iterator_init(peers, 0);
13568    while ((peer = ao2_iterator_next(&i))) {
13569       iax2_poke_peer(peer, 0);
13570       peer_unref(peer);
13571    }
13572    ao2_iterator_destroy(&i);
13573 }

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

Definition at line 2364 of file chan_iax2.c.

References CMP_MATCH, and addr_range::delme.

Referenced by reload_config().

02365 {
02366    struct addr_range *addr_range = obj;
02367 
02368    return addr_range->delme ? CMP_MATCH : 0;
02369 }

static void prune_peers ( void   )  [static]

Definition at line 13059 of file chan_iax2.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_test_flag64, IAX_DELME, IAX_RTCACHEFRIENDS, peer_unref(), and unlink_peer().

13060 {
13061    struct iax2_peer *peer;
13062    struct ao2_iterator i;
13063 
13064    i = ao2_iterator_init(peers, 0);
13065    while ((peer = ao2_iterator_next(&i))) {
13066       if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
13067          unlink_peer(peer);
13068       }
13069       peer_unref(peer);
13070    }
13071    ao2_iterator_destroy(&i);
13072 }

static void prune_users ( void   )  [static]

Definition at line 13043 of file chan_iax2.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_unlink, ast_test_flag64, IAX_DELME, IAX_RTCACHEFRIENDS, and user_unref().

Referenced by handle_cli_iax2_prune_realtime(), and reload_config().

13044 {
13045    struct iax2_user *user;
13046    struct ao2_iterator i;
13047 
13048    i = ao2_iterator_init(users, 0);
13049    while ((user = ao2_iterator_next(&i))) {
13050       if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
13051          ao2_unlink(users, user);
13052       }
13053       user_unref(user);
13054    }
13055    ao2_iterator_destroy(&i);
13056 }

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

Definition at line 14492 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().

14493 {
14494    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14495 
14496    /* The frames_received field is used to hold whether we're matching
14497     * against a full frame or not ... */
14498 
14499    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
14500       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14501 }

static void pvt_destructor ( void *  obj  )  [static]

Definition at line 1942 of file chan_iax2.c.

References chan_iax2_pvt::addr, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, jb_frame::data, frame_queue, free_signaling_queue_entry(), iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, sched_delay_remove(), chan_iax2_pvt::signaling_queue, and chan_iax2_pvt::vars.

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

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

Definition at line 14485 of file chan_iax2.c.

References chan_iax2_pvt::peercallno.

14486 {
14487    const struct chan_iax2_pvt *pvt = obj;
14488 
14489    return pvt->peercallno;
14490 }

static int queue_signalling ( struct chan_iax2_pvt pvt,
struct ast_frame f 
) [static]

All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.

Definition at line 1918 of file chan_iax2.c.

References ast_calloc, AST_FRAME_IAX, AST_LIST_INSERT_TAIL, ast_frame::data, ast_frame::frametype, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, ast_frame::ptr, and chan_iax2_pvt::signaling_queue.

Referenced by __send_command().

01919 {
01920    struct signaling_queue_entry *new;
01921 
01922    if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01923       return 1; /* do not queue this frame */
01924    } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01925       return -1;  /* out of memory */
01926    }
01927 
01928    memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */
01929 
01930    if (new->f.datalen) { /* if there is data in this frame copy it over as well */
01931       if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
01932          free_signaling_queue_entry(new);
01933          return -1;
01934       }
01935       memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
01936    }
01937    AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
01938 
01939    return 0;
01940 }

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

Definition at line 7838 of file chan_iax2.c.

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

Referenced by socket_process().

07839 {
07840    struct ast_iax2_full_hdr fh;
07841    fh.scallno = htons(src | IAX_FLAG_FULL);
07842    fh.dcallno = htons(dst);
07843    fh.ts = 0;
07844    fh.oseqno = 0;
07845    fh.iseqno = 0;
07846    fh.type = AST_FRAME_IAX;
07847    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07848    iax_outputframe(NULL, &fh, 0, sin, 0);
07849    ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07850       ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07851    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07852 }

static struct iax2_peer * realtime_peer ( const char *  peername,
struct sockaddr_in *  sin 
) [static, read]

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

References iax2_peer::addr, ao2_link, ast_copy_flags64, ast_debug, ast_get_time_t(), ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), AST_SCHED_DEL, ast_set_flag64, ast_sockaddr_parse(), ast_sockaddr_set_port, ast_test_flag64, ast_variables_destroy(), build_peer(), iax2_peer::expire, expire_registry(), hp, iax2_sched_add(), IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, iax2_peer::name, ast_variable::name, ast_variable::next, PARSE_PORT_IGNORE, peer_ref(), peer_unref(), realtime_update_peer(), reg_source_db(), SENTINEL, ast_variable::value, and var.

04386 {
04387    struct ast_variable *var = NULL;
04388    struct ast_variable *tmp;
04389    struct iax2_peer *peer=NULL;
04390    time_t regseconds = 0, nowtime;
04391    int dynamic=0;
04392 
04393    if (peername) {
04394       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04395       if (!var && sin)
04396          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04397    } else if (sin) {
04398       char porta[25];
04399       sprintf(porta, "%d", ntohs(sin->sin_port));
04400       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04401       if (var) {
04402          /* We'll need the peer name in order to build the structure! */
04403          for (tmp = var; tmp; tmp = tmp->next) {
04404             if (!strcasecmp(tmp->name, "name"))
04405                peername = tmp->value;
04406          }
04407       }
04408    }
04409    if (!var && peername) { /* Last ditch effort */
04410       var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04411       /*!\note
04412        * If this one loaded something, then we need to ensure that the host
04413        * field matched.  The only reason why we can't have this as a criteria
04414        * is because we only have the IP address and the host field might be
04415        * set as a name (and the reverse PTR might not match).
04416        */
04417       if (var && sin) {
04418          for (tmp = var; tmp; tmp = tmp->next) {
04419             if (!strcasecmp(tmp->name, "host")) {
04420                struct ast_hostent ahp;
04421                struct hostent *hp;
04422                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04423                   /* No match */
04424                   ast_variables_destroy(var);
04425                   var = NULL;
04426                }
04427                break;
04428             }
04429          }
04430       }
04431    }
04432    if (!var)
04433       return NULL;
04434 
04435    peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04436 
04437    if (!peer) {
04438       ast_variables_destroy(var);
04439       return NULL;
04440    }
04441 
04442    for (tmp = var; tmp; tmp = tmp->next) {
04443       /* Make sure it's not a user only... */
04444       if (!strcasecmp(tmp->name, "type")) {
04445          if (strcasecmp(tmp->value, "friend") &&
04446              strcasecmp(tmp->value, "peer")) {
04447             /* Whoops, we weren't supposed to exist! */
04448             peer = peer_unref(peer);
04449             break;
04450          } 
04451       } else if (!strcasecmp(tmp->name, "regseconds")) {
04452          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
04453       } else if (!strcasecmp(tmp->name, "ipaddr")) {
04454          ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE);
04455       } else if (!strcasecmp(tmp->name, "port")) {
04456          ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
04457       } else if (!strcasecmp(tmp->name, "host")) {
04458          if (!strcasecmp(tmp->value, "dynamic"))
04459             dynamic = 1;
04460       }
04461    }
04462 
04463    ast_variables_destroy(var);
04464 
04465    if (!peer)
04466       return NULL;
04467 
04468    if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04469       ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04470       if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
04471          if (peer->expire > -1) {
04472             if (!AST_SCHED_DEL(sched, peer->expire)) {
04473                peer->expire = -1;
04474                peer_unref(peer);
04475             }
04476          }
04477          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04478          if (peer->expire == -1)
04479             peer_unref(peer);
04480       }
04481       ao2_link(peers, peer);
04482       if (ast_test_flag64(peer, IAX_DYNAMIC))
04483          reg_source_db(peer);
04484    } else {
04485       ast_set_flag64(peer, IAX_TEMPONLY);
04486    }
04487 
04488    if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04489       time(&nowtime);
04490       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04491          memset(&peer->addr, 0, sizeof(peer->addr));
04492          realtime_update_peer(peer->name, &peer->addr, 0);
04493          ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04494             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04495       }
04496       else {
04497          ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04498             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04499       }
04500    }
04501 
04502    return peer;
04503 }

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

Definition at line 4576 of file chan_iax2.c.

References ast_config_AST_SYSTEM_NAME, ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_test_flag64, ast_update_realtime(), IAX_RTSAVE_SYSNAME, and SENTINEL.

Referenced by __expire_registry(), realtime_peer(), update_peer(), and update_registry().

04577 {
04578    char port[10];
04579    char regseconds[20];
04580    const char *sysname = ast_config_AST_SYSTEM_NAME;
04581    char *syslabel = NULL;
04582 
04583    if (ast_strlen_zero(sysname)) /* No system name, disable this */
04584       sysname = NULL;
04585    else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME))
04586       syslabel = "regserver";
04587 
04588    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04589    snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
04590    ast_update_realtime("iaxpeers", "name", peername, 
04591       "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 
04592       "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */
04593 }

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

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

References ao2_link, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_set_flag64, ast_test_flag64, ast_variables_destroy(), build_user(), hp, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.

04506 {
04507    struct ast_variable *var;
04508    struct ast_variable *tmp;
04509    struct iax2_user *user=NULL;
04510 
04511    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04512    if (!var)
04513       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04514    if (!var && sin) {
04515       char porta[6];
04516       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04517       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04518       if (!var)
04519          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04520    }
04521    if (!var) { /* Last ditch effort */
04522       var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04523       /*!\note
04524        * If this one loaded something, then we need to ensure that the host
04525        * field matched.  The only reason why we can't have this as a criteria
04526        * is because we only have the IP address and the host field might be
04527        * set as a name (and the reverse PTR might not match).
04528        */
04529       if (var) {
04530          for (tmp = var; tmp; tmp = tmp->next) {
04531             if (!strcasecmp(tmp->name, "host")) {
04532                struct ast_hostent ahp;
04533                struct hostent *hp;
04534                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04535                   /* No match */
04536                   ast_variables_destroy(var);
04537                   var = NULL;
04538                }
04539                break;
04540             }
04541          }
04542       }
04543    }
04544    if (!var)
04545       return NULL;
04546 
04547    tmp = var;
04548    while(tmp) {
04549       /* Make sure it's not a peer only... */
04550       if (!strcasecmp(tmp->name, "type")) {
04551          if (strcasecmp(tmp->value, "friend") &&
04552              strcasecmp(tmp->value, "user")) {
04553             return NULL;
04554          } 
04555       }
04556       tmp = tmp->next;
04557    }
04558 
04559    user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS));
04560 
04561    ast_variables_destroy(var);
04562 
04563    if (!user)
04564       return NULL;
04565 
04566    if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04567       ast_set_flag64(user, IAX_RTCACHEFRIENDS);
04568       ao2_link(users, user);
04569    } else {
04570       ast_set_flag64(user, IAX_TEMPONLY);
04571    }
04572 
04573    return user;
04574 }

static void reg_source_db ( struct iax2_peer p  )  [static]

Definition at line 8720 of file chan_iax2.c.

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

Referenced by build_peer(), realtime_peer(), set_config(), and temp_peer().

08721 {
08722    char data[80];
08723    char *expiry;
08724 
08725    if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08726       return;
08727    }
08728 
08729    expiry = strrchr(data, ':');
08730    if (!expiry) {
08731       ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08732    }
08733    *expiry++ = '\0';
08734 
08735    if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08736       ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08737       return;
08738    }
08739 
08740    p->expiry = atoi(expiry);
08741 
08742    ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08743       ast_sockaddr_stringify(&p->addr), p->expiry);
08744 
08745    iax2_poke_peer(p, 0);
08746    if (p->expire > -1) {
08747       if (!AST_SCHED_DEL(sched, p->expire)) {
08748          p->expire = -1;
08749          peer_unref(p);
08750       }
08751    }
08752 
08753    ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
08754 
08755    p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08756    if (p->expire == -1) {
08757       peer_unref(p);
08758    }
08759 
08760    if (iax2_regfunk) {
08761       iax2_regfunk(p->name, 1);
08762    }
08763 
08764    register_peer_exten(p, 1);
08765 }

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

Definition at line 8635 of file chan_iax2.c.

References ast_add_extension(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_strdup, ast_strlen_zero(), ext, iax2_peer::name, iax2_peer::regexten, S_OR, and strsep().

Referenced by __expire_registry(), expire_register(), handle_response_peerpoke(), parse_register_contact(), peer_destructor(), reg_source_db(), sip_destroy_peer(), sip_poke_noanswer(), and update_registry().

08636 {
08637    char multi[256];
08638    char *stringp, *ext;
08639    if (!ast_strlen_zero(regcontext)) {
08640       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08641       stringp = multi;
08642       while((ext = strsep(&stringp, "&"))) {
08643          if (onoff) {
08644             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08645                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08646                        "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08647          } else
08648             ast_context_remove_extension(regcontext, ext, 1, NULL);
08649       }
08650    }
08651 }

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

Verify inbound registration.

Definition at line 8005 of file chan_iax2.c.

References ast_apply_ha(), ast_check_signature(), ast_clear_flag, ast_copy_string(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_inet_ntoa(), ast_key_get(), AST_KEY_PUBLIC, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_sockaddr_from_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, iax2_peer::authmethods, chan_iax2_pvt::expiry, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, iax2_peer::inkeys, LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax_ies::password, peer_unref(), iax_ies::refresh, iax_ies::rsa_result, iax2_peer::secret, secret, strsep(), and iax_ies::username.

Referenced by handle_request_register(), and socket_process().

08006 {
08007    char requeststr[256] = "";
08008    char peer[256] = "";
08009    char md5secret[256] = "";
08010    char rsasecret[256] = "";
08011    char secret[256] = "";
08012    struct iax2_peer *p = NULL;
08013    struct ast_key *key;
08014    char *keyn;
08015    int x;
08016    int expire = 0;
08017    int res = -1;
08018    struct ast_sockaddr addr;
08019 
08020    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08021    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
08022    if (ies->username)
08023       ast_copy_string(peer, ies->username, sizeof(peer));
08024    if (ies->password)
08025       ast_copy_string(secret, ies->password, sizeof(secret));
08026    if (ies->md5_result)
08027       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
08028    if (ies->rsa_result)
08029       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
08030    if (ies->refresh)
08031       expire = ies->refresh;
08032 
08033    if (ast_strlen_zero(peer)) {
08034       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
08035       return -1;
08036    }
08037 
08038    /* SLD: first call to lookup peer during registration */
08039    ast_mutex_unlock(&iaxsl[callno]);
08040    p = find_peer(peer, 1);
08041    ast_mutex_lock(&iaxsl[callno]);
08042    if (!p || !iaxs[callno]) {
08043       if (iaxs[callno]) {
08044          int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
08045          /* Anything, as long as it's non-blank */
08046          ast_string_field_set(iaxs[callno], secret, "badsecret");
08047          /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
08048           * 1. A challenge already exists indicating a AUTHREQ was already sent out.
08049           * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
08050           * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
08051           *    to be plaintext, indicating it is an authmethod used by other peers on the system. 
08052           *
08053           * If none of these cases exist, res will be returned as 0 without authentication indicating
08054           * an AUTHREQ needs to be sent out. */
08055 
08056          if (ast_strlen_zero(iaxs[callno]->challenge) &&
08057             !(!ast_strlen_zero(secret) && plaintext)) {
08058             /* by setting res to 0, an REGAUTH will be sent */
08059             res = 0;
08060          }
08061       }
08062       if (authdebug && !p)
08063          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08064       goto return_unref;
08065    }
08066 
08067    if (!ast_test_flag64(p, IAX_DYNAMIC)) {
08068       if (authdebug)
08069          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08070       goto return_unref;
08071    }
08072 
08073    ast_sockaddr_from_sin(&addr, sin);
08074    if (!ast_apply_ha(p->ha, &addr)) {
08075       if (authdebug)
08076          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08077       goto return_unref;
08078    }
08079    ast_string_field_set(iaxs[callno], secret, p->secret);
08080    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
08081    /* Check secret against what we have on file */
08082    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08083       if (!ast_strlen_zero(p->inkeys)) {
08084          char tmpkeys[256];
08085          char *stringp=NULL;
08086          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
08087          stringp=tmpkeys;
08088          keyn = strsep(&stringp, ":");
08089          while(keyn) {
08090             key = ast_key_get(keyn, AST_KEY_PUBLIC);
08091             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
08092                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08093                break;
08094             } else if (!key)
08095                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
08096             keyn = strsep(&stringp, ":");
08097          }
08098          if (!keyn) {
08099             if (authdebug)
08100                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
08101             goto return_unref;
08102          }
08103       } else {
08104          if (authdebug)
08105             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
08106          goto return_unref;
08107       }
08108    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08109       struct MD5Context md5;
08110       unsigned char digest[16];
08111       char *tmppw, *stringp;
08112 
08113       tmppw = ast_strdupa(p->secret);
08114       stringp = tmppw;
08115       while((tmppw = strsep(&stringp, ";"))) {
08116          MD5Init(&md5);
08117          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
08118          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08119          MD5Final(digest, &md5);
08120          for (x=0;x<16;x++)
08121             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
08122          if (!strcasecmp(requeststr, md5secret))
08123             break;
08124       }
08125       if (tmppw) {
08126          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08127       } else {
08128          if (authdebug)
08129             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
08130          goto return_unref;
08131       }
08132    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
08133       /* They've provided a plain text password and we support that */
08134       if (strcmp(secret, p->secret)) {
08135          if (authdebug)
08136             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08137          goto return_unref;
08138       } else
08139          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08140    } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
08141       /* if challenge has been sent, but no challenge response if given, reject. */
08142       goto return_unref;
08143    }
08144    ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
08145 
08146    /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
08147    res = 0;
08148 
08149 return_unref:
08150    if (iaxs[callno]) {
08151       ast_string_field_set(iaxs[callno], peer, peer);
08152 
08153       /* Choose lowest expiry number */
08154       if (expire && (expire < iaxs[callno]->expiry)) {
08155          iaxs[callno]->expiry = expire;
08156       }
08157    }
08158 
08159    if (p) {
08160       peer_unref(p);
08161    }
08162    return res;
08163 }

static int registry_authrequest ( int  callno  )  [static]

Definition at line 8941 of file chan_iax2.c.

References AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::authmethods, iax2_peer::authmethods, iax_ie_data::buf, find_peer(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, peer_unref(), iax_ie_data::pos, and send_command().

Referenced by socket_process().

08942 {
08943    struct iax_ie_data ied;
08944    struct iax2_peer *p;
08945    char challenge[10];
08946    const char *peer_name;
08947    int sentauthmethod;
08948 
08949    peer_name = ast_strdupa(iaxs[callno]->peer);
08950 
08951    /* SLD: third call to find_peer in registration */
08952    ast_mutex_unlock(&iaxsl[callno]);
08953    if ((p = find_peer(peer_name, 1))) {
08954       last_authmethod = p->authmethods;
08955    }
08956 
08957    ast_mutex_lock(&iaxsl[callno]);
08958    if (!iaxs[callno])
08959       goto return_unref;
08960 
08961    memset(&ied, 0, sizeof(ied));
08962    /* The selection of which delayed reject is sent may leak information,
08963     * if it sets a static response.  For example, if a host is known to only
08964     * use MD5 authentication, then an RSA response would indicate that the
08965     * peer does not exist, and vice-versa.
08966     * Therefore, we use whatever the last peer used (which may vary over the
08967     * course of a server, which should leak minimal information). */
08968    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08969    if (!p) {
08970       iaxs[callno]->authmethods = sentauthmethod;
08971    }
08972    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08973    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08974       /* Build the challenge */
08975       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08976       ast_string_field_set(iaxs[callno], challenge, challenge);
08977       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08978    }
08979    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08980 
08981 return_unref:
08982    if (p) {
08983       peer_unref(p);
08984    }
08985 
08986    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08987 }

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

Definition at line 8989 of file chan_iax2.c.

References add_empty_calltoken_ie(), iax2_registry::addr, ast_copy_string(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_sockaddr_to_sin, ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax_ie_data::buf, iax_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, REG_STATE_NOAUTH, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.

Referenced by socket_process().

08990 {
08991    struct iax2_registry *reg;
08992    /* Start pessimistic */
08993    struct iax_ie_data ied;
08994    char peer[256] = "";
08995    char challenge[256] = "";
08996    int res;
08997    int authmethods = 0;
08998    if (ies->authmethods)
08999       authmethods = ies->authmethods;
09000    if (ies->username)
09001       ast_copy_string(peer, ies->username, sizeof(peer));
09002    if (ies->challenge)
09003       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
09004    memset(&ied, 0, sizeof(ied));
09005    reg = iaxs[callno]->reg;
09006    if (reg) {
09007       struct sockaddr_in reg_addr;
09008 
09009       ast_sockaddr_to_sin(&reg->addr, &reg_addr);
09010 
09011       if (inaddrcmp(&reg_addr, sin)) {
09012          ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
09013          return -1;
09014       }
09015       if (ast_strlen_zero(reg->secret)) {
09016          ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
09017          reg->regstate = REG_STATE_NOAUTH;
09018          return -1;
09019       }
09020       iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
09021       iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
09022       if (reg->secret[0] == '[') {
09023          char tmpkey[256];
09024          ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
09025          tmpkey[strlen(tmpkey) - 1] = '\0';
09026          res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
09027       } else
09028          res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
09029       if (!res) {
09030          reg->regstate = REG_STATE_AUTHSENT;
09031          add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
09032          return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
09033       } else
09034          return -1;
09035       ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
09036    } else   
09037       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
09038    return -1;
09039 }

static char* regstate2str ( int  regstate  )  [static]

Definition at line 7122 of file chan_iax2.c.

References REG_STATE_AUTHSENT, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.

Referenced by handle_cli_iax2_show_registry(), handle_response_register(), manager_iax2_show_registry(), manager_show_registry(), sip_reg_timeout(), and sip_show_registry().

07123 {
07124    switch(regstate) {
07125    case REG_STATE_UNREGISTERED:
07126       return "Unregistered";
07127    case REG_STATE_REGSENT:
07128       return "Request Sent";
07129    case REG_STATE_AUTHSENT:
07130       return "Auth. Sent";
07131    case REG_STATE_REGISTERED:
07132       return "Registered";
07133    case REG_STATE_REJECTED:
07134       return "Rejected";
07135    case REG_STATE_TIMEOUT:
07136       return "Timeout";
07137    case REG_STATE_NOAUTH:
07138       return "No Authentication";
07139    default:
07140       return "Unknown";
07141    }
07142 }

static int reload ( void   )  [static]

Definition at line 13623 of file chan_iax2.c.

References reload_config().

13624 {
13625    return reload_config();
13626 }

static int reload_config ( void   )  [static]

Definition at line 13574 of file chan_iax2.c.

References ao2_callback, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_unload_realtime(), config, debugaddr, iax2_do_register(), iax_provision_reload(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, poke_all_peers(), prune_addr_range_cb(), prune_peers(), prune_users(), reload_firmware(), set_config(), and set_peercnt_limit_all_cb().

13575 {
13576    static const char config[] = "iax.conf";
13577    struct iax2_registry *reg;
13578 
13579    if (set_config(config, 1) > 0) {
13580       prune_peers();
13581       prune_users();
13582       ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13583       ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13584       ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13585       trunk_timed = trunk_untimed = 0; 
13586       trunk_nmaxmtu = trunk_maxmtu = 0;
13587       memset(&debugaddr, '\0', sizeof(debugaddr));
13588 
13589       AST_LIST_LOCK(&registrations);
13590       AST_LIST_TRAVERSE(&registrations, reg, entry)
13591          iax2_do_register(reg);
13592       AST_LIST_UNLOCK(&registrations);
13593 
13594       /* Qualify hosts, too */
13595       poke_all_peers();
13596    }
13597    
13598    reload_firmware(0);
13599    iax_provision_reload(1);
13600    ast_unload_realtime("iaxpeers");
13601 
13602    return 0;
13603 }

static void reload_firmware ( int  unload  )  [static]

Definition at line 3277 of file chan_iax2.c.

References ast_config_AST_DATA_DIR, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verb, iax_firmware::dead, destroy_firmware(), errno, LOG_WARNING, and try_firmware().

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

03278 {
03279    struct iax_firmware *cur = NULL;
03280    DIR *fwd;
03281    struct dirent *de;
03282    char dir[256], fn[256];
03283 
03284    AST_LIST_LOCK(&firmwares);
03285 
03286    /* Mark all as dead */
03287    AST_LIST_TRAVERSE(&firmwares, cur, list)
03288       cur->dead = 1;
03289 
03290    /* Now that we have marked them dead... load new ones */
03291    if (!unload) {
03292       snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03293       fwd = opendir(dir);
03294       if (fwd) {
03295          while((de = readdir(fwd))) {
03296             if (de->d_name[0] != '.') {
03297                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03298                if (!try_firmware(fn)) {
03299                   ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03300                }
03301             }
03302          }
03303          closedir(fwd);
03304       } else 
03305          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03306    }
03307 
03308    /* Clean up leftovers */
03309    AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03310       if (!cur->dead)
03311          continue;
03312       AST_LIST_REMOVE_CURRENT(list);
03313       destroy_firmware(cur);
03314    }
03315    AST_LIST_TRAVERSE_SAFE_END;
03316 
03317    AST_LIST_UNLOCK(&firmwares);
03318 }

static void remove_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2199 of file chan_iax2.c.

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

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

02200 {
02201    if (!pvt->peercallno) {
02202       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02203       return;
02204    }
02205 
02206    ao2_unlink(iax_peercallno_pvts, pvt);
02207 }

static void remove_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2180 of file chan_iax2.c.

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

Referenced by complete_transfer(), and iax2_destroy().

02181 {
02182    if (!pvt->transfercallno) {
02183       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02184       return;
02185    }
02186 
02187    ao2_unlink(iax_transfercallno_pvts, pvt);
02188 }

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

Definition at line 2709 of file chan_iax2.c.

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

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

02710 {
02711    struct callno_entry *callno_entry = (struct callno_entry *) obj;
02712 
02713    /* the callno_pool container is locked here primarily to ensure thread
02714     * safety of the total_nonval_callno_used check and decrement */
02715    ao2_lock(callno_pool);
02716 
02717    if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02718       total_nonval_callno_used--;
02719    } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02720       ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02721    }
02722 
02723    if (callno_entry->callno < TRUNK_CALL_START) {
02724       ao2_link(callno_pool, callno_entry);
02725    } else {
02726       ao2_link(callno_pool_trunk, callno_entry);
02727    }
02728    ao2_ref(callno_entry, -1); /* only container ref remains */
02729 
02730    ao2_unlock(callno_pool);
02731    return 0;
02732 }

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

Definition at line 4894 of file chan_iax2.c.

References ast_strlen_zero(), CALLTOKEN_AUTO, iax2_peer::calltoken_required, iax2_user::calltoken_required, CALLTOKEN_YES, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), and user_unref().

Referenced by handle_call_token().

04895 {
04896    struct iax2_user *user = NULL;
04897    struct iax2_peer *peer = NULL;
04898 
04899    if (ast_strlen_zero(name)) {
04900       return; /* no username given */
04901    }
04902 
04903    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04904       user->calltoken_required = CALLTOKEN_YES;
04905    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04906       peer->calltoken_required = CALLTOKEN_YES;
04907    }
04908 
04909    if (peer) {
04910       peer_unref(peer);
04911    }
04912    if (user) {
04913       user_unref(user);
04914    }
04915 }

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

Definition at line 4812 of file chan_iax2.c.

References iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_LIST_REMOVE, iax_ie_data::buf, chan_iax2_pvt::calltoken_ie_len, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, iax_frame::encmethods, frame_queue, ast_frame::frametype, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, ast_frame_subclass::integer, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, remove_by_peercallno(), chan_iax2_pvt::rseqno, send_command(), and ast_frame::subclass.

Referenced by socket_process().

04813 {
04814    struct chan_iax2_pvt *pvt = iaxs[callno];
04815    int frametype = f->af.frametype;
04816    int subclass = f->af.subclass.integer;
04817    struct {
04818       struct ast_iax2_full_hdr fh;
04819       struct iax_ie_data ied;
04820    } data = {
04821       .ied.buf = { 0 },
04822       .ied.pos = 0,
04823    };
04824    /* total len - header len gives us the frame's IE len */
04825    int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04826 
04827    if (!pvt) {
04828       return;  /* this should not be possible if called from socket_process() */
04829    }
04830 
04831    /* 
04832     * Check to make sure last frame sent is valid for call token resend
04833     * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 
04834     * 2. Frame should _NOT_ already have a destination callno
04835     * 3. Frame must be a valid iax_frame subclass capable of starting dialog
04836     * 4. Pvt must have a calltoken_ie_len which represents the number of
04837     *    bytes at the end of the frame used for the previous calltoken ie.
04838     * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length
04839     * 6. Total length of f->data must be _LESS_ than size of our data struct
04840     *    because f->data must be able to fit within data. 
04841     */
04842    if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04843       || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04844       (f->datalen > sizeof(data))) {
04845 
04846       return;  /* ignore resend, token was not valid for the dialog */
04847    }
04848 
04849    /* token is valid
04850     * 1. Copy frame data over
04851     * 2. Redo calltoken IE, it will always be the last ie in the frame.
04852     *    NOTE: Having the ie always be last is not protocol specified,
04853     *    it is only an implementation choice.  Since we only expect the ie to
04854     *    be last for frames we have sent, this can no way be affected by
04855     *    another end point.
04856     * 3. Remove frame from queue
04857     * 4. Free old frame
04858     * 5. Clear previous seqnos
04859     * 6. Resend with CALLTOKEN ie.
04860     */
04861 
04862    /* ---1.--- */
04863    memcpy(&data, f->data, f->datalen);
04864    data.ied.pos = ie_data_pos;
04865 
04866    /* ---2.--- */
04867    /* move to the beginning of the calltoken ie so we can write over it */
04868    data.ied.pos -= pvt->calltoken_ie_len;
04869    iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04870 
04871    /* make sure to update token length incase it ever has to be stripped off again */
04872    pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */
04873 
04874    /* ---3.--- */
04875    AST_LIST_REMOVE(&frame_queue[callno], f, list);
04876 
04877    /* ---4.--- */
04878    iax2_frame_free(f);
04879 
04880    /* ---5.--- */
04881    pvt->oseqno = 0;
04882    pvt->rseqno = 0;
04883    pvt->iseqno = 0;
04884    pvt->aseqno = 0;
04885    if (pvt->peercallno) {
04886       remove_by_peercallno(pvt);
04887       pvt->peercallno = 0;
04888    }
04889 
04890    /* ---6.--- */
04891    send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04892 }

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

Definition at line 9516 of file chan_iax2.c.

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

Referenced by socket_process().

09517 {
09518    int i;
09519    unsigned int length, offset = 0;
09520    char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09521 
09522    for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09523       length = ies->ospblocklength[i];
09524       if (length != 0) {
09525          if (length > IAX_MAX_OSPBLOCK_SIZE) {
09526             /* OSP token block length wrong, clear buffer */
09527             offset = 0;
09528             break;
09529          } else {
09530             memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09531             offset += length;
09532          }
09533       } else {
09534          break;
09535       }
09536    }
09537    *(full_osptoken + offset) = '\0';
09538    if (strlen(full_osptoken) != offset) {
09539       /* OSP token length wrong, clear buffer */
09540       *full_osptoken = '\0';
09541    }
09542 
09543    ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09544 }

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

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

Definition at line 2781 of file chan_iax2.c.

References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), iax2_sched_add(), MIN_REUSE_TIME, OBJ_POINTER, peercnt_remove_cb(), and replace_callno().

Referenced by pvt_destructor().

02782 {
02783    int i;
02784    struct peercnt *peercnt;
02785    struct peercnt tmp = {
02786       .addr = sin->sin_addr.s_addr,
02787    };
02788 
02789    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02790       /* refcount is incremented with ao2_find.  keep that ref for the scheduler */
02791       ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02792       i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02793       if (i == -1) {
02794          ao2_ref(peercnt, -1);
02795       }
02796    }
02797 
02798    iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02799 }

static int schedule_delivery ( struct iax_frame fr,
int  updatehistory,
int  fromtrunk,
unsigned int *  tsout 
) [static]

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

References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_channel_unlock, ast_codec_get_samples(), ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_samp2tv(), AST_SCHED_DEL, ast_test_flag64, ast_tv(), ast_tvadd(), ast_tvzero(), ast_channel::bridge, calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame_subclass::format, ast_frame::frametype, iax2_frame_free(), iax2_lock_owner(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, ast_frame::subclass, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().

Referenced by socket_process(), and socket_process_meta().

04214 {
04215    int type, len;
04216    int ret;
04217    int needfree = 0;
04218    struct ast_channel *owner = NULL;
04219    struct ast_channel *bridge = NULL;
04220 
04221    /* Attempt to recover wrapped timestamps */
04222    unwrap_timestamp(fr);
04223 
04224    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
04225    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04226       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04227    else {
04228 #if 0
04229       ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04230 #endif
04231       fr->af.delivery = ast_tv(0,0);
04232    }
04233 
04234    type = JB_TYPE_CONTROL;
04235    len = 0;
04236 
04237    if(fr->af.frametype == AST_FRAME_VOICE) {
04238       type = JB_TYPE_VOICE;
04239       len = ast_codec_get_samples(&fr->af) / (ast_format_rate(&fr->af.subclass.format) / 1000);
04240    } else if(fr->af.frametype == AST_FRAME_CNG) {
04241       type = JB_TYPE_SILENCE;
04242    }
04243 
04244    if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04245       if (tsout)
04246          *tsout = fr->ts;
04247       __do_deliver(fr);
04248       return -1;
04249    }
04250 
04251    iax2_lock_owner(fr->callno);
04252    if (!iaxs[fr->callno]) {
04253       /* The call dissappeared so discard this frame that we could not send. */
04254       iax2_frame_free(fr);
04255       return -1;
04256    }
04257    if ((owner = iaxs[fr->callno]->owner))
04258       bridge = ast_bridged_channel(owner);
04259 
04260    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
04261     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
04262    if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04263       jb_frame frame;
04264 
04265       ast_channel_unlock(owner);
04266 
04267       /* deliver any frames in the jb */
04268       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04269          __do_deliver(frame.data);
04270          /* __do_deliver() can make the call disappear */
04271          if (!iaxs[fr->callno])
04272             return -1;
04273       }
04274 
04275       jb_reset(iaxs[fr->callno]->jb);
04276 
04277       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
04278 
04279       /* deliver this frame now */
04280       if (tsout)
04281          *tsout = fr->ts;
04282       __do_deliver(fr);
04283       return -1;
04284    }
04285    if (owner) {
04286       ast_channel_unlock(owner);
04287    }
04288 
04289    /* insert into jitterbuffer */
04290    /* TODO: Perhaps we could act immediately if it's not droppable and late */
04291    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04292          calc_rxstamp(iaxs[fr->callno],fr->ts));
04293    if (ret == JB_DROP) {
04294       needfree++;
04295    } else if (ret == JB_SCHED) {
04296       update_jbsched(iaxs[fr->callno]);
04297    }
04298    if (tsout)
04299       *tsout = fr->ts;
04300    if (needfree) {
04301       /* Free our iax frame */
04302       iax2_frame_free(fr);
04303       return -1;
04304    }
04305    return 0;
04306 }

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

Definition at line 1883 of file chan_iax2.c.

References ast_debug, ast_mutex_lock, ast_mutex_unlock, iax2_destroy(), and PTR_TO_CALLNO.

Referenced by iax2_hangup().

01884 {
01885    unsigned short callno = PTR_TO_CALLNO(vid);
01886    ast_mutex_lock(&iaxsl[callno]);
01887    if (iaxs[callno]) {
01888       ast_debug(1, "Really destroying %d now...\n", callno);
01889       iax2_destroy(callno);
01890    }
01891    ast_mutex_unlock(&iaxsl[callno]);
01892    return 0;
01893 }

static int send_apathetic_reply ( unsigned short  callno,
unsigned short  dcallno,
struct sockaddr_in *  sin,
int  command,
int  ts,
unsigned char  seqno,
int  sockfd,
struct iax_ie_data ied 
) [static]

Definition at line 4776 of file chan_iax2.c.

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

Referenced by handle_call_token(), and socket_process().

04779 {
04780    struct {
04781       struct ast_iax2_full_hdr f;
04782       struct iax_ie_data ied;
04783    } data;
04784    size_t size = sizeof(struct ast_iax2_full_hdr);
04785 
04786    if (ied) {
04787       size += ied->pos;
04788       memcpy(&data.ied, ied->buf, ied->pos);
04789    }
04790 
04791    data.f.scallno = htons(0x8000 | callno);
04792    data.f.dcallno = htons(dcallno);
04793    data.f.ts = htonl(ts);
04794    data.f.iseqno = seqno;
04795    data.f.oseqno = 0;
04796    data.f.type = AST_FRAME_IAX;
04797    data.f.csub = compress_subclass(command);
04798 
04799    return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04800 }

static int send_command ( struct chan_iax2_pvt i,
char  type,
int  command,
unsigned int  ts,
const unsigned char *  data,
int  datalen,
int  seqno 
) [static]

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

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

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

07581 {
07582    int call_num = i->callno;
07583    /* It is assumed that the callno has already been locked */
07584    iax2_predestroy(i->callno);
07585    if (!iaxs[call_num])
07586       return -1;
07587    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07588 }

static int send_command_immediate ( struct chan_iax2_pvt i,
char  type,
int  command,
unsigned int  ts,
const unsigned char *  data,
int  datalen,
int  seqno 
) [static]

Definition at line 7590 of file chan_iax2.c.

References __send_command().

Referenced by iax2_vnak(), and socket_process().

07591 {
07592    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07593 }

static int send_command_locked ( unsigned short  callno,
char  type,
int  command,
unsigned int  ts,
const unsigned char *  data,
int  datalen,
int  seqno 
) [static]

Definition at line 7566 of file chan_iax2.c.

References ast_mutex_lock, ast_mutex_unlock, and send_command().

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

07567 {
07568    int res;
07569    ast_mutex_lock(&iaxsl[callno]);
07570    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07571    ast_mutex_unlock(&iaxsl[callno]);
07572    return res;
07573 }

static int send_command_transfer ( struct chan_iax2_pvt i,
char  type,
int  command,
unsigned int  ts,
const unsigned char *  data,
int  datalen 
) [static]

Definition at line 7595 of file chan_iax2.c.

References __send_command().

Referenced by socket_process(), and try_transfer().

07596 {
07597    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07598 }

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

Definition at line 1589 of file chan_iax2.c.

References __send_lagrq(), ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, chan_iax2_pvt::lagid, and schedule_action.

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

01590 {
01591    int callno = (long) data;
01592    ast_mutex_lock(&iaxsl[callno]);
01593    if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) {
01594       iaxs[callno]->lagid = -1;
01595    }
01596    ast_mutex_unlock(&iaxsl[callno]);
01597 
01598 #ifdef SCHED_MULTITHREADED
01599    if (schedule_action(__send_lagrq, data))
01600 #endif
01601       __send_lagrq(data);
01602    return 0;
01603 }

static int send_packet ( struct iax_frame f  )  [static]

Definition at line 3390 of file chan_iax2.c.

References chan_iax2_pvt::addr, iax2_trunk_peer::addr, ast_debug, ast_inet_ntoa(), iax_frame::callno, iax_frame::data, iax_frame::datalen, errno, handle_error(), iax_showframe(), chan_iax2_pvt::peercallno, iax2_trunk_peer::sockfd, chan_iax2_pvt::transfer, transfer, iax_frame::transfer, and iax_frame::ts.

Referenced by __attempt_transmit(), iax2_send(), transmit_frame(), and vnak_retransmit().

03391 {
03392    int res;
03393    int callno = f->callno;
03394 
03395    /* Don't send if there was an error, but return error instead */
03396    if (!callno || !iaxs[callno] || iaxs[callno]->error)
03397        return -1;
03398 
03399    /* Called with iaxsl held */
03400    if (iaxdebug)
03401       ast_debug(3, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port));
03402 
03403    if (f->transfer) {
03404       if (iaxdebug)
03405          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03406       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03407    } else {
03408       if (iaxdebug)
03409          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03410       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03411    }
03412    if (res < 0) {
03413       if (iaxdebug)
03414          ast_debug(1, "Received error: %s\n", strerror(errno));
03415       handle_error();
03416    } else
03417       res = 0;
03418 
03419    return res;
03420 }

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

Definition at line 1522 of file chan_iax2.c.

References __send_ping(), ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, chan_iax2_pvt::pingid, and schedule_action.

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

01523 {
01524    int callno = (long) data;
01525    ast_mutex_lock(&iaxsl[callno]);
01526    if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) {
01527       iaxs[callno]->pingid = -1;
01528    }
01529    ast_mutex_unlock(&iaxsl[callno]);
01530 
01531 #ifdef SCHED_MULTITHREADED
01532    if (schedule_action(__send_ping, data))
01533 #endif
01534       __send_ping(data);
01535 
01536    return 0;
01537 }

static void send_signaling ( struct chan_iax2_pvt pvt  )  [static]

This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.

Definition at line 1905 of file chan_iax2.c.

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

Referenced by socket_process().

01906 {
01907    struct signaling_queue_entry *s = NULL;
01908 
01909    while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01910       iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01911       free_signaling_queue_entry(s);
01912    }
01913    pvt->hold_signaling = 0;
01914 }

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

Definition at line 9173 of file chan_iax2.c.

References iax2_trunk_peer::addr, iax_frame::afdata, ast_debug, ast_inet_ntoa(), ast_test_flag64, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.

Referenced by iax2_trunk_queue(), and timing_read().

09174 {
09175    int res = 0;
09176    struct iax_frame *fr;
09177    struct ast_iax2_meta_hdr *meta;
09178    struct ast_iax2_meta_trunk_hdr *mth;
09179    int calls = 0;
09180    
09181    /* Point to frame */
09182    fr = (struct iax_frame *)tpeer->trunkdata;
09183    /* Point to meta data */
09184    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09185    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09186    if (tpeer->trunkdatalen) {
09187       /* We're actually sending a frame, so fill the meta trunk header and meta header */
09188       meta->zeros = 0;
09189       meta->metacmd = IAX_META_TRUNK;
09190       if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09191          meta->cmddata = IAX_META_TRUNK_MINI;
09192       else
09193          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09194       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09195       /* And the rest of the ast_iax2 header */
09196       fr->direction = DIRECTION_OUTGRESS;
09197       fr->retrans = -1;
09198       fr->transfer = 0;
09199       /* Any appropriate call will do */
09200       fr->data = fr->afdata;
09201       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09202       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09203       calls = tpeer->calls;
09204 #if 0
09205       ast_debug(1, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts));
09206 #endif
09207       /* Reset transmit trunk side data */
09208       tpeer->trunkdatalen = 0;
09209       tpeer->calls = 0;
09210    }
09211    if (res < 0)
09212       return res;
09213    return calls;
09214 }

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

Load configuration.

Definition at line 13091 of file chan_iax2.c.

References add_calltoken_ignore(), ao2_link, ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_clear_flag64, ast_config_destroy(), ast_config_load, ast_context_find_or_create(), ast_copy_string(), ast_false(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_test_flag64, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, build_callno_limits(), build_peer(), build_user(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), iax2_parse_allow_disallow(), iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTSAVE_SYSNAME, IAX_RTUPDATE, IAX_SENDCONNECTEDLINE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_TRUNK_MTU, MAX_TRUNKDATA, ast_variable::name, network_change_event_subscribe(), network_change_event_unsubscribe(), ast_variable::next, peer_unref(), prefs, qos, reg_source_db(), secret, set_config_destroy(), socket_read(), user_unref(), and ast_variable::value.

Referenced by load_module(), reload(), reload_config(), and reload_module().

13092 {
13093    struct ast_config *cfg, *ucfg;
13094    iax2_format capability = iax2_capability;
13095    struct ast_variable *v;
13096    char *cat;
13097    const char *utype;
13098    const char *tosval;
13099    int format;
13100    int portno = IAX_DEFAULT_PORTNO;
13101    int  x;
13102    int mtuv;
13103    int subscribe_network_change = 1;
13104    struct iax2_user *user;
13105    struct iax2_peer *peer;
13106    struct ast_netsock *ns;
13107    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13108 #if 0
13109    static unsigned short int last_port=0;
13110 #endif
13111 
13112    cfg = ast_config_load(config_file, config_flags);
13113 
13114    if (!cfg) {
13115       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13116       return -1;
13117    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13118       ucfg = ast_config_load("users.conf", config_flags);
13119       if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13120          return 0;
13121       /* Otherwise we need to reread both files */
13122       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13123       if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13124          ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config_file);
13125          ast_config_destroy(ucfg);
13126          return 0;
13127       }
13128    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13129       ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config_file);
13130       return 0;
13131    } else { /* iax.conf changed, gotta reread users.conf, too */
13132       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13133       if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13134          ast_log(LOG_ERROR, "Config file users.conf is in an invalid format.  Aborting.\n");
13135          ast_config_destroy(cfg);
13136          return 0;
13137       }
13138    }
13139 
13140    if (reload) {
13141       set_config_destroy();
13142    }
13143 
13144    /* Reset global codec prefs */
13145    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
13146 
13147    /* Reset Global Flags */
13148    memset(&globalflags, 0, sizeof(globalflags));
13149    ast_set_flag64(&globalflags, IAX_RTUPDATE);
13150    ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13151 
13152 #ifdef SO_NO_CHECK
13153    nochecksums = 0;
13154 #endif
13155    /* Reset default parking lot */
13156    default_parkinglot[0] = '\0';
13157 
13158    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13159    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13160    global_max_trunk_mtu = MAX_TRUNK_MTU;
13161    global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
13162    global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
13163 
13164    maxauthreq = 3;
13165 
13166    srvlookup = 0;
13167 
13168    v = ast_variable_browse(cfg, "general");
13169 
13170    /* Seed initial tos value */
13171    tosval = ast_variable_retrieve(cfg, "general", "tos");
13172    if (tosval) {
13173       if (ast_str2tos(tosval, &qos.tos))
13174          ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13175    }
13176    /* Seed initial cos value */
13177    tosval = ast_variable_retrieve(cfg, "general", "cos");
13178    if (tosval) {
13179       if (ast_str2cos(tosval, &qos.cos))
13180          ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13181    }
13182    while(v) {
13183       if (!strcasecmp(v->name, "bindport")){ 
13184          if (reload)
13185             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13186          else
13187             portno = atoi(v->value);
13188       } else if (!strcasecmp(v->name, "pingtime")) 
13189          ping_time = atoi(v->value);
13190       else if (!strcasecmp(v->name, "iaxthreadcount")) {
13191          if (reload) {
13192             if (atoi(v->value) != iaxthreadcount)
13193                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13194          } else {
13195             iaxthreadcount = atoi(v->value);
13196             if (iaxthreadcount < 1) {
13197                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13198                iaxthreadcount = 1;
13199             } else if (iaxthreadcount > 256) {
13200                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13201                iaxthreadcount = 256;
13202             }
13203          }
13204       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13205          if (reload) {
13206             AST_LIST_LOCK(&dynamic_list);
13207             iaxmaxthreadcount = atoi(v->value);
13208             AST_LIST_UNLOCK(&dynamic_list);
13209          } else {
13210             iaxmaxthreadcount = atoi(v->value);
13211             if (iaxmaxthreadcount < 0) {
13212                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13213                iaxmaxthreadcount = 0;
13214             } else if (iaxmaxthreadcount > 256) {
13215                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13216                iaxmaxthreadcount = 256;
13217             }
13218          }
13219       } else if (!strcasecmp(v->name, "nochecksums")) {
13220 #ifdef SO_NO_CHECK
13221          if (ast_true(v->value))
13222             nochecksums = 1;
13223          else
13224             nochecksums = 0;
13225 #else
13226          if (ast_true(v->value))
13227             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13228 #endif
13229       }
13230       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
13231          maxjitterbuffer = atoi(v->value);
13232       else if (!strcasecmp(v->name, "resyncthreshold")) 
13233          resyncthreshold = atoi(v->value);
13234       else if (!strcasecmp(v->name, "maxjitterinterps")) 
13235          maxjitterinterps = atoi(v->value);
13236       else if (!strcasecmp(v->name, "jittertargetextra"))
13237          jittertargetextra = atoi(v->value);
13238       else if (!strcasecmp(v->name, "lagrqtime")) 
13239          lagrq_time = atoi(v->value);
13240       else if (!strcasecmp(v->name, "maxregexpire")) 
13241          max_reg_expire = atoi(v->value);
13242       else if (!strcasecmp(v->name, "minregexpire")) 
13243          min_reg_expire = atoi(v->value);
13244       else if (!strcasecmp(v->name, "bindaddr")) {
13245          if (reload) {
13246             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13247          } else {
13248             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13249                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13250             } else {
13251                   if (strchr(v->value, ':'))
13252                   ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13253                   else
13254                   ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13255                if (defaultsockfd < 0) 
13256                   defaultsockfd = ast_netsock_sockfd(ns);
13257                ast_netsock_unref(ns);
13258             }
13259          }
13260       } else if (!strcasecmp(v->name, "authdebug")) {
13261          authdebug = ast_true(v->value);
13262       } else if (!strcasecmp(v->name, "encryption")) {
13263             iax2_encryption |= get_encrypt_methods(v->value);
13264             if (!iax2_encryption) {
13265                ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13266             }
13267       } else if (!strcasecmp(v->name, "forceencryption")) {
13268          if (ast_false(v->value)) {
13269             ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13270          } else {
13271             iax2_encryption |= get_encrypt_methods(v->value);
13272             if (iax2_encryption) {
13273                ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13274             }
13275          }
13276       } else if (!strcasecmp(v->name, "transfer")) {
13277          if (!strcasecmp(v->value, "mediaonly")) {
13278             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13279          } else if (ast_true(v->value)) {
13280             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13281          } else
13282             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13283       } else if (!strcasecmp(v->name, "codecpriority")) {
13284          if(!strcasecmp(v->value, "caller"))
13285             ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13286          else if(!strcasecmp(v->value, "disabled"))
13287             ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13288          else if(!strcasecmp(v->value, "reqonly")) {
13289             ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13290             ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13291          }
13292       } else if (!strcasecmp(v->name, "jitterbuffer"))
13293          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13294       else if (!strcasecmp(v->name, "forcejitterbuffer"))
13295          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13296       else if (!strcasecmp(v->name, "delayreject"))
13297          delayreject = ast_true(v->value);
13298       else if (!strcasecmp(v->name, "allowfwdownload"))
13299          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13300       else if (!strcasecmp(v->name, "rtcachefriends"))
13301          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13302       else if (!strcasecmp(v->name, "rtignoreregexpire"))
13303          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13304       else if (!strcasecmp(v->name, "rtupdate"))
13305          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13306       else if (!strcasecmp(v->name, "rtsavesysname"))
13307          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13308       else if (!strcasecmp(v->name, "trunktimestamps"))
13309          ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13310       else if (!strcasecmp(v->name, "rtautoclear")) {
13311          int i = atoi(v->value);
13312          if(i > 0)
13313             global_rtautoclear = i;
13314          else
13315             i = 0;
13316          ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13317       } else if (!strcasecmp(v->name, "trunkfreq")) {
13318          trunkfreq = atoi(v->value);
13319          if (trunkfreq < 10)
13320             trunkfreq = 10;
13321       } else if (!strcasecmp(v->name, "trunkmtu")) {
13322          mtuv = atoi(v->value);
13323          if (mtuv  == 0 )
13324             global_max_trunk_mtu = 0;
13325          else if (mtuv >= 172 && mtuv < 4000)
13326             global_max_trunk_mtu = mtuv;
13327          else
13328             ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13329                mtuv, v->lineno);
13330       } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13331          trunkmaxsize = atoi(v->value);
13332          if (trunkmaxsize == 0)
13333             trunkmaxsize = MAX_TRUNKDATA;
13334       } else if (!strcasecmp(v->name, "autokill")) {
13335          if (sscanf(v->value, "%30d", &x) == 1) {
13336             if (x >= 0)
13337                autokill = x;
13338             else
13339                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13340          } else if (ast_true(v->value)) {
13341             autokill = DEFAULT_MAXMS;
13342          } else {
13343             autokill = 0;
13344          }
13345       } else if (!strcasecmp(v->name, "bandwidth")) {
13346          if (!strcasecmp(v->value, "low")) {
13347             capability = IAX_CAPABILITY_LOWBANDWIDTH;
13348          } else if (!strcasecmp(v->value, "medium")) {
13349             capability = IAX_CAPABILITY_MEDBANDWIDTH;
13350          } else if (!strcasecmp(v->value, "high")) {
13351             capability = IAX_CAPABILITY_FULLBANDWIDTH;
13352          } else
13353             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13354       } else if (!strcasecmp(v->name, "allow")) {
13355          iax2_parse_allow_disallow(&prefs, &capability, v->value, 1);
13356       } else if (!strcasecmp(v->name, "disallow")) {
13357          iax2_parse_allow_disallow(&prefs, &capability, v->value, 0);
13358       } else if (!strcasecmp(v->name, "register")) {
13359          iax2_register(v->value, v->lineno);
13360       } else if (!strcasecmp(v->name, "iaxcompat")) {
13361          iaxcompat = ast_true(v->value);
13362       } else if (!strcasecmp(v->name, "regcontext")) {
13363          ast_copy_string(regcontext, v->value, sizeof(regcontext));
13364          /* Create context if it doesn't exist already */
13365          ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13366       } else if (!strcasecmp(v->name, "tos")) {
13367          if (ast_str2tos(v->value, &qos.tos))
13368             ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13369       } else if (!strcasecmp(v->name, "cos")) {
13370          if (ast_str2cos(v->value, &qos.cos))
13371             ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13372       } else if (!strcasecmp(v->name, "parkinglot")) {
13373          ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13374       } else if (!strcasecmp(v->name, "accountcode")) {
13375          ast_copy_string(accountcode, v->value, sizeof(accountcode));
13376       } else if (!strcasecmp(v->name, "mohinterpret")) {
13377          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13378       } else if (!strcasecmp(v->name, "mohsuggest")) {
13379          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13380       } else if (!strcasecmp(v->name, "amaflags")) {
13381          format = ast_cdr_amaflags2int(v->value);
13382          if (format < 0) {
13383             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13384          } else {
13385             amaflags = format;
13386          }
13387       } else if (!strcasecmp(v->name, "language")) {
13388          ast_copy_string(language, v->value, sizeof(language));
13389       } else if (!strcasecmp(v->name, "maxauthreq")) {
13390          maxauthreq = atoi(v->value);
13391          if (maxauthreq < 0)
13392             maxauthreq = 0;
13393       } else if (!strcasecmp(v->name, "adsi")) {
13394          adsi = ast_true(v->value);
13395       } else if (!strcasecmp(v->name, "srvlookup")) {
13396          srvlookup = ast_true(v->value);
13397       } else if (!strcasecmp(v->name, "connectedline")) {
13398          if (ast_true(v->value)) {
13399             ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13400          } else if (!strcasecmp(v->value, "send")) {
13401             ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13402             ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13403          } else if (!strcasecmp(v->value, "receive")) {
13404             ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13405             ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13406          } else {
13407             ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13408          }
13409       } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13410          if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13411             ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number.  %s is not valid at line %d\n", v->value, v->lineno);
13412          }
13413       } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13414          if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13415             ast_log(LOG_WARNING, "maxcallnumbers_nonvalidated must be set to a valid number.  %s is not valid at line %d.\n", v->value, v->lineno);
13416          }
13417       } else if (!strcasecmp(v->name, "calltokenoptional")) {
13418          if (add_calltoken_ignore(v->value)) {
13419             ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13420          }
13421       } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13422          if (ast_true(v->value)) {
13423             subscribe_network_change = 1;
13424          } else if (ast_false(v->value)) {
13425             subscribe_network_change = 0;
13426          } else {
13427             ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13428          }
13429       } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13430          if (ast_true(v->value)) {
13431             ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13432          } else if (ast_false(v->value)) {
13433             ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13434          } else {
13435             ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13436          }
13437       }/*else if (strcasecmp(v->name,"type")) */
13438       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13439       v = v->next;
13440    }
13441 
13442    if (subscribe_network_change) {
13443       network_change_event_subscribe();
13444    } else {
13445       network_change_event_unsubscribe();
13446    }
13447 
13448    if (defaultsockfd < 0) {
13449       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13450          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13451       } else {
13452          ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13453          defaultsockfd = ast_netsock_sockfd(ns);
13454          ast_netsock_unref(ns);
13455       }
13456    }
13457    if (reload) {
13458       ast_netsock_release(outsock);
13459       outsock = ast_netsock_list_alloc();
13460       if (!outsock) {
13461          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13462          return -1;
13463       }
13464       ast_netsock_init(outsock);
13465    }
13466 
13467    if (min_reg_expire > max_reg_expire) {
13468       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13469          min_reg_expire, max_reg_expire, max_reg_expire);
13470       min_reg_expire = max_reg_expire;
13471    }
13472    iax2_capability = capability;
13473    
13474    if (ucfg) {
13475       struct ast_variable *gen;
13476       int genhasiax;
13477       int genregisteriax;
13478       const char *hasiax, *registeriax;
13479       
13480       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13481       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13482       gen = ast_variable_browse(ucfg, "general");
13483       cat = ast_category_browse(ucfg, NULL);
13484       while (cat) {
13485          if (strcasecmp(cat, "general")) {
13486             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13487             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13488             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13489                /* Start with general parameters, then specific parameters, user and peer */
13490                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13491                if (user) {
13492                   ao2_link(users, user);
13493                   user = user_unref(user);
13494                }
13495                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13496                if (peer) {
13497                   if (ast_test_flag64(peer, IAX_DYNAMIC))
13498                      reg_source_db(peer);
13499                   ao2_link(peers, peer);
13500                   peer = peer_unref(peer);
13501                }
13502             }
13503             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13504                char tmp[256];
13505                const char *host = ast_variable_retrieve(ucfg, cat, "host");
13506                const char *username = ast_variable_retrieve(ucfg, cat, "username");
13507                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13508                if (!host)
13509                   host = ast_variable_retrieve(ucfg, "general", "host");
13510                if (!username)
13511                   username = ast_variable_retrieve(ucfg, "general", "username");
13512                if (!secret)
13513                   secret = ast_variable_retrieve(ucfg, "general", "secret");
13514                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13515                   if (!ast_strlen_zero(secret))
13516                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13517                   else
13518                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13519                   iax2_register(tmp, 0);
13520                }
13521             }
13522          }
13523          cat = ast_category_browse(ucfg, cat);
13524       }
13525       ast_config_destroy(ucfg);
13526    }
13527    
13528    cat = ast_category_browse(cfg, NULL);
13529    while(cat) {
13530       if (strcasecmp(cat, "general")) {
13531          utype = ast_variable_retrieve(cfg, cat, "type");
13532          if (!strcasecmp(cat, "callnumberlimits")) {
13533             build_callno_limits(ast_variable_browse(cfg, cat));
13534          } else if (utype) {
13535             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13536                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13537                if (user) {
13538                   ao2_link(users, user);
13539                   user = user_unref(user);
13540                }
13541             }
13542             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13543                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13544                if (peer) {
13545                   if (ast_test_flag64(peer, IAX_DYNAMIC))
13546                      reg_source_db(peer);
13547                   ao2_link(peers, peer);
13548                   peer = peer_unref(peer);
13549                }
13550             } else if (strcasecmp(utype, "user")) {
13551                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13552             }
13553          } else
13554             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13555       }
13556       cat = ast_category_browse(cfg, cat);
13557    }
13558    ast_config_destroy(cfg);
13559    return 1;
13560 }

static void set_config_destroy ( void   )  [static]

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

Definition at line 9941 of file chan_iax2.c.

References ast_channel_name(), ast_channel_unlock, ast_set_hangupsource(), ast_channel::hangupcause, iax2_lock_owner(), and chan_iax2_pvt::owner.

Referenced by socket_process().

09942 {
09943    iax2_lock_owner(callno);
09944    if (iaxs[callno] && iaxs[callno]->owner) {
09945       if (causecode) {
09946          iaxs[callno]->owner->hangupcause = causecode;
09947       }
09948       ast_set_hangupsource(iaxs[callno]->owner, ast_channel_name(iaxs[callno]->owner), 0);
09949       ast_channel_unlock(iaxs[callno]->owner);
09950    }
09951 }

static void set_peercnt_limit ( struct peercnt peercnt  )  [static]

Definition at line 2324 of file chan_iax2.c.

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

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

02325 {
02326    uint16_t limit = global_maxcallno;
02327    struct addr_range *addr_range;
02328    struct sockaddr_in sin = {
02329       .sin_addr.s_addr = peercnt->addr,
02330    };
02331 
02332 
02333    if (peercnt->reg && peercnt->limit) {
02334       return; /* this peercnt has a custom limit set by a registration */
02335    }
02336 
02337    if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02338       limit = addr_range->limit;
02339       ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02340       ao2_ref(addr_range, -1);
02341    }
02342 
02343    peercnt->limit = limit;
02344 }

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

Definition at line 2350 of file chan_iax2.c.

References ast_debug, and set_peercnt_limit().

Referenced by reload_config().

02351 {
02352    struct peercnt *peercnt = obj;
02353 
02354    set_peercnt_limit(peercnt);
02355    ast_debug(1, "Reset limits for peercnts table\n");
02356 
02357    return 0;
02358 }

static void signal_condition ( ast_mutex_t lock,
ast_cond_t cond 
) [static]

Definition at line 1049 of file chan_iax2.c.

References ast_cond_signal, ast_mutex_lock, and ast_mutex_unlock.

Referenced by __schedule_action(), cleanup_thread_list(), iax2_process_thread(), and socket_read().

01050 {
01051    ast_mutex_lock(lock);
01052    ast_cond_signal(cond);
01053    ast_mutex_unlock(lock);
01054 }

static int socket_process ( struct iax2_thread thread  )  [static]

Definition at line 9953 of file chan_iax2.c.

References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, ast_aes_set_decrypt_key(), ast_async_goto(), ast_bridged_channel(), ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_channel_datastore_add(), ast_channel_name(), ast_channel_ref, ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_clear_flag64, ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), ast_connected_line_parse_data(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_exists_extension(), ast_format_cap_copy(), ast_format_cap_destroy(), ast_format_cap_dup(), ast_format_cap_from_old_bitfield(), ast_format_cap_set(), ast_format_cap_to_old_bitfield(), ast_format_from_old_bitfield(), ast_format_id_from_old_bitfield(), ast_format_set_video_mark(), AST_FORMAT_SLINEAR, ast_format_to_old_bitfield(), ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_free, ast_getformatname(), ast_getformatname_multiple(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_event, ast_mutex_lock, ast_mutex_unlock, ast_parking_ext_valid(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_id_presentation(), AST_SCHED_DEL, ast_set_callerid(), ast_set_flag, ast_set_flag64, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_var_assign(), ast_variables_destroy(), ast_verb, auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), chan_iax2_pvt::authmethods, iax_ie_data::buf, iax2_thread::buf, iax2_thread::buf_len, CACHE_FLAG_TRANSMITTED, iax_frame::cacheable, calc_timestamp(), iax_ies::called_number, ast_channel::caller, chan_iax2_pvt::calling_pres, iax2_peer::callno, chan_iax2_pvt::callno, iax_frame::callno, iax_ies::calltoken, iax_ies::calltokendata, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, check_access(), check_provisioning(), chan_iax2_pvt::chosenformat, cid_name, chan_iax2_pvt::cid_num, cid_num, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), context, chan_iax2_pvt::context, ast_iax2_full_hdr::csub, ast_datastore::data, ast_frame::data, ast_frame::datalen, DATASTORE_INHERIT_FOREVER, ast_iax2_full_hdr::dcallno, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::encmethods, iax_ies::encmethods, ast_var_t::entries, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, chan_iax2_pvt::exten, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, ast_frame_subclass::format, format, frame_queue, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, chan_iax2_pvt::hold_signaling, iax2_ack_registry(), iax2_allow_new(), iax2_best_codec(), iax2_codec_choose(), iax2_destroy(), iax2_dprequest(), iax2_getformatname(), iax2_getformatname_multiple(), iax2_lock_owner(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CALLENCRYPTED, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_RTKEY, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DEBUGDIGEST, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, IAX_FORCE_ENCRYPT, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_IAX_UNKNOWN, IAX_IMMEDIATE, iax_outputframe(), iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, IAX_RECVCONNECTEDLINE, IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), chan_iax2_pvt::iaxvars, ast_party_caller::id, ast_party_connected_line::id, ast_format::id, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::initid, chan_iax2_pvt::inkeys, ast_frame_subclass::integer, iax2_thread::iofd, iax2_thread::iosin, chan_iax2_pvt::iseqno, iax_frame::iseqno, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, ast_frame::len, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event, iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, chan_iax2_pvt::mohsuggest, iax_ies::musiconhold, ast_party_id::name, iax2_peer::name, ast_variable::name, ast_channel::nativeformats, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, ast_variable::next, ast_party_id::number, ast_frame::offset, chan_iax2_pvt::oseqno, iax_frame::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::outoforder, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), peer_ref(), peer_unref(), chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, ast_party_name::presentation, ast_party_number::presentation, iax_ies::provver, iax_ies::provverpres, ast_frame::ptr, raw_hangup(), ast_channel::readformat, iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rprefs, chan_iax2_pvt::rseqno, S_COR, S_OR, ast_frame::samples, save_osptoken(), save_rr(), ast_iax2_full_hdr::scallno, schedule_delivery(), chan_iax2_pvt::secret, send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), send_signaling(), iax_ies::serviceident, set_hangup_source_and_cause(), iax2_peer::smoothing, socket_process_meta(), spawn_dp_lookup(), ast_frame::src, chan_iax2_pvt::state, stop_stuff(), store_by_peercallno(), ast_party_name::str, ast_party_number::str, ast_frame::subclass, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MEDIAPASS, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), iax_frame::ts, ast_iax2_full_hdr::ts, ast_iax2_full_hdr::type, uncompress_subclass(), update_registry(), iax_ies::username, ast_party_name::valid, ast_party_number::valid, ast_variable::value, var, iax_ies::vars, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.

Referenced by handle_deferred_full_frames(), and iax2_process_thread().

09954 {
09955    struct sockaddr_in sin;
09956    int res;
09957    int updatehistory=1;
09958    int new = NEW_PREVENT;
09959    int dcallno = 0;
09960    char decrypted = 0;
09961    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09962    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09963    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09964    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09965    struct iax_frame *fr;
09966    struct iax_frame *cur;
09967    struct ast_frame f = { 0, };
09968    struct ast_channel *c = NULL;
09969    struct iax2_dpcache *dp;
09970    struct iax2_peer *peer;
09971    struct iax_ies ies;
09972    struct iax_ie_data ied0, ied1;
09973    iax2_format format;
09974    int fd;
09975    int exists;
09976    int minivid = 0;
09977    char empty[32]="";      /* Safety measure */
09978    struct iax_frame *duped_fr;
09979    char host_pref_buf[128];
09980    char caller_pref_buf[128];
09981    struct ast_codec_pref pref;
09982    char *using_prefs = "mine";
09983 
09984    /* allocate an iax_frame with 4096 bytes of data buffer */
09985    fr = alloca(sizeof(*fr) + 4096);
09986    memset(fr, 0, sizeof(*fr));
09987    fr->afdatalen = 4096; /* From alloca() above */
09988 
09989    /* Copy frequently used parameters to the stack */
09990    res = thread->buf_len;
09991    fd = thread->iofd;
09992    memcpy(&sin, &thread->iosin, sizeof(sin));
09993 
09994    if (res < sizeof(*mh)) {
09995       ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09996       return 1;
09997    }
09998    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09999       if (res < sizeof(*vh)) {
10000          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
10001          return 1;
10002       }
10003 
10004       /* This is a video frame, get call number */
10005       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
10006       minivid = 1;
10007    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
10008       return socket_process_meta(res, meta, &sin, fd, fr);
10009 
10010 #ifdef DEBUG_SUPPORT
10011    if (res >= sizeof(*fh))
10012       iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
10013 #endif
10014    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10015       if (res < sizeof(*fh)) {
10016          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
10017          return 1;
10018       }
10019 
10020       /* Get the destination call number */
10021       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
10022 
10023 
10024       /* check to make sure this full frame isn't encrypted before we attempt
10025        * to look inside of it. If it is encrypted, decrypt it first. Its ok if the
10026        * callno is not found here, that just means one hasn't been allocated for
10027        * this connection yet. */
10028       if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
10029          ast_mutex_lock(&iaxsl[fr->callno]);
10030          if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
10031             if (decrypt_frame(fr->callno, fh, &f, &res)) {
10032                ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10033                ast_mutex_unlock(&iaxsl[fr->callno]);
10034                return 1;
10035             }
10036             decrypted = 1;
10037          }
10038          ast_mutex_unlock(&iaxsl[fr->callno]);
10039       }
10040 
10041       /* Retrieve the type and subclass */
10042       f.frametype = fh->type;
10043       if (f.frametype == AST_FRAME_VIDEO) {
10044          ast_format_from_old_bitfield(&f.subclass.format, (uncompress_subclass(fh->csub & ~0x40)));
10045          if ((fh->csub >> 6) & 0x1) {
10046             ast_format_set_video_mark(&f.subclass.format);
10047          }
10048       } else if (f.frametype == AST_FRAME_VOICE) {
10049          ast_format_from_old_bitfield(&f.subclass.format, uncompress_subclass(fh->csub));
10050       } else {
10051          f.subclass.integer = uncompress_subclass(fh->csub);
10052       }
10053 
10054       /* Deal with POKE/PONG without allocating a callno */
10055       if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
10056          /* Reply back with a PONG, but don't care about the result. */
10057          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10058          return 1;
10059       } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
10060          /* Ignore */
10061          return 1;
10062       }
10063 
10064       f.datalen = res - sizeof(*fh);
10065       if (f.datalen) {
10066          if (f.frametype == AST_FRAME_IAX) {
10067             if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
10068                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
10069                ast_variables_destroy(ies.vars);
10070                return 1;
10071             }
10072             f.data.ptr = NULL;
10073             f.datalen = 0;
10074          } else {
10075             f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
10076             memset(&ies, 0, sizeof(ies));
10077          }
10078       } else {
10079          if (f.frametype == AST_FRAME_IAX)
10080             f.data.ptr = NULL;
10081          else
10082             f.data.ptr = empty;
10083          memset(&ies, 0, sizeof(ies));
10084       }
10085 
10086       if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
10087          /* only set NEW_ALLOW if calltoken checks out */
10088          if (handle_call_token(fh, &ies, &sin, fd)) {
10089             ast_variables_destroy(ies.vars);
10090             return 1;
10091          }
10092 
10093          if (ies.calltoken && ies.calltokendata) {
10094             /* if we've gotten this far, and the calltoken ie data exists,
10095              * then calltoken validation _MUST_ have taken place.  If calltoken
10096              * data is provided, it is always validated reguardless of any
10097              * calltokenoptional or requirecalltoken options */
10098             new = NEW_ALLOW_CALLTOKEN_VALIDATED;
10099          } else {
10100             new = NEW_ALLOW;
10101          }
10102       }
10103    } else {
10104       /* Don't know anything about it yet */
10105       f.frametype = AST_FRAME_NULL;
10106       f.subclass.integer = 0;
10107       memset(&ies, 0, sizeof(ies));
10108    }
10109 
10110    if (!fr->callno) {
10111       int check_dcallno = 0;
10112 
10113       /*
10114        * We enforce accurate destination call numbers for ACKs.  This forces the other
10115        * end to know the destination call number before call setup can complete.
10116        *
10117        * Discussed in the following thread:
10118        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
10119        */
10120 
10121       if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10122          check_dcallno = 1;
10123       }
10124 
10125       if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
10126          if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
10127             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10128          } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
10129             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10130          }
10131          ast_variables_destroy(ies.vars);
10132          return 1;
10133       }
10134    }
10135 
10136    if (fr->callno > 0)
10137       ast_mutex_lock(&iaxsl[fr->callno]);
10138 
10139    if (!fr->callno || !iaxs[fr->callno]) {
10140       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
10141          frame, reply with an inval */
10142       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10143          /* We can only raw hangup control frames */
10144          if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10145              (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10146              (f.subclass.integer != IAX_COMMAND_TXACC) &&
10147              (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
10148              (f.frametype != AST_FRAME_IAX))
10149             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10150             fd);
10151       }
10152       if (fr->callno > 0) 
10153          ast_mutex_unlock(&iaxsl[fr->callno]);
10154       ast_variables_destroy(ies.vars);
10155       return 1;
10156    }
10157    if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10158       if (decrypt_frame(fr->callno, fh, &f, &res)) {
10159          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10160          ast_variables_destroy(ies.vars);
10161          ast_mutex_unlock(&iaxsl[fr->callno]);
10162          return 1;
10163       }
10164       decrypted = 1;
10165    }
10166 
10167 #ifdef DEBUG_SUPPORT
10168    if (decrypted) {
10169       iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10170    }
10171 #endif
10172 
10173 
10174    /* count this frame */
10175    iaxs[fr->callno]->frames_received++;
10176 
10177    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10178       f.subclass.integer != IAX_COMMAND_TXCNT &&      /* for attended transfer */
10179       f.subclass.integer != IAX_COMMAND_TXACC) {      /* for attended transfer */
10180       unsigned short new_peercallno;
10181 
10182       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10183       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10184          if (iaxs[fr->callno]->peercallno) {
10185             remove_by_peercallno(iaxs[fr->callno]);
10186          }
10187          iaxs[fr->callno]->peercallno = new_peercallno;
10188          store_by_peercallno(iaxs[fr->callno]);
10189       }
10190    }
10191    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10192       if (iaxdebug)
10193          ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10194       /* Check if it's out of order (and not an ACK or INVAL) */
10195       fr->oseqno = fh->oseqno;
10196       fr->iseqno = fh->iseqno;
10197       fr->ts = ntohl(fh->ts);
10198 #ifdef IAXTESTS
10199       if (test_resync) {
10200          ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10201          fr->ts += test_resync;
10202       }
10203 #endif /* IAXTESTS */
10204 #if 0
10205       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10206            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10207                         (f.subclass == IAX_COMMAND_NEW ||
10208                          f.subclass == IAX_COMMAND_AUTHREQ ||
10209                          f.subclass == IAX_COMMAND_ACCEPT ||
10210                          f.subclass == IAX_COMMAND_REJECT))      ) )
10211 #endif
10212       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10213          updatehistory = 0;
10214       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10215          (iaxs[fr->callno]->iseqno ||
10216             ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10217             (f.subclass.integer != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
10218             (f.subclass.integer != IAX_COMMAND_TXREL) &&    /* for attended transfer */
10219             (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
10220             (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10221             (f.frametype != AST_FRAME_IAX))) {
10222          if (
10223           ((f.subclass.integer != IAX_COMMAND_ACK) &&
10224            (f.subclass.integer != IAX_COMMAND_INVAL) &&
10225            (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10226            (f.subclass.integer != IAX_COMMAND_TXREADY) &&      /* for attended transfer */
10227            (f.subclass.integer != IAX_COMMAND_TXREL) &&     /* for attended transfer */
10228            (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
10229            (f.subclass.integer != IAX_COMMAND_TXACC) &&
10230            (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10231            (f.frametype != AST_FRAME_IAX)) {
10232             /* If it's not an ACK packet, it's out of order. */
10233             ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
10234                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10235             /* Check to see if we need to request retransmission,
10236              * and take sequence number wraparound into account */
10237             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10238                /* If we've already seen it, ack it XXX There's a border condition here XXX */
10239                if ((f.frametype != AST_FRAME_IAX) ||
10240                      ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10241                   ast_debug(1, "Acking anyway\n");
10242                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
10243                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
10244                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10245                }
10246             } else {
10247                /* Send a VNAK requesting retransmission */
10248                iax2_vnak(fr->callno);
10249             }
10250             ast_variables_destroy(ies.vars);
10251             ast_mutex_unlock(&iaxsl[fr->callno]);
10252             return 1;
10253          }
10254       } else {
10255          /* Increment unless it's an ACK or VNAK */
10256          if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10257              (f.subclass.integer != IAX_COMMAND_INVAL) &&
10258              (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10259              (f.subclass.integer != IAX_COMMAND_TXACC) &&
10260             (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10261              (f.frametype != AST_FRAME_IAX))
10262             iaxs[fr->callno]->iseqno++;
10263       }
10264       /* Ensure text frames are NULL-terminated */
10265       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10266          if (res < thread->buf_size)
10267             thread->buf[res++] = '\0';
10268          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
10269             thread->buf[res - 1] = '\0';
10270       }
10271 
10272       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
10273          from the real peer, not the transfer peer */
10274       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10275           ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10276            (f.frametype != AST_FRAME_IAX))) {
10277          unsigned char x;
10278          int call_to_destroy;
10279          /* First we have to qualify that the ACKed value is within our window */
10280          if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10281             x = fr->iseqno;
10282          else
10283             x = iaxs[fr->callno]->oseqno;
10284          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10285             /* The acknowledgement is within our window.  Time to acknowledge everything
10286                that it says to */
10287             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10288                /* Ack the packet with the given timestamp */
10289                if (iaxdebug)
10290                   ast_debug(1, "Cancelling transmission of packet %d\n", x);
10291                call_to_destroy = 0;
10292                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10293                   /* If it's our call, and our timestamp, mark -1 retries */
10294                   if (x == cur->oseqno) {
10295                      cur->retries = -1;
10296                      /* Destroy call if this is the end */
10297                      if (cur->final)
10298                         call_to_destroy = fr->callno;
10299                   }
10300                }
10301                if (call_to_destroy) {
10302                   if (iaxdebug)
10303                      ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10304                   ast_mutex_lock(&iaxsl[call_to_destroy]);
10305                   iax2_destroy(call_to_destroy);
10306                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
10307                }
10308             }
10309             /* Note how much we've received acknowledgement for */
10310             if (iaxs[fr->callno])
10311                iaxs[fr->callno]->rseqno = fr->iseqno;
10312             else {
10313                /* Stop processing now */
10314                ast_variables_destroy(ies.vars);
10315                ast_mutex_unlock(&iaxsl[fr->callno]);
10316                return 1;
10317             }
10318          } else {
10319             ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10320          }
10321       }
10322       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10323          ((f.frametype != AST_FRAME_IAX) ||
10324           ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10325            (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10326          /* Only messages we accept from a transfer host are TXACC and TXCNT */
10327          ast_variables_destroy(ies.vars);
10328          ast_mutex_unlock(&iaxsl[fr->callno]);
10329          return 1;
10330       }
10331 
10332       /* when we receive the first full frame for a new incoming channel,
10333          it is safe to start the PBX on the channel because we have now
10334          completed a 3-way handshake with the peer */
10335       if ((f.frametype == AST_FRAME_VOICE) ||
10336           (f.frametype == AST_FRAME_VIDEO) ||
10337           (f.frametype == AST_FRAME_IAX)) {
10338          if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10339             ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10340             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
10341                ast_variables_destroy(ies.vars);
10342                ast_mutex_unlock(&iaxsl[fr->callno]);
10343                return 1;
10344             }
10345          }
10346 
10347          if (ies.vars) {
10348             struct ast_datastore *variablestore = NULL;
10349             struct ast_variable *var, *prev = NULL;
10350             AST_LIST_HEAD(, ast_var_t) *varlist;
10351 
10352             iax2_lock_owner(fr->callno);
10353             if (!iaxs[fr->callno]) {
10354                ast_variables_destroy(ies.vars);
10355                ast_mutex_unlock(&iaxsl[fr->callno]);
10356                return 1;
10357             }
10358             if ((c = iaxs[fr->callno]->owner)) {
10359                varlist = ast_calloc(1, sizeof(*varlist));
10360                variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10361 
10362                if (variablestore && varlist) {
10363                   variablestore->data = varlist;
10364                   variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10365                   AST_LIST_HEAD_INIT(varlist);
10366                   ast_debug(1, "I can haz IAX vars?\n");
10367                   for (var = ies.vars; var; var = var->next) {
10368                      struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10369                      if (prev) {
10370                         ast_free(prev);
10371                      }
10372                      prev = var;
10373                      if (!newvar) {
10374                         /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
10375                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10376                      } else {
10377                         AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10378                      }
10379                   }
10380                   if (prev) {
10381                      ast_free(prev);
10382                   }
10383                   ies.vars = NULL;
10384                   ast_channel_datastore_add(c, variablestore);
10385                } else {
10386                   ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10387                   if (variablestore) {
10388                      ast_datastore_free(variablestore);
10389                   }
10390                   if (varlist) {
10391                      ast_free(varlist);
10392                   }
10393                }
10394                ast_channel_unlock(c);
10395             } else {
10396                /* No channel yet, so transfer the variables directly over to the pvt,
10397                 * for later inheritance. */
10398                ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10399                for (var = ies.vars; var && var->next; var = var->next);
10400                if (var) {
10401                   var->next = iaxs[fr->callno]->iaxvars;
10402                   iaxs[fr->callno]->iaxvars = ies.vars;
10403                   ies.vars = NULL;
10404                }
10405             }
10406          }
10407 
10408          if (ies.vars) {
10409             ast_debug(1, "I have IAX variables, but they were not processed\n");
10410          }
10411       }
10412 
10413       /* once we receive our first IAX Full Frame that is not CallToken related, send all
10414        * queued signaling frames that were being held. */
10415       if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10416          send_signaling(iaxs[fr->callno]);
10417       }
10418 
10419       if (f.frametype == AST_FRAME_VOICE) {
10420          if (ast_format_to_old_bitfield(&f.subclass.format) != iaxs[fr->callno]->voiceformat) {
10421                iaxs[fr->callno]->voiceformat = ast_format_to_old_bitfield(&f.subclass.format);
10422                ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(&f.subclass.format));
10423                if (iaxs[fr->callno]->owner) {
10424                   iax2_lock_owner(fr->callno);
10425                   if (iaxs[fr->callno]) {
10426                      if (iaxs[fr->callno]->owner) {
10427                         struct ast_format_cap *orignative = ast_format_cap_dup(iaxs[fr->callno]->owner->nativeformats);
10428                         struct ast_format_cap *native = iaxs[fr->callno]->owner->nativeformats;
10429                         if (orignative) {
10430                            ast_format_cap_set(native, &f.subclass.format);
10431                            if (iaxs[fr->callno]->owner->readformat.id) {
10432                               ast_set_read_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->readformat);
10433                            }
10434                            ast_format_cap_copy(native, orignative);
10435                            ast_channel_unlock(iaxs[fr->callno]->owner);
10436                            orignative = ast_format_cap_destroy(orignative);
10437                         }
10438                      }
10439                   } else {
10440                      ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10441                      /* Free remote variables (if any) */
10442                      if (ies.vars) {
10443                         ast_variables_destroy(ies.vars);
10444                         ast_debug(1, "I can haz iaxvars, but they is no good.  :-(\n");
10445                         ies.vars = NULL;
10446                      }
10447                      ast_mutex_unlock(&iaxsl[fr->callno]);
10448                      return 1;
10449                   }
10450                }
10451          }
10452       }
10453       if (f.frametype == AST_FRAME_VIDEO) {
10454          if (f.subclass.format.id != ast_format_id_from_old_bitfield(iaxs[fr->callno]->videoformat)) {
10455             ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(&f.subclass.format));
10456             iaxs[fr->callno]->videoformat = ast_format_to_old_bitfield(&f.subclass.format);
10457          }
10458       }
10459       if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10460          if (f.subclass.integer == AST_CONTROL_BUSY) {
10461             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10462          } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
10463             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10464          }
10465       }
10466       if (f.frametype == AST_FRAME_IAX) {
10467          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
10468          /* Handle the IAX pseudo frame itself */
10469          if (iaxdebug)
10470             ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10471 
10472                         /* Update last ts unless the frame's timestamp originated with us. */
10473          if (iaxs[fr->callno]->last < fr->ts &&
10474                             f.subclass.integer != IAX_COMMAND_ACK &&
10475                             f.subclass.integer != IAX_COMMAND_PONG &&
10476                             f.subclass.integer != IAX_COMMAND_LAGRP) {
10477             iaxs[fr->callno]->last = fr->ts;
10478             if (iaxdebug)
10479                ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10480          }
10481          iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10482          if (!iaxs[fr->callno]->first_iax_message) {
10483             iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10484          }
10485          switch(f.subclass.integer) {
10486          case IAX_COMMAND_ACK:
10487             /* Do nothing */
10488             break;
10489          case IAX_COMMAND_QUELCH:
10490             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10491                     /* Generate Manager Hold event, if necessary*/
10492                if (iaxs[fr->callno]->owner) {
10493                   ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10494                      "Status: On\r\n"
10495                      "Channel: %s\r\n"
10496                      "Uniqueid: %s\r\n",
10497                      ast_channel_name(iaxs[fr->callno]->owner),
10498                      ast_channel_uniqueid(iaxs[fr->callno]->owner));
10499                }
10500 
10501                ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10502                if (ies.musiconhold) {
10503                   iax2_lock_owner(fr->callno);
10504                   if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10505                      break;
10506                   }
10507                   if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10508                      const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10509 
10510                      /*
10511                       * We already hold the owner lock so we do not
10512                       * need to check iaxs[fr->callno] after it returns.
10513                       */
10514                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
10515                         S_OR(moh_suggest, NULL),
10516                         !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10517                   }
10518                   ast_channel_unlock(iaxs[fr->callno]->owner);
10519                }
10520             }
10521             break;
10522          case IAX_COMMAND_UNQUELCH:
10523             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10524                iax2_lock_owner(fr->callno);
10525                if (!iaxs[fr->callno]) {
10526                   break;
10527                }
10528                /* Generate Manager Unhold event, if necessary */
10529                if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10530                   ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10531                      "Status: Off\r\n"
10532                      "Channel: %s\r\n"
10533                      "Uniqueid: %s\r\n",
10534                      ast_channel_name(iaxs[fr->callno]->owner),
10535                      ast_channel_uniqueid(iaxs[fr->callno]->owner));
10536                }
10537 
10538                ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10539                if (!iaxs[fr->callno]->owner) {
10540                   break;
10541                }
10542                if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10543                   /*
10544                    * We already hold the owner lock so we do not
10545                    * need to check iaxs[fr->callno] after it returns.
10546                    */
10547                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10548                }
10549                ast_channel_unlock(iaxs[fr->callno]->owner);
10550             }
10551             break;
10552          case IAX_COMMAND_TXACC:
10553             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10554                /* Ack the packet with the given timestamp */
10555                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10556                   /* Cancel any outstanding txcnt's */
10557                   if (cur->transfer) {
10558                      cur->retries = -1;
10559                   }
10560                }
10561                memset(&ied1, 0, sizeof(ied1));
10562                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10563                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10564                iaxs[fr->callno]->transferring = TRANSFER_READY;
10565             }
10566             break;
10567          case IAX_COMMAND_NEW:
10568             /* Ignore if it's already up */
10569             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10570                break;
10571             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10572                ast_mutex_unlock(&iaxsl[fr->callno]);
10573                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10574                ast_mutex_lock(&iaxsl[fr->callno]);
10575                if (!iaxs[fr->callno]) {
10576                   break;
10577                }
10578             }
10579             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
10580             if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10581                int new_callno;
10582                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10583                   fr->callno = new_callno;
10584             }
10585             /* For security, always ack immediately */
10586             if (delayreject)
10587                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10588             if (check_access(fr->callno, &sin, &ies)) {
10589                /* They're not allowed on */
10590                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10591                if (authdebug)
10592                   ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
10593                break;
10594             }
10595             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10596                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10597                ast_log(LOG_WARNING, "Rejected connect attempt.  No secret present while force encrypt enabled.\n");
10598                break;
10599             }
10600             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10601                const char *context, *exten, *cid_num;
10602 
10603                context = ast_strdupa(iaxs[fr->callno]->context);
10604                exten = ast_strdupa(iaxs[fr->callno]->exten);
10605                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10606 
10607                /* This might re-enter the IAX code and need the lock */
10608                ast_mutex_unlock(&iaxsl[fr->callno]);
10609                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10610                ast_mutex_lock(&iaxsl[fr->callno]);
10611 
10612                if (!iaxs[fr->callno]) {
10613                   break;
10614                }
10615             } else
10616                exists = 0;
10617             /* Get OSP token if it does exist */
10618             save_osptoken(fr, &ies);
10619             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10620                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10621                   memset(&ied0, 0, sizeof(ied0));
10622                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10623                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10624                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10625                   if (!iaxs[fr->callno]) {
10626                      break;
10627                   }
10628                   if (authdebug)
10629                      ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
10630                } else {
10631                   /* Select an appropriate format */
10632 
10633                   if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10634                      if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10635                         using_prefs = "reqonly";
10636                      } else {
10637                         using_prefs = "disabled";
10638                      }
10639                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10640                      memset(&pref, 0, sizeof(pref));
10641                      strcpy(caller_pref_buf, "disabled");
10642                      strcpy(host_pref_buf, "disabled");
10643                   } else {
10644                      struct ast_format tmpfmt;
10645                      using_prefs = "mine";
10646                      /* If the information elements are in here... use them */
10647                      if (ies.codec_prefs)
10648                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10649                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
10650                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
10651                         if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10652                            pref = iaxs[fr->callno]->rprefs;
10653                            using_prefs = "caller";
10654                         } else {
10655                            pref = iaxs[fr->callno]->prefs;
10656                         }
10657                      } else
10658                         pref = iaxs[fr->callno]->prefs;
10659 
10660                      format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10661                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10662                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10663                   }
10664                   if (!format) {
10665                      if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10666                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10667                      if (!format) {
10668                         memset(&ied0, 0, sizeof(ied0));
10669                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10670                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10671                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10672                         if (!iaxs[fr->callno]) {
10673                            break;
10674                         }
10675                         if (authdebug) {
10676                            char tmp[256], tmp2[256], tmp3[256];
10677                            if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10678                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10679                                  ast_inet_ntoa(sin.sin_addr),
10680                                  iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10681                                  iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10682                            } else {
10683                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10684                                  ast_inet_ntoa(sin.sin_addr),
10685                                  iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10686                                  iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10687                                  iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10688                            }
10689                         }
10690                      } else {
10691                         /* Pick one... */
10692                         if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10693                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10694                               format = 0;
10695                         } else {
10696                            if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10697                               using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10698                               memset(&pref, 0, sizeof(pref));
10699                               format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10700                               strcpy(caller_pref_buf,"disabled");
10701                               strcpy(host_pref_buf,"disabled");
10702                            } else {
10703                               struct ast_format tmpfmt;
10704                               using_prefs = "mine";
10705                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
10706                                  /* Do the opposite of what we tried above. */
10707                                  if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10708                                     pref = iaxs[fr->callno]->prefs;
10709                                  } else {
10710                                     pref = iaxs[fr->callno]->rprefs;
10711                                     using_prefs = "caller";
10712                                  }
10713                                  format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10714                               } else /* if no codec_prefs IE do it the old way */
10715                                  format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10716                            }
10717                         }
10718 
10719                         if (!format) {
10720                            char tmp[256], tmp2[256], tmp3[256];
10721                            memset(&ied0, 0, sizeof(ied0));
10722                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10723                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10724                            ast_log(LOG_ERROR, "No best format in '%s'???\n", iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10725                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10726                            if (!iaxs[fr->callno]) {
10727                               break;
10728                            }
10729                            if (authdebug) {
10730                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10731                                  ast_inet_ntoa(sin.sin_addr),
10732                                  iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10733                                  iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10734                                  iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10735                            }
10736                            ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10737                            break;
10738                         }
10739                      }
10740                   }
10741                   if (format) {
10742                      /* No authentication required, let them in */
10743                      memset(&ied1, 0, sizeof(ied1));
10744                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10745                      iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10746                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10747                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10748                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10749                         ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10750                                     "%srequested format = %s,\n"
10751                                     "%srequested prefs = %s,\n"
10752                                     "%sactual format = %s,\n"
10753                                     "%shost prefs = %s,\n"
10754                                     "%spriority = %s\n",
10755                                     ast_inet_ntoa(sin.sin_addr), 
10756                                     VERBOSE_PREFIX_4,
10757                                     iax2_getformatname(iaxs[fr->callno]->peerformat), 
10758                                     VERBOSE_PREFIX_4,
10759                                     caller_pref_buf,
10760                                     VERBOSE_PREFIX_4,
10761                                     iax2_getformatname(format), 
10762                                     VERBOSE_PREFIX_4,
10763                                     host_pref_buf, 
10764                                     VERBOSE_PREFIX_4,
10765                                     using_prefs);
10766 
10767                         iaxs[fr->callno]->chosenformat = format;
10768                         ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10769                      } else {
10770                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10771                         /* If this is a TBD call, we're ready but now what...  */
10772                         ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10773                      }
10774                   }
10775                }
10776                break;
10777             }
10778             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10779                merge_encryption(iaxs[fr->callno],ies.encmethods);
10780             else
10781                iaxs[fr->callno]->encmethods = 0;
10782             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10783                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10784             break;
10785          case IAX_COMMAND_DPREQ:
10786             /* Request status in the dialplan */
10787             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10788                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10789                if (iaxcompat) {
10790                   /* Spawn a thread for the lookup */
10791                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10792                } else {
10793                   /* Just look it up */
10794                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10795                }
10796             }
10797             break;
10798          case IAX_COMMAND_HANGUP:
10799             ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10800             ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10801             /* Set hangup cause according to remote and hangupsource */
10802             if (iaxs[fr->callno]->owner) {
10803                set_hangup_source_and_cause(fr->callno, ies.causecode);
10804                if (!iaxs[fr->callno]) {
10805                   break;
10806                }
10807             }
10808 
10809             /* Send ack immediately, before we destroy */
10810             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10811             iax2_destroy(fr->callno);
10812             break;
10813          case IAX_COMMAND_REJECT:
10814             /* Set hangup cause according to remote and hangup source */
10815             if (iaxs[fr->callno]->owner) {
10816                set_hangup_source_and_cause(fr->callno, ies.causecode);
10817                if (!iaxs[fr->callno]) {
10818                   break;
10819                }
10820             }
10821 
10822             if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10823                if (iaxs[fr->callno]->owner && authdebug)
10824                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10825                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10826                      ies.cause ? ies.cause : "<Unknown>");
10827                ast_debug(1, "Immediately destroying %d, having received reject\n",
10828                   fr->callno);
10829             }
10830             /* Send ack immediately, before we destroy */
10831             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10832                          fr->ts, NULL, 0, fr->iseqno);
10833             if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10834                iaxs[fr->callno]->error = EPERM;
10835             iax2_destroy(fr->callno);
10836             break;
10837          case IAX_COMMAND_TRANSFER:
10838          {
10839             struct ast_channel *bridged_chan;
10840             struct ast_channel *owner;
10841 
10842             iax2_lock_owner(fr->callno);
10843             if (!iaxs[fr->callno]) {
10844                /* Initiating call went away before we could transfer. */
10845                break;
10846             }
10847             owner = iaxs[fr->callno]->owner;
10848             bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10849             if (bridged_chan && ies.called_number) {
10850                const char *context;
10851 
10852                context = ast_strdupa(iaxs[fr->callno]->context);
10853 
10854                ast_channel_ref(owner);
10855                ast_channel_ref(bridged_chan);
10856                ast_channel_unlock(owner);
10857                ast_mutex_unlock(&iaxsl[fr->callno]);
10858 
10859                /* Set BLINDTRANSFER channel variables */
10860                pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", ast_channel_name(bridged_chan));
10861                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", ast_channel_name(owner));
10862 
10863                /* DO NOT hold any locks while calling ast_parking_ext_valid() */
10864                if (ast_parking_ext_valid(ies.called_number, owner, context)) {
10865                   ast_debug(1, "Parking call '%s'\n", ast_channel_name(bridged_chan));
10866                   if (iax_park(bridged_chan, owner, ies.called_number, context)) {
10867                      ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10868                         ast_channel_name(bridged_chan));
10869                   }
10870                } else {
10871                   if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) {
10872                      ast_log(LOG_WARNING,
10873                         "Async goto of '%s' to '%s@%s' failed\n",
10874                         ast_channel_name(bridged_chan), ies.called_number, context);
10875                   } else {
10876                      ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10877                         ast_channel_name(bridged_chan), ies.called_number, context);
10878                   }
10879                }
10880                ast_channel_unref(owner);
10881                ast_channel_unref(bridged_chan);
10882 
10883                ast_mutex_lock(&iaxsl[fr->callno]);
10884             } else {
10885                ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10886                if (owner) {
10887                   ast_channel_unlock(owner);
10888                }
10889             }
10890 
10891             break;
10892          }
10893          case IAX_COMMAND_ACCEPT:
10894             /* Ignore if call is already up or needs authentication or is a TBD */
10895             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10896                break;
10897             if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10898                /* Send ack immediately, before we destroy */
10899                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10900                iax2_destroy(fr->callno);
10901                break;
10902             }
10903             if (ies.format) {
10904                iaxs[fr->callno]->peerformat = ies.format;
10905             } else {
10906                if (iaxs[fr->callno]->owner)
10907                   iaxs[fr->callno]->peerformat = ast_format_cap_to_old_bitfield(iaxs[fr->callno]->owner->nativeformats);
10908                else
10909                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10910             }
10911             ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iax2_getformatname(iaxs[fr->callno]->peerformat));
10912             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10913                memset(&ied0, 0, sizeof(ied0));
10914                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10915                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10916                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10917                if (!iaxs[fr->callno]) {
10918                   break;
10919                }
10920                if (authdebug) {
10921                   char tmp1[256], tmp2[256];
10922                   ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
10923                      ast_inet_ntoa(sin.sin_addr),
10924                      iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10925                      iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10926                }
10927             } else {
10928                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10929                iax2_lock_owner(fr->callno);
10930                if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10931                   char tmp[256];
10932                   /* Switch us to use a compatible format */
10933                   ast_format_cap_from_old_bitfield(iaxs[fr->callno]->owner->nativeformats, iaxs[fr->callno]->peerformat);
10934                   ast_verb(3, "Format for call is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->owner->nativeformats));
10935 
10936                   /* Setup read/write formats properly. */
10937                   if (iaxs[fr->callno]->owner->writeformat.id)
10938                      ast_set_write_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->writeformat);
10939                   if (iaxs[fr->callno]->owner->readformat.id)
10940                      ast_set_read_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->readformat);
10941                   ast_channel_unlock(iaxs[fr->callno]->owner);
10942                }
10943             }
10944             if (iaxs[fr->callno]) {
10945                AST_LIST_LOCK(&dpcache);
10946                AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10947                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10948                      iax2_dprequest(dp, fr->callno);
10949                AST_LIST_UNLOCK(&dpcache);
10950             }
10951             break;
10952          case IAX_COMMAND_POKE:
10953             /* Send back a pong packet with the original timestamp */
10954             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10955             break;
10956          case IAX_COMMAND_PING:
10957          {
10958             struct iax_ie_data pingied;
10959             construct_rr(iaxs[fr->callno], &pingied);
10960             /* Send back a pong packet with the original timestamp */
10961             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10962          }
10963             break;
10964          case IAX_COMMAND_PONG:
10965             /* Calculate ping time */
10966             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10967             /* save RR info */
10968             save_rr(fr, &ies);
10969 
10970             /* Good time to write jb stats for this call */
10971             log_jitterstats(fr->callno);
10972 
10973             if (iaxs[fr->callno]->peerpoke) {
10974                peer = iaxs[fr->callno]->peerpoke;
10975                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
10976                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10977                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10978                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
10979                      ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */
10980                   }
10981                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10982                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
10983                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10984                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
10985                      ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
10986                   }
10987                }
10988                peer->lastms = iaxs[fr->callno]->pingtime;
10989                if (peer->smoothing && (peer->lastms > -1))
10990                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10991                else if (peer->smoothing && peer->lastms < 0)
10992                   peer->historicms = (0 + peer->historicms) / 2;
10993                else              
10994                   peer->historicms = iaxs[fr->callno]->pingtime;
10995 
10996                /* Remove scheduled iax2_poke_noanswer */
10997                if (peer->pokeexpire > -1) {
10998                   if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
10999                      peer_unref(peer);
11000                      peer->pokeexpire = -1;
11001                   }
11002                }
11003                /* Schedule the next cycle */
11004                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms))
11005                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11006                else
11007                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
11008                if (peer->pokeexpire == -1)
11009                   peer_unref(peer);
11010                /* and finally send the ack */
11011                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11012                /* And wrap up the qualify call */
11013                iax2_destroy(fr->callno);
11014                peer->callno = 0;
11015                ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
11016             }
11017             break;
11018          case IAX_COMMAND_LAGRQ:
11019          case IAX_COMMAND_LAGRP:
11020             f.src = "LAGRQ";
11021             f.mallocd = 0;
11022             f.offset = 0;
11023             f.samples = 0;
11024             iax_frame_wrap(fr, &f);
11025             if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
11026                /* Received a LAGRQ - echo back a LAGRP */
11027                fr->af.subclass.integer = IAX_COMMAND_LAGRP;
11028                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
11029             } else {
11030                /* Received LAGRP in response to our LAGRQ */
11031                unsigned int ts;
11032                /* This is a reply we've been given, actually measure the difference */
11033                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
11034                iaxs[fr->callno]->lag = ts - fr->ts;
11035                if (iaxdebug)
11036                   ast_debug(1, "Peer %s lag measured as %dms\n",
11037                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
11038             }
11039             break;
11040          case IAX_COMMAND_AUTHREQ:
11041             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11042                ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11043                break;
11044             }
11045             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
11046                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
11047                         .subclass.integer = AST_CONTROL_HANGUP,
11048                };
11049                ast_log(LOG_WARNING, 
11050                   "I don't know how to authenticate %s to %s\n", 
11051                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
11052                iax2_queue_frame(fr->callno, &hangup_fr);
11053             }
11054             break;
11055          case IAX_COMMAND_AUTHREP:
11056             /* For security, always ack immediately */
11057             if (delayreject)
11058                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11059             /* Ignore once we've started */
11060             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11061                ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11062                break;
11063             }
11064             if (authenticate_verify(iaxs[fr->callno], &ies)) {
11065                if (authdebug)
11066                   ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username);
11067                memset(&ied0, 0, sizeof(ied0));
11068                auth_fail(fr->callno, IAX_COMMAND_REJECT);
11069                break;
11070             }
11071             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
11072                /* This might re-enter the IAX code and need the lock */
11073                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
11074             } else
11075                exists = 0;
11076             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
11077                if (authdebug)
11078                   ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
11079                memset(&ied0, 0, sizeof(ied0));
11080                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11081                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11082                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11083                if (!iaxs[fr->callno]) {
11084                   break;
11085                }
11086             } else {
11087                /* Select an appropriate format */
11088                if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11089                   if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11090                      using_prefs = "reqonly";
11091                   } else {
11092                      using_prefs = "disabled";
11093                   }
11094                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
11095                   memset(&pref, 0, sizeof(pref));
11096                   strcpy(caller_pref_buf, "disabled");
11097                   strcpy(host_pref_buf, "disabled");
11098                } else {
11099                   struct ast_format tmpfmt;
11100                   using_prefs = "mine";
11101                   if (ies.codec_prefs)
11102                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11103                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11104                      if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11105                         pref = iaxs[fr->callno]->rprefs;
11106                         using_prefs = "caller";
11107                      } else {
11108                         pref = iaxs[fr->callno]->prefs;
11109                      }
11110                   } else /* if no codec_prefs IE do it the old way */
11111                      pref = iaxs[fr->callno]->prefs;
11112                   format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
11113                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11114                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11115                }
11116                if (!format) {
11117                   char tmp1[256], tmp2[256], tmp3[256];
11118                   if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11119                      ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11120                         iax2_getformatname(iaxs[fr->callno]->peerformat),
11121                         iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
11122                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11123                   }
11124                   if (!format) {
11125                      if (authdebug) {
11126                         if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11127                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
11128                               iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11129                               iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11130                         } else {
11131                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11132                               ast_inet_ntoa(sin.sin_addr),
11133                               iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11134                               iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11135                               iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11136                         }
11137                      }
11138                      memset(&ied0, 0, sizeof(ied0));
11139                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11140                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11141                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11142                      if (!iaxs[fr->callno]) {
11143                         break;
11144                      }
11145                   } else {
11146                      /* Pick one... */
11147                      if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11148                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11149                            format = 0;
11150                      } else {
11151                         if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11152                            using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11153                            memset(&pref, 0, sizeof(pref));
11154                            format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
11155                               iaxs[fr->callno]->peerformat : iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11156                            strcpy(caller_pref_buf,"disabled");
11157                            strcpy(host_pref_buf,"disabled");
11158                         } else {
11159                            struct ast_format tmpfmt;
11160                            using_prefs = "mine";
11161                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11162                               /* Do the opposite of what we tried above. */
11163                               if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11164                                  pref = iaxs[fr->callno]->prefs;
11165                               } else {
11166                                  pref = iaxs[fr->callno]->rprefs;
11167                                  using_prefs = "caller";
11168                               }
11169                               format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11170                            } else /* if no codec_prefs IE do it the old way */
11171                               format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);   
11172                         }
11173                      }
11174                      if (!format) {
11175                         char tmp1[256], tmp2[256], tmp3[256];
11176                         ast_log(LOG_ERROR, "No best format in %s???\n",
11177                            iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11178                         if (authdebug) {
11179                            if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11180                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11181                                  ast_inet_ntoa(sin.sin_addr),
11182                                  iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11183                                  iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11184                            } else {
11185                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11186                                  ast_inet_ntoa(sin.sin_addr),
11187                                  iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11188                                  iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11189                                  iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11190                            }
11191                         }
11192                         memset(&ied0, 0, sizeof(ied0));
11193                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11194                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11195                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11196                         if (!iaxs[fr->callno]) {
11197                            break;
11198                         }
11199                      }
11200                   }
11201                }
11202                if (format) {
11203                   /* Authentication received */
11204                   memset(&ied1, 0, sizeof(ied1));
11205                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11206                   iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11207                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11208                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11209                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11210                      ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11211                                  "%srequested format = %s,\n"
11212                                  "%srequested prefs = %s,\n"
11213                                  "%sactual format = %s,\n"
11214                                  "%shost prefs = %s,\n"
11215                                  "%spriority = %s\n", 
11216                                  ast_inet_ntoa(sin.sin_addr), 
11217                                  VERBOSE_PREFIX_4,
11218                                  iax2_getformatname(iaxs[fr->callno]->peerformat),
11219                                  VERBOSE_PREFIX_4,
11220                                  caller_pref_buf,
11221                                  VERBOSE_PREFIX_4,
11222                                  iax2_getformatname(format),
11223                                  VERBOSE_PREFIX_4,
11224                                  host_pref_buf,
11225                                  VERBOSE_PREFIX_4,
11226                                  using_prefs);
11227 
11228                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11229                      if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
11230                         iax2_destroy(fr->callno);
11231                      else if (ies.vars) {
11232                         struct ast_datastore *variablestore;
11233                         struct ast_variable *var, *prev = NULL;
11234                         AST_LIST_HEAD(, ast_var_t) *varlist;
11235                         varlist = ast_calloc(1, sizeof(*varlist));
11236                         variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11237                         if (variablestore && varlist) {
11238                            variablestore->data = varlist;
11239                            variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11240                            AST_LIST_HEAD_INIT(varlist);
11241                            ast_debug(1, "I can haz IAX vars? w00t\n");
11242                            for (var = ies.vars; var; var = var->next) {
11243                               struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11244                               if (prev)
11245                                  ast_free(prev);
11246                               prev = var;
11247                               if (!newvar) {
11248                                  /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11249                                  ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11250                               } else {
11251                                  AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11252                               }
11253                            }
11254                            if (prev)
11255                               ast_free(prev);
11256                            ies.vars = NULL;
11257                            ast_channel_datastore_add(c, variablestore);
11258                         } else {
11259                            ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11260                            if (variablestore)
11261                               ast_datastore_free(variablestore);
11262                            if (varlist)
11263                               ast_free(varlist);
11264                         }
11265                      }
11266                   } else {
11267                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11268                      /* If this is a TBD call, we're ready but now what...  */
11269                      ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11270                      if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11271                         goto immediatedial;
11272                      }
11273                   }
11274                }
11275             }
11276             break;
11277          case IAX_COMMAND_DIAL:
11278 immediatedial:
11279             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11280                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11281                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11282                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11283                   if (authdebug)
11284                      ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
11285                   memset(&ied0, 0, sizeof(ied0));
11286                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11287                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11288                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11289                   if (!iaxs[fr->callno]) {
11290                      break;
11291                   }
11292                } else {
11293                   char tmp[256];
11294                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11295                   ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11296                      ast_inet_ntoa(sin.sin_addr),
11297                      iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11298                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11299                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11300                   if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
11301                      iax2_destroy(fr->callno);
11302                   else if (ies.vars) {
11303                      struct ast_datastore *variablestore;
11304                      struct ast_variable *var, *prev = NULL;
11305                      AST_LIST_HEAD(, ast_var_t) *varlist;
11306                      varlist = ast_calloc(1, sizeof(*varlist));
11307                      variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11308                      ast_debug(1, "I can haz IAX vars? w00t\n");
11309                      if (variablestore && varlist) {
11310                         variablestore->data = varlist;
11311                         variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11312                         AST_LIST_HEAD_INIT(varlist);
11313                         for (var = ies.vars; var; var = var->next) {
11314                            struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11315                            if (prev)
11316                               ast_free(prev);
11317                            prev = var;
11318                            if (!newvar) {
11319                               /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11320                               ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11321                            } else {
11322                               AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11323                            }
11324                         }
11325                         if (prev)
11326                            ast_free(prev);
11327                         ies.vars = NULL;
11328                         ast_channel_datastore_add(c, variablestore);
11329                      } else {
11330                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11331                         if (variablestore)
11332                            ast_datastore_free(variablestore);
11333                         if (varlist)
11334                            ast_free(varlist);
11335                      }
11336                   }
11337                }
11338             }
11339             break;
11340          case IAX_COMMAND_INVAL:
11341             iaxs[fr->callno]->error = ENOTCONN;
11342             ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11343             iax2_destroy(fr->callno);
11344             ast_debug(1, "Destroying call %d\n", fr->callno);
11345             break;
11346          case IAX_COMMAND_VNAK:
11347             ast_debug(1, "Received VNAK: resending outstanding frames\n");
11348             /* Force retransmission */
11349             vnak_retransmit(fr->callno, fr->iseqno);
11350             break;
11351          case IAX_COMMAND_REGREQ:
11352          case IAX_COMMAND_REGREL:
11353             /* For security, always ack immediately */
11354             if (delayreject)
11355                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11356             if (register_verify(fr->callno, &sin, &ies)) {
11357                if (!iaxs[fr->callno]) {
11358                   break;
11359                }
11360                /* Send delayed failure */
11361                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11362                break;
11363             }
11364             if (!iaxs[fr->callno]) {
11365                break;
11366             }
11367             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11368                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11369 
11370                if (f.subclass.integer == IAX_COMMAND_REGREL) {
11371                   memset(&sin, 0, sizeof(sin));
11372                   sin.sin_family = AF_INET;
11373                }
11374                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11375                   ast_log(LOG_WARNING, "Registry error\n");
11376                }
11377                if (!iaxs[fr->callno]) {
11378                   break;
11379                }
11380                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11381                   ast_mutex_unlock(&iaxsl[fr->callno]);
11382                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11383                   ast_mutex_lock(&iaxsl[fr->callno]);
11384                }
11385                break;
11386             }
11387             registry_authrequest(fr->callno);
11388             break;
11389          case IAX_COMMAND_REGACK:
11390             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
11391                ast_log(LOG_WARNING, "Registration failure\n");
11392             /* Send ack immediately, before we destroy */
11393             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11394             iax2_destroy(fr->callno);
11395             break;
11396          case IAX_COMMAND_REGREJ:
11397             if (iaxs[fr->callno]->reg) {
11398                if (authdebug) {
11399                   ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>", ast_inet_ntoa(sin.sin_addr));
11400                   manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
11401                }
11402                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11403             }
11404             /* Send ack immediately, before we destroy */
11405             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11406             iax2_destroy(fr->callno);
11407             break;
11408          case IAX_COMMAND_REGAUTH:
11409             /* Authentication request */
11410             if (registry_rerequest(&ies, fr->callno, &sin)) {
11411                memset(&ied0, 0, sizeof(ied0));
11412                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11413                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11414                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11415             }
11416             break;
11417          case IAX_COMMAND_TXREJ:
11418             iaxs[fr->callno]->transferring = 0;
11419             ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11420             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11421             if (iaxs[fr->callno]->bridgecallno) {
11422                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11423                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
11424                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11425                }
11426             }
11427             break;
11428          case IAX_COMMAND_TXREADY:
11429             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
11430                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
11431                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
11432                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11433                else
11434                   iaxs[fr->callno]->transferring = TRANSFER_READY;
11435                ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11436                if (iaxs[fr->callno]->bridgecallno) {
11437                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
11438                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
11439                      /* They're both ready, now release them. */
11440                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11441                         ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
11442                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : "<Unknown>");
11443 
11444                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11445                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11446 
11447                         memset(&ied0, 0, sizeof(ied0));
11448                         memset(&ied1, 0, sizeof(ied1));
11449                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11450                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11451                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11452                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11453                      } else {
11454                         ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
11455                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : "<Unknown>");
11456 
11457                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11458                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11459                         ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11460                         ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11461 
11462                         /* Stop doing lag & ping requests */
11463                         stop_stuff(fr->callno);
11464                         stop_stuff(iaxs[fr->callno]->bridgecallno);
11465 
11466                         memset(&ied0, 0, sizeof(ied0));
11467                         memset(&ied1, 0, sizeof(ied1));
11468                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11469                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11470                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11471                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11472                      }
11473 
11474                   }
11475                }
11476             }
11477             break;
11478          case IAX_COMMAND_TXREQ:
11479             try_transfer(iaxs[fr->callno], &ies);
11480             break;
11481          case IAX_COMMAND_TXCNT:
11482             if (iaxs[fr->callno]->transferring)
11483                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11484             break;
11485          case IAX_COMMAND_TXREL:
11486             /* Send ack immediately, rather than waiting until we've changed addresses */
11487             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11488             complete_transfer(fr->callno, &ies);
11489             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
11490             break;   
11491          case IAX_COMMAND_TXMEDIA:
11492             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11493                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11494                   /* Cancel any outstanding frames and start anew */
11495                   if (cur->transfer) {
11496                      cur->retries = -1;
11497                   }
11498                }
11499                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
11500                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11501             }
11502             break;
11503          case IAX_COMMAND_RTKEY:
11504             if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11505                ast_log(LOG_WARNING, 
11506                   "we've been told to rotate our encryption key, "
11507                   "but this isn't an encrypted call. bad things will happen.\n"
11508                );
11509                break;
11510             }
11511 
11512             IAX_DEBUGDIGEST("Receiving", ies.challenge);
11513 
11514             ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11515             break;
11516          case IAX_COMMAND_DPREP:
11517             complete_dpreply(iaxs[fr->callno], &ies);
11518             break;
11519          case IAX_COMMAND_UNSUPPORT:
11520             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11521             break;
11522          case IAX_COMMAND_FWDOWNL:
11523             /* Firmware download */
11524             if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11525                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11526                break;
11527             }
11528             memset(&ied0, 0, sizeof(ied0));
11529             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11530             if (res < 0)
11531                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11532             else if (res > 0)
11533                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11534             else
11535                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11536             break;
11537          case IAX_COMMAND_CALLTOKEN:
11538          {
11539             struct iax_frame *cur;
11540             /* find last sent frame */
11541             if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11542                resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11543             }
11544             break;
11545          }
11546          default:
11547             ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11548             memset(&ied0, 0, sizeof(ied0));
11549             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11550             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11551          }
11552          /* Free remote variables (if any) */
11553          if (ies.vars) {
11554             ast_variables_destroy(ies.vars);
11555             ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11556             ies.vars = NULL;
11557          }
11558 
11559          /* Don't actually pass these frames along */
11560          if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11561            (f.subclass.integer != IAX_COMMAND_TXCNT) &&
11562            (f.subclass.integer != IAX_COMMAND_TXACC) &&
11563            (f.subclass.integer != IAX_COMMAND_INVAL) &&
11564            (f.subclass.integer != IAX_COMMAND_VNAK)) {
11565             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11566                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11567          }
11568          ast_mutex_unlock(&iaxsl[fr->callno]);
11569          return 1;
11570       }
11571       /* Unless this is an ACK or INVAL frame, ack it */
11572       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11573          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11574    } else if (minivid) {
11575       f.frametype = AST_FRAME_VIDEO;
11576       if (iaxs[fr->callno]->videoformat > 0) {
11577          if (ntohs(vh->ts) & 0x8000LL) {
11578             ast_format_set_video_mark(&f.subclass.format);
11579          }
11580          ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->videoformat);
11581       } else {
11582          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11583          iax2_vnak(fr->callno);
11584          ast_variables_destroy(ies.vars);
11585          ast_mutex_unlock(&iaxsl[fr->callno]);
11586          return 1;
11587       }
11588       f.datalen = res - sizeof(*vh);
11589       if (f.datalen)
11590          f.data.ptr = thread->buf + sizeof(*vh);
11591       else
11592          f.data.ptr = NULL;
11593 #ifdef IAXTESTS
11594       if (test_resync) {
11595          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11596       } else
11597 #endif /* IAXTESTS */
11598          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11599    } else {
11600       /* A mini frame */
11601       f.frametype = AST_FRAME_VOICE;
11602       if (iaxs[fr->callno]->voiceformat > 0)
11603          ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
11604       else {
11605          ast_debug(1, "Received mini frame before first full voice frame\n");
11606          iax2_vnak(fr->callno);
11607          ast_variables_destroy(ies.vars);
11608          ast_mutex_unlock(&iaxsl[fr->callno]);
11609          return 1;
11610       }
11611       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11612       if (f.datalen < 0) {
11613          ast_log(LOG_WARNING, "Datalen < 0?\n");
11614          ast_variables_destroy(ies.vars);
11615          ast_mutex_unlock(&iaxsl[fr->callno]);
11616          return 1;
11617       }
11618       if (f.datalen)
11619          f.data.ptr = thread->buf + sizeof(*mh);
11620       else
11621          f.data.ptr = NULL;
11622 #ifdef IAXTESTS
11623       if (test_resync) {
11624          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11625       } else
11626 #endif /* IAXTESTS */
11627       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11628       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
11629    }
11630    /* Don't pass any packets until we're started */
11631    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11632       ast_variables_destroy(ies.vars);
11633       ast_mutex_unlock(&iaxsl[fr->callno]);
11634       return 1;
11635    }
11636    /* Don't allow connected line updates unless we are configured to */
11637    if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) {
11638       struct ast_party_connected_line connected;
11639 
11640       if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11641          ast_variables_destroy(ies.vars);
11642          ast_mutex_unlock(&iaxsl[fr->callno]);
11643          return 1;
11644       }
11645 
11646       /* Initialize defaults */
11647       ast_party_connected_line_init(&connected);
11648       connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11649       connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11650 
11651       if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11652          ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11653          ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11654          iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11655 
11656          if (iaxs[fr->callno]->owner) {
11657             ast_set_callerid(iaxs[fr->callno]->owner,
11658                S_COR(connected.id.number.valid, connected.id.number.str, ""),
11659                S_COR(connected.id.name.valid, connected.id.name.str, ""),
11660                NULL);
11661             iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11662             iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11663          }
11664       }
11665       ast_party_connected_line_free(&connected);
11666    }
11667    /* Common things */
11668    f.src = "IAX2";
11669    f.mallocd = 0;
11670    f.offset = 0;
11671    f.len = 0;
11672    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11673       f.samples = ast_codec_get_samples(&f);
11674       /* We need to byteswap incoming slinear samples from network byte order */
11675       if (f.subclass.format.id == AST_FORMAT_SLINEAR)
11676          ast_frame_byteswap_be(&f);
11677    } else
11678       f.samples = 0;
11679    iax_frame_wrap(fr, &f);
11680 
11681    /* If this is our most recent packet, use it as our basis for timestamping */
11682    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11683       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
11684       fr->outoforder = 0;
11685    } else {
11686       if (iaxdebug && iaxs[fr->callno])
11687          ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last);
11688       fr->outoforder = -1;
11689    }
11690    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11691    duped_fr = iaxfrdup2(fr);
11692    if (duped_fr) {
11693       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11694    }
11695    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11696       iaxs[fr->callno]->last = fr->ts;
11697 #if 1
11698       if (iaxdebug)
11699          ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11700 #endif
11701    }
11702 
11703    /* Always run again */
11704    ast_variables_destroy(ies.vars);
11705    ast_mutex_unlock(&iaxsl[fr->callno]);
11706    return 1;
11707 }

static int socket_process_meta ( int  packet_len,
struct ast_iax2_meta_hdr meta,
struct sockaddr_in *  sin,
int  sockfd,
struct iax_frame fr 
) [static]

Definition at line 9743 of file chan_iax2.c.

References ast_codec_get_samples(), ast_format_from_old_bitfield(), AST_FRAME_VOICE, ast_inet_ntoa(), ast_log(), ast_mutex_unlock, ast_test_flag, ast_tvnow(), ast_tvzero(), iax_frame::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, ast_iax2_meta_hdr::cmddata, ast_frame::data, ast_iax2_meta_trunk_hdr::data, ast_iax2_meta_hdr::data, ast_frame::datalen, find_callno_locked(), find_tpeer(), fix_peerts(), ast_frame_subclass::format, ast_frame::frametype, iax2_vnak(), IAX_FLAG_FULL, iax_frame_wrap(), IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_STATE_STARTED, iaxfrdup2(), chan_iax2_pvt::last, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_frame::mallocd, ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, NEW_PREVENT, ast_frame::offset, iax_frame::outoforder, ast_frame::ptr, iax2_trunk_peer::rxtrunktime, ast_frame::samples, schedule_delivery(), ast_frame::src, chan_iax2_pvt::state, ast_frame::subclass, iax2_trunk_peer::trunkact, iax_frame::ts, ast_iax2_mini_hdr::ts, ast_iax2_meta_trunk_hdr::ts, and chan_iax2_pvt::voiceformat.

Referenced by socket_process().

09745 {
09746    unsigned char metatype;
09747    struct ast_iax2_meta_trunk_mini *mtm;
09748    struct ast_iax2_meta_trunk_hdr *mth;
09749    struct ast_iax2_meta_trunk_entry *mte;
09750    struct iax2_trunk_peer *tpeer;
09751    unsigned int ts;
09752    void *ptr;
09753    struct timeval rxtrunktime;
09754    struct ast_frame f = { 0, };
09755 
09756    if (packet_len < sizeof(*meta)) {
09757       ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 
09758          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09759       return 1;
09760    }
09761 
09762    if (meta->metacmd != IAX_META_TRUNK)
09763       return 1;
09764 
09765    if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09766       ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09767          (int) (sizeof(*meta) + sizeof(*mth)));
09768       return 1;
09769    }
09770    mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09771    ts = ntohl(mth->ts);
09772    metatype = meta->cmddata;
09773    packet_len -= (sizeof(*meta) + sizeof(*mth));
09774    ptr = mth->data;
09775    tpeer = find_tpeer(sin, sockfd);
09776    if (!tpeer) {
09777       ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 
09778          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09779       return 1;
09780    }
09781    tpeer->trunkact = ast_tvnow();
09782    if (!ts || ast_tvzero(tpeer->rxtrunktime))
09783       tpeer->rxtrunktime = tpeer->trunkact;
09784    rxtrunktime = tpeer->rxtrunktime;
09785    ast_mutex_unlock(&tpeer->lock);
09786    while (packet_len >= sizeof(*mte)) {
09787       /* Process channels */
09788       unsigned short callno, trunked_ts, len;
09789 
09790       if (metatype == IAX_META_TRUNK_MINI) {
09791          mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09792          ptr += sizeof(*mtm);
09793          packet_len -= sizeof(*mtm);
09794          len = ntohs(mtm->len);
09795          callno = ntohs(mtm->mini.callno);
09796          trunked_ts = ntohs(mtm->mini.ts);
09797       } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09798          mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09799          ptr += sizeof(*mte);
09800          packet_len -= sizeof(*mte);
09801          len = ntohs(mte->len);
09802          callno = ntohs(mte->callno);
09803          trunked_ts = 0;
09804       } else {
09805          ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09806          break;
09807       }
09808       /* Stop if we don't have enough data */
09809       if (len > packet_len)
09810          break;
09811       fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09812       if (!fr->callno)
09813          continue;
09814 
09815       /* If it's a valid call, deliver the contents.  If not, we
09816          drop it, since we don't have a scallno to use for an INVAL */
09817       /* Process as a mini frame */
09818       memset(&f, 0, sizeof(f));
09819       f.frametype = AST_FRAME_VOICE;
09820       if (!iaxs[fr->callno]) {
09821          /* drop it */
09822       } else if (iaxs[fr->callno]->voiceformat == 0) {
09823          ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09824          iax2_vnak(fr->callno);
09825       } else {
09826          ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
09827          f.datalen = len;
09828          if (f.datalen >= 0) {
09829             if (f.datalen)
09830                f.data.ptr = ptr;
09831             else
09832                f.data.ptr = NULL;
09833             if (trunked_ts)
09834                fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09835             else
09836                fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09837             /* Don't pass any packets until we're started */
09838             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09839                struct iax_frame *duped_fr;
09840 
09841                /* Common things */
09842                f.src = "IAX2";
09843                f.mallocd = 0;
09844                f.offset = 0;
09845                if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
09846                   f.samples = ast_codec_get_samples(&f);
09847                else
09848                   f.samples = 0;
09849                fr->outoforder = 0;
09850                iax_frame_wrap(fr, &f);
09851                duped_fr = iaxfrdup2(fr);
09852                if (duped_fr)
09853                   schedule_delivery(duped_fr, 1, 1, &fr->ts);
09854                if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09855                   iaxs[fr->callno]->last = fr->ts;
09856             }
09857          } else {
09858             ast_log(LOG_WARNING, "Datalen < 0?\n");
09859          }
09860       }
09861       ast_mutex_unlock(&iaxsl[fr->callno]);
09862       ptr += len;
09863       packet_len -= len;
09864    }
09865 
09866    return 1;
09867 }

static int socket_read ( int *  id,
int  fd,
short  events,
void *  cbdata 
) [static]

Definition at line 9664 of file chan_iax2.c.

References ast_copy_string(), ast_debug, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), iax2_thread::buf, iax2_thread::buf_len, iax2_thread::buf_size, iax2_thread::callno, iax2_thread::cond, ast_iax2_full_hdr::csub, iax2_thread::csub, iax2_thread::curfunc, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), iax2_thread::iofd, iax2_thread::iosin, iax2_thread::iostate, iax2_thread::lock, LOG_WARNING, iax2_thread::readbuf, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, thread, ast_iax2_full_hdr::type, and iax2_thread::type.

Referenced by network_thread(), peer_set_srcaddr(), and set_config().

09665 {
09666    struct iax2_thread *thread;
09667    socklen_t len;
09668    time_t t;
09669    static time_t last_errtime = 0;
09670    struct ast_iax2_full_hdr *fh;
09671 
09672    if (!(thread = find_idle_thread())) {
09673       time(&t);
09674       if (t != last_errtime)
09675          ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09676       last_errtime = t;
09677       usleep(1);
09678       return 1;
09679    }
09680 
09681    len = sizeof(thread->iosin);
09682    thread->iofd = fd;
09683    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09684    thread->buf_size = sizeof(thread->readbuf);
09685    thread->buf = thread->readbuf;
09686    if (thread->buf_len < 0) {
09687       if (errno != ECONNREFUSED && errno != EAGAIN)
09688          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09689       handle_error();
09690       thread->iostate = IAX_IOSTATE_IDLE;
09691       signal_condition(&thread->lock, &thread->cond);
09692       return 1;
09693    }
09694    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
09695       thread->iostate = IAX_IOSTATE_IDLE;
09696       signal_condition(&thread->lock, &thread->cond);
09697       return 1;
09698    }
09699    
09700    /* Determine if this frame is a full frame; if so, and any thread is currently
09701       processing a full frame for the same callno from this peer, then drop this
09702       frame (and the peer will retransmit it) */
09703    fh = (struct ast_iax2_full_hdr *) thread->buf;
09704    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09705       struct iax2_thread *cur = NULL;
09706       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09707       
09708       AST_LIST_LOCK(&active_list);
09709       AST_LIST_TRAVERSE(&active_list, cur, list) {
09710          if ((cur->ffinfo.callno == callno) &&
09711              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09712             break;
09713       }
09714       if (cur) {
09715          /* we found another thread processing a full frame for this call,
09716             so queue it up for processing later. */
09717          defer_full_frame(thread, cur);
09718          AST_LIST_UNLOCK(&active_list);
09719          thread->iostate = IAX_IOSTATE_IDLE;
09720          signal_condition(&thread->lock, &thread->cond);
09721          return 1;
09722       } else {
09723          /* this thread is going to process this frame, so mark it */
09724          thread->ffinfo.callno = callno;
09725          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09726          thread->ffinfo.type = fh->type;
09727          thread->ffinfo.csub = fh->csub;
09728          AST_LIST_INSERT_HEAD(&active_list, thread, list);
09729       }
09730       AST_LIST_UNLOCK(&active_list);
09731    }
09732    
09733    /* Mark as ready and send on its way */
09734    thread->iostate = IAX_IOSTATE_READY;
09735 #ifdef DEBUG_SCHED_MULTITHREAD
09736    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09737 #endif
09738    signal_condition(&thread->lock, &thread->cond);
09739 
09740    return 1;
09741 }

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

Definition at line 9334 of file chan_iax2.c.

References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create_detached, ast_strdup, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, dp_lookup_thread(), and LOG_WARNING.

Referenced by socket_process().

09335 {
09336    pthread_t newthread;
09337    struct dpreq_data *dpr;
09338    
09339    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09340       return;
09341 
09342    dpr->callno = callno;
09343    ast_copy_string(dpr->context, context, sizeof(dpr->context));
09344    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09345    if (callerid)
09346       dpr->callerid = ast_strdup(callerid);
09347    if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09348       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09349    }
09350 }

static int start_network_thread ( void   )  [static]

Definition at line 12270 of file chan_iax2.c.

References ast_calloc, ast_cond_destroy, ast_cond_init, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, ast_pthread_create_background, ast_verb, iax2_thread::cond, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, iax2_thread::init_cond, iax2_thread::init_lock, iax2_thread::lock, LOG_WARNING, network_thread(), thread, iax2_thread::threadid, iax2_thread::threadnum, and iax2_thread::type.

Referenced by load_module().

12271 {
12272    struct iax2_thread *thread;
12273    int threadcount = 0;
12274    int x;
12275    for (x = 0; x < iaxthreadcount; x++) {
12276       thread = ast_calloc(1, sizeof(*thread));
12277       if (thread) {
12278          thread->type = IAX_THREAD_TYPE_POOL;
12279          thread->threadnum = ++threadcount;
12280          ast_mutex_init(&thread->lock);
12281          ast_cond_init(&thread->cond, NULL);
12282          ast_mutex_init(&thread->init_lock);
12283          ast_cond_init(&thread->init_cond, NULL);
12284          if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12285             ast_log(LOG_WARNING, "Failed to create new thread!\n");
12286             ast_mutex_destroy(&thread->lock);
12287             ast_cond_destroy(&thread->cond);
12288             ast_mutex_destroy(&thread->init_lock);
12289             ast_cond_destroy(&thread->init_cond);
12290             ast_free(thread);
12291             thread = NULL;
12292             continue;
12293          }
12294          AST_LIST_LOCK(&idle_list);
12295          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12296          AST_LIST_UNLOCK(&idle_list);
12297       }
12298    }
12299    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
12300    ast_verb(2, "%d helper threads started\n", threadcount);
12301    return 0;
12302 }

static void stop_stuff ( int  callno  )  [static]

Definition at line 9041 of file chan_iax2.c.

References iax2_destroy_helper().

Referenced by socket_process().

09042 {
09043    iax2_destroy_helper(iaxs[callno]);
09044 }

static void store_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2189 of file chan_iax2.c.

References ao2_link, ast_log(), LOG_ERROR, and chan_iax2_pvt::peercallno.

Referenced by __find_callno(), complete_transfer(), and socket_process().

02190 {
02191    if (!pvt->peercallno) {
02192       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02193       return;
02194    }
02195 
02196    ao2_link(iax_peercallno_pvts, pvt);
02197 }

static void store_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2170 of file chan_iax2.c.

References ao2_link, ast_log(), LOG_ERROR, and chan_iax2_pvt::transfercallno.

Referenced by try_transfer().

02171 {
02172    if (!pvt->transfercallno) {
02173       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02174       return;
02175    }
02176 
02177    ao2_link(iax_transfercallno_pvts, pvt);
02178 }

static int timing_read ( int *  id,
int  fd,
short  events,
void *  cbdata 
) [static]

Definition at line 9224 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_debug, ast_free, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_timer_ack(), ast_tvnow(), ast_verbose, iax2_trunk_expired(), iax2_trunk_peer::lock, send_trunk(), totalcalls, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.

Referenced by network_thread().

09225 {
09226    int res, processed = 0, totalcalls = 0;
09227    struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09228    struct timeval now = ast_tvnow();
09229 
09230    if (iaxtrunkdebug)
09231       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09232 
09233    if (timer) { 
09234       ast_timer_ack(timer, 1);
09235    }
09236 
09237    /* For each peer that supports trunking... */
09238    AST_LIST_LOCK(&tpeers);
09239    AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09240       processed++;
09241       res = 0;
09242       ast_mutex_lock(&tpeer->lock);
09243       /* We can drop a single tpeer per pass.  That makes all this logic
09244          substantially easier */
09245       if (!drop && iax2_trunk_expired(tpeer, &now)) {
09246          /* Take it out of the list, but don't free it yet, because it
09247             could be in use */
09248          AST_LIST_REMOVE_CURRENT(list);
09249          drop = tpeer;
09250       } else {
09251          res = send_trunk(tpeer, &now);
09252          trunk_timed++;
09253          if (iaxtrunkdebug)
09254             ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
09255       }
09256       totalcalls += res;
09257       res = 0;
09258       ast_mutex_unlock(&tpeer->lock);
09259    }
09260    AST_LIST_TRAVERSE_SAFE_END;
09261    AST_LIST_UNLOCK(&tpeers);
09262 
09263    if (drop) {
09264       ast_mutex_lock(&drop->lock);
09265       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
09266          because by the time they could get tpeerlock, we've already grabbed it */
09267       ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09268       if (drop->trunkdata) {
09269          ast_free(drop->trunkdata);
09270          drop->trunkdata = NULL;
09271       }
09272       ast_mutex_unlock(&drop->lock);
09273       ast_mutex_destroy(&drop->lock);
09274       ast_free(drop);
09275    }
09276 
09277    if (iaxtrunkdebug)
09278       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09279    iaxtrunkdebug = 0;
09280 
09281    return 1;
09282 }

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

Definition at line 14510 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().

Referenced by load_objects().

14511 {
14512    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14513 
14514    /* The frames_received field is used to hold whether we're matching
14515     * against a full frame or not ... */
14516 
14517    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14518       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14519 }

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

Definition at line 14503 of file chan_iax2.c.

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

14504 {
14505    const struct chan_iax2_pvt *pvt = obj;
14506 
14507    return pvt->transfercallno;
14508 }

static int transmit_frame ( void *  data  )  [static]

Definition at line 4308 of file chan_iax2.c.

References AST_LIST_INSERT_TAIL, ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, frame_queue, iax2_sched_add(), iax_frame_free(), iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), and iax_frame::sentyet.

Referenced by iax2_transmit().

04309 {
04310    struct iax_frame *fr = data;
04311 
04312    ast_mutex_lock(&iaxsl[fr->callno]);
04313 
04314    fr->sentyet = 1;
04315 
04316    if (iaxs[fr->callno]) {
04317       send_packet(fr);
04318    }
04319 
04320    if (fr->retries < 0) {
04321       ast_mutex_unlock(&iaxsl[fr->callno]);
04322       /* No retransmit requested */
04323       iax_frame_free(fr);
04324    } else {
04325       /* We need reliable delivery.  Schedule a retransmission */
04326       AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04327       fr->retries++;
04328       fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04329       ast_mutex_unlock(&iaxsl[fr->callno]);
04330    }
04331 
04332    return 0;
04333 }

static int transmit_trunk ( struct iax_frame f,
struct sockaddr_in *  sin,
int  sockfd 
) [static]

Definition at line 3377 of file chan_iax2.c.

References ast_debug, iax_frame::data, iax_frame::datalen, errno, and handle_error().

Referenced by send_trunk().

03378 {
03379    int res;
03380    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03381                sizeof(*sin));
03382    if (res < 0) {
03383       ast_debug(1, "Received error: %s\n", strerror(errno));
03384       handle_error();
03385    } else
03386       res = 0;
03387    return res;
03388 }

static int try_firmware ( char *  s  )  [static]

Definition at line 3079 of file chan_iax2.c.

References ast_calloc, AST_FILE_MODE, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strlen_zero(), ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, LOG_WARNING, ast_iax2_firmware_header::magic, MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, and ast_iax2_firmware_header::version.

Referenced by reload_firmware().

03080 {
03081    struct stat stbuf;
03082    struct iax_firmware *cur = NULL;
03083    int ifd, fd, res, len, chunk;
03084    struct ast_iax2_firmware_header *fwh, fwh2;
03085    struct MD5Context md5;
03086    unsigned char sum[16], buf[1024];
03087    char *s2, *last;
03088 
03089    if (!(s2 = alloca(strlen(s) + 100))) {
03090       ast_log(LOG_WARNING, "Alloca failed!\n");
03091       return -1;
03092    }
03093 
03094    last = strrchr(s, '/');
03095    if (last)
03096       last++;
03097    else
03098       last = s;
03099 
03100    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
03101 
03102    if (stat(s, &stbuf) < 0) {
03103       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03104       return -1;
03105    }
03106 
03107    /* Make sure it's not a directory */
03108    if (S_ISDIR(stbuf.st_mode))
03109       return -1;
03110    ifd = open(s, O_RDONLY);
03111    if (ifd < 0) {
03112       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03113       return -1;
03114    }
03115    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03116    if (fd < 0) {
03117       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03118       close(ifd);
03119       return -1;
03120    }
03121    /* Unlink our newly created file */
03122    unlink(s2);
03123    
03124    /* Now copy the firmware into it */
03125    len = stbuf.st_size;
03126    while(len) {
03127       chunk = len;
03128       if (chunk > sizeof(buf))
03129          chunk = sizeof(buf);
03130       res = read(ifd, buf, chunk);
03131       if (res != chunk) {
03132          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03133          close(ifd);
03134          close(fd);
03135          return -1;
03136       }
03137       res = write(fd, buf, chunk);
03138       if (res != chunk) {
03139          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03140          close(ifd);
03141          close(fd);
03142          return -1;
03143       }
03144       len -= chunk;
03145    }
03146    close(ifd);
03147    /* Return to the beginning */
03148    lseek(fd, 0, SEEK_SET);
03149    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03150       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03151       close(fd);
03152       return -1;
03153    }
03154    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03155       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03156       close(fd);
03157       return -1;
03158    }
03159    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03160       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03161       close(fd);
03162       return -1;
03163    }
03164    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03165       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03166       close(fd);
03167       return -1;
03168    }
03169    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
03170    if (fwh == MAP_FAILED) {
03171       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03172       close(fd);
03173       return -1;
03174    }
03175    MD5Init(&md5);
03176    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03177    MD5Final(sum, &md5);
03178    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03179       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03180       munmap((void*)fwh, stbuf.st_size);
03181       close(fd);
03182       return -1;
03183    }
03184 
03185    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03186       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03187          /* Found a candidate */
03188          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03189             /* The version we have on loaded is older, load this one instead */
03190             break;
03191          /* This version is no newer than what we have.  Don't worry about it.
03192             We'll consider it a proper load anyhow though */
03193          munmap((void*)fwh, stbuf.st_size);
03194          close(fd);
03195          return 0;
03196       }
03197    }
03198    
03199    if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03200       cur->fd = -1;
03201       AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03202    }
03203    
03204    if (cur) {
03205       if (cur->fwh)
03206          munmap((void*)cur->fwh, cur->mmaplen);
03207       if (cur->fd > -1)
03208          close(cur->fd);
03209       cur->fwh = fwh;
03210       cur->fd = fd;
03211       cur->mmaplen = stbuf.st_size;
03212       cur->dead = 0;
03213    }
03214    
03215    return 0;
03216 }

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

Definition at line 8359 of file chan_iax2.c.

References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ie_data::buf, iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, inet_aton(), LOG_WARNING, iax_ie_data::pos, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, TRANSFER_NONE, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.

Referenced by socket_process().

08360 {
08361    int newcall = 0;
08362    char newip[256];
08363    struct iax_ie_data ied;
08364    struct sockaddr_in new;
08365    
08366    
08367    memset(&ied, 0, sizeof(ied));
08368    if (ies->apparent_addr)
08369       memmove(&new, ies->apparent_addr, sizeof(new));
08370    if (ies->callno)
08371       newcall = ies->callno;
08372    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08373       ast_log(LOG_WARNING, "Invalid transfer request\n");
08374       return -1;
08375    }
08376    pvt->transfercallno = newcall;
08377    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08378    inet_aton(newip, &pvt->transfer.sin_addr);
08379    pvt->transfer.sin_family = AF_INET;
08380    pvt->transferid = ies->transferid;
08381    /* only store by transfercallno if this is a new transfer,
08382     * just in case we get a duplicate TXREQ */
08383    if (pvt->transferring == TRANSFER_NONE) {
08384       store_by_transfercallno(pvt);
08385    }
08386    pvt->transferring = TRANSFER_BEGIN;
08387 
08388    if (ies->transferid)
08389       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08390    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08391    return 0;
08392 }

static iax2_format uncompress_subclass ( unsigned char  csub  )  [static]

Definition at line 1625 of file chan_iax2.c.

References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

Referenced by decode_frame(), handle_call_token(), and socket_process().

01626 {
01627    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01628    if (csub & IAX_FLAG_SC_LOG) {
01629       /* special case for 'compressed' -1 */
01630       if (csub == 0xff)
01631          return -1;
01632       else
01633          return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01634    }
01635    else
01636       return csub;
01637 }

static void unlink_peer ( struct iax2_peer peer  )  [static]

Definition at line 8654 of file chan_iax2.c.

References ao2_unlink, AST_SCHED_DEL, iax2_peer::expire, peer_unref(), and iax2_peer::pokeexpire.

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

08655 {
08656    if (peer->expire > -1) {
08657       if (!AST_SCHED_DEL(sched, peer->expire)) {
08658          peer->expire = -1;
08659          peer_unref(peer);
08660       }
08661    }
08662 
08663    if (peer->pokeexpire > -1) {
08664       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
08665          peer->pokeexpire = -1;
08666          peer_unref(peer);
08667       }
08668    }
08669 
08670    ao2_unlink(peers, peer);
08671 }

static int unload_module ( void   )  [static]

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

Definition at line 5525 of file chan_iax2.c.

References ast_mutex_unlock.

Referenced by iax2_bridge().

05526 {
05527    ast_mutex_unlock(&iaxsl[callno1]);
05528    ast_mutex_unlock(&iaxsl[callno0]);
05529 }

static void unwrap_timestamp ( struct iax_frame fr  )  [static]

Definition at line 4068 of file chan_iax2.c.

References iax_frame::af, ast_debug, AST_FRAME_VIDEO, iax_frame::callno, ast_frame::frametype, chan_iax2_pvt::last, and iax_frame::ts.

Referenced by schedule_delivery().

04069 {
04070    /* Video mini frames only encode the lower 15 bits of the session
04071     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
04072    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
04073    const int lower_mask = (1 << ts_shift) - 1;
04074    const int upper_mask = ~lower_mask;
04075    const int last_upper = iaxs[fr->callno]->last & upper_mask;
04076 
04077    if ( (fr->ts & upper_mask) == last_upper ) {
04078       const int x = fr->ts - iaxs[fr->callno]->last;
04079       const int threshold = (ts_shift == 15) ? 25000 : 50000;
04080 
04081       if (x < -threshold) {
04082          /* Sudden big jump backwards in timestamp:
04083             What likely happened here is that miniframe timestamp has circled but we haven't
04084             gotten the update from the main packet.  We'll just pretend that we did, and
04085             update the timestamp appropriately. */
04086          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04087          if (iaxdebug)
04088             ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04089       } else if (x > threshold) {
04090          /* Sudden apparent big jump forwards in timestamp:
04091             What's likely happened is this is an old miniframe belonging to the previous
04092             top 15 or 16-bit timestamp that has turned up out of order.
04093             Adjust the timestamp appropriately. */
04094          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04095          if (iaxdebug)
04096             ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04097       }
04098    }
04099 }

static void update_jbsched ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 4103 of file chan_iax2.c.

References ast_tvdiff_ms(), ast_tvnow(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_replace(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, and chan_iax2_pvt::rxcore.

Referenced by __get_from_jb(), and schedule_delivery().

04104 {
04105    int when;
04106 
04107    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04108 
04109    when = jb_next(pvt->jb) - when;
04110 
04111    if (when <= 0) {
04112       /* XXX should really just empty until when > 0.. */
04113       when = 1;
04114    }
04115 
04116    pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
04117       CALLNO_TO_PTR(pvt->callno));
04118 }

static void update_max_nontrunk ( void   )  [static]

Definition at line 2097 of file chan_iax2.c.

References ast_debug, and TRUNK_CALL_START.

Referenced by __find_callno(), and make_trunk().

02098 {
02099    int max = 1;
02100    int x;
02101    /* XXX Prolly don't need locks here XXX */
02102    for (x=1;x<TRUNK_CALL_START - 1; x++) {
02103       if (iaxs[x])
02104          max = x + 1;
02105    }
02106    maxnontrunkcall = max;
02107    if (iaxdebug)
02108       ast_debug(1, "New max nontrunk callno is %d\n", max);
02109 }

static void update_max_trunk ( void   )  [static]

Definition at line 2080 of file chan_iax2.c.

References ARRAY_LEN, ast_debug, and TRUNK_CALL_START.

Referenced by iax2_destroy(), and make_trunk().

02081 {
02082    int max = TRUNK_CALL_START;
02083    int x;
02084 
02085    /* XXX Prolly don't need locks here XXX */
02086    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
02087       if (iaxs[x]) {
02088          max = x + 1;
02089       }
02090    }
02091 
02092    maxtrunkcall = max;
02093    if (iaxdebug)
02094       ast_debug(1, "New max trunk callno is %d\n", max);
02095 }

static int update_packet ( struct iax_frame f  )  [static]

Definition at line 3515 of file chan_iax2.c.

References build_rand_pad(), iax_frame::callno, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, ast_iax2_full_hdr::dcallno, decode_frame(), iax_frame::ecx, iax_frame::encmethods, encrypt_frame(), IAX_FLAG_RETRANS, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, iax_frame::mydcx, and iax_frame::semirand.

Referenced by __attempt_transmit().

03516 {
03517    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
03518    struct ast_iax2_full_hdr *fh = f->data;
03519    struct ast_frame af;
03520 
03521    /* if frame is encrypted. decrypt before updating it. */
03522    if (f->encmethods) {
03523       decode_frame(&f->mydcx, fh, &af, &f->datalen);
03524    }
03525    /* Mark this as a retransmission */
03526    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03527    /* Update iseqno */
03528    f->iseqno = iaxs[f->callno]->iseqno;
03529    fh->iseqno = f->iseqno;
03530 
03531    /* Now re-encrypt the frame */
03532    if (f->encmethods) {
03533    /* since this is a retransmit frame, create a new random padding
03534     * before re-encrypting. */
03535       build_rand_pad(f->semirand, sizeof(f->semirand));
03536       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03537    }
03538    return 0;
03539 }

static int update_registry ( struct sockaddr_in *  sin,
int  callno,
char *  devtype,
int  fd,
unsigned short  refresh 
) [static]

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

References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_SCHED_DEL, ast_sockaddr_cmp(), ast_sockaddr_from_sin, ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_verb, iax_ie_data::buf, iax2_peer::cid_name, iax2_peer::cid_num, context, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, LOG_NOTICE, LOG_WARNING, mailbox, iax2_peer::mailbox, manager_event, iax2_peer::maxcallno, iax2_peer::name, peer_ref(), peer_unref(), peercnt_modify(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), send_command_final(), iax2_peer::sockfd, strsep(), version, and iax2_peer::zonetag.

Referenced by socket_process().

08774 {
08775    /* Called from IAX thread only, with proper iaxsl lock */
08776    struct iax_ie_data ied = {
08777       .pos = 0,
08778    };
08779    struct iax2_peer *p;
08780    int msgcount;
08781    char data[80];
08782    int version;
08783    const char *peer_name;
08784    int res = -1;
08785    struct ast_sockaddr sockaddr;
08786 
08787    ast_sockaddr_from_sin(&sockaddr, sin);
08788 
08789    peer_name = ast_strdupa(iaxs[callno]->peer);
08790 
08791    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
08792    ast_mutex_unlock(&iaxsl[callno]);
08793    if (!(p = find_peer(peer_name, 1))) {
08794       ast_mutex_lock(&iaxsl[callno]);
08795       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08796       return -1;
08797    }
08798    ast_mutex_lock(&iaxsl[callno]);
08799    if (!iaxs[callno])
08800       goto return_unref;
08801 
08802    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08803       if (sin->sin_addr.s_addr) {
08804          time_t nowtime;
08805          time(&nowtime);
08806          realtime_update_peer(peer_name, &sockaddr, nowtime);
08807       } else {
08808          realtime_update_peer(peer_name, &sockaddr, 0);
08809       }
08810    }
08811 
08812    if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08813       if (iax2_regfunk) {
08814          iax2_regfunk(p->name, 1);
08815       }
08816 
08817       /* modify entry in peercnts table as _not_ registered */
08818       peercnt_modify(0, 0, &p->addr);
08819 
08820       /* Stash the IP address from which they registered */
08821       ast_sockaddr_from_sin(&p->addr, sin);
08822 
08823       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08824       if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08825          ast_db_put("IAX/Registry", p->name, data);
08826          ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08827                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08828          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\nPost: %d\r\n", p->name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08829          register_peer_exten(p, 1);
08830          ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
08831       } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08832          ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08833                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08834          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08835          register_peer_exten(p, 0);
08836          ast_db_del("IAX/Registry", p->name);
08837          ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */
08838       }
08839       /* Update the host */
08840       /* Verify that the host is really there */
08841       iax2_poke_peer(p, callno);
08842    }
08843 
08844    /* modify entry in peercnts table as registered */
08845    if (p->maxcallno) {
08846       peercnt_modify(1, p->maxcallno, &p->addr);
08847    }
08848 
08849    /* Make sure our call still exists, an INVAL at the right point may make it go away */
08850    if (!iaxs[callno]) {
08851       res = -1;
08852       goto return_unref;
08853    }
08854 
08855    /* Store socket fd */
08856    p->sockfd = fd;
08857    /* Setup the expiry */
08858    if (p->expire > -1) {
08859       if (!AST_SCHED_DEL(sched, p->expire)) {
08860          p->expire = -1;
08861          peer_unref(p);
08862       }
08863    }
08864    /* treat an unspecified refresh interval as the minimum */
08865    if (!refresh)
08866       refresh = min_reg_expire;
08867    if (refresh > max_reg_expire) {
08868       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08869          p->name, max_reg_expire, refresh);
08870       p->expiry = max_reg_expire;
08871    } else if (refresh < min_reg_expire) {
08872       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08873          p->name, min_reg_expire, refresh);
08874       p->expiry = min_reg_expire;
08875    } else {
08876       p->expiry = refresh;
08877    }
08878    if (p->expiry && sin->sin_addr.s_addr) {
08879       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08880       if (p->expire == -1)
08881          peer_unref(p);
08882    }
08883    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08884    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08885    if (sin->sin_addr.s_addr) {
08886       struct sockaddr_in peer_addr;
08887 
08888       ast_sockaddr_to_sin(&p->addr, &peer_addr);
08889 
08890       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08891       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08892       if (!ast_strlen_zero(p->mailbox)) {
08893          struct ast_event *event;
08894          int new, old;
08895          char *mailbox, *context;
08896 
08897          context = mailbox = ast_strdupa(p->mailbox);
08898          strsep(&context, "@");
08899          if (ast_strlen_zero(context))
08900             context = "default";
08901 
08902          event = ast_event_get_cached(AST_EVENT_MWI,
08903             AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08904             AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08905             AST_EVENT_IE_END);
08906          if (event) {
08907             new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08908             old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08909             ast_event_destroy(event);
08910          } else { /* Fall back on checking the mailbox directly */
08911             ast_app_inboxcount(p->mailbox, &new, &old);
08912          }
08913 
08914          if (new > 255) {
08915             new = 255;
08916          }
08917          if (old > 255) {
08918             old = 255;
08919          }
08920          msgcount = (old << 8) | new;
08921 
08922          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08923       }
08924       if (ast_test_flag64(p, IAX_HASCALLERID)) {
08925          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08926          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08927       }
08928    }
08929    version = iax_check_version(devtype);
08930    if (version) 
08931       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08932 
08933    res = 0;
08934 
08935 return_unref:
08936    peer_unref(p);
08937 
08938    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08939 }

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

Note:
The only member of the user passed here guaranteed to be set is the name field

Definition at line 1760 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, iax2_user::name, name, and OBJ_KEY.

Referenced by load_objects().

01761 {
01762    struct iax2_user *user = obj, *user2 = arg;
01763    const char *name = arg;
01764 
01765    return !strcmp(user->name, flags & OBJ_KEY ? name : user2->name) ?
01766          CMP_MATCH | CMP_STOP : 0;
01767 }

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

Definition at line 13005 of file chan_iax2.c.

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

13006 {
13007    struct iax2_user *user = obj;
13008 
13009    ast_set_flag64(user, IAX_DELME);
13010 
13011    return 0;
13012 }

static void user_destructor ( void *  obj  )  [static]

Definition at line 12733 of file chan_iax2.c.

References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), iax2_user::contexts, free_context(), iax2_user::ha, and iax2_user::vars.

Referenced by build_user().

12734 {
12735    struct iax2_user *user = obj;
12736 
12737    ast_free_ha(user->ha);
12738    free_context(user->contexts);
12739    if(user->vars) {
12740       ast_variables_destroy(user->vars);
12741       user->vars = NULL;
12742    }
12743    ast_string_field_free_memory(user);
12744 }

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

Note:
The only member of the user passed here guaranteed to be set is the name field

Definition at line 1749 of file chan_iax2.c.

References ast_str_hash(), iax2_user::name, name, and OBJ_KEY.

Referenced by load_objects().

01750 {
01751    const struct iax2_user *user = obj;
01752    const char *name = obj;
01753 
01754    return ast_str_hash(flags & OBJ_KEY ? name : user->name);
01755 }

static struct iax2_user* user_ref ( struct iax2_user user  )  [static, read]

Definition at line 1802 of file chan_iax2.c.

References ao2_ref.

01803 {
01804    ao2_ref(user, +1);
01805    return user;
01806 }

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

References iax2_user::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cdr_flags2str(), ast_copy_string(), ast_data_add_bool(), ast_data_add_int(), ast_data_add_node(), ast_data_add_password(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_strlen_zero(), ast_test_flag64, iax2_user::authmethods, iax2_user::capability, iax2_context::context, iax2_user::contexts, DEFAULT_CONTEXT, iax2_user::ha, iax2_data_add_codecs(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, iax2_user::inkeys, iax2_user::secret, and user_unref().

14675 {
14676    struct ast_data *data_user, *data_authmethods, *data_enum_node;
14677    struct iax2_user *user;
14678    struct ao2_iterator i;
14679    char auth[90];
14680    char *pstr = "";
14681 
14682    i = ao2_iterator_init(users, 0);
14683    for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
14684       data_user = ast_data_add_node(data_root, "user");
14685       if (!data_user) {
14686          continue;
14687       }
14688 
14689       ast_data_add_structure(iax2_user, data_user, user);
14690 
14691       iax2_data_add_codecs(data_user, "codecs", user->capability);
14692 
14693       if (!ast_strlen_zero(user->secret)) {
14694          ast_copy_string(auth, user->secret, sizeof(auth));
14695       } else if (!ast_strlen_zero(user->inkeys)) {
14696          snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14697       } else {
14698          ast_copy_string(auth, "no secret", sizeof(auth));
14699       }
14700       ast_data_add_password(data_user, "secret", auth);
14701 
14702       ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14703 
14704       /* authmethods */
14705       data_authmethods = ast_data_add_node(data_user, "authmethods");
14706       if (!data_authmethods) {
14707          ast_data_remove_node(data_root, data_user);
14708          continue;
14709       }
14710       ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14711       ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14712       ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14713 
14714       /* amaflags */
14715       data_enum_node = ast_data_add_node(data_user, "amaflags");
14716       if (!data_enum_node) {
14717          ast_data_remove_node(data_root, data_user);
14718          continue;
14719       }
14720       ast_data_add_int(data_enum_node, "value", user->amaflags);
14721       ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14722 
14723       ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14724 
14725       if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14726          pstr = "REQ only";
14727       } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14728          pstr = "disabled";
14729       } else {
14730          pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14731       }
14732       ast_data_add_str(data_user, "codec-preferences", pstr);
14733 
14734       if (!ast_data_search_match(search, data_user)) {
14735          ast_data_remove_node(data_root, data_user);
14736       }
14737    }
14738    ao2_iterator_destroy(&i);
14739 
14740    return 0;
14741 }

static void vnak_retransmit ( int  callno,
int  last 
) [static]

Definition at line 9142 of file chan_iax2.c.

References AST_LIST_TRAVERSE, f, frame_queue, iax_frame::oseqno, iax_frame::retries, and send_packet().

Referenced by socket_process().

09143 {
09144    struct iax_frame *f;
09145 
09146    AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09147       /* Send a copy immediately */
09148       if (((unsigned char) (f->oseqno - last) < 128) &&
09149             (f->retries >= 0)) {
09150          send_packet(f);
09151       }
09152    }
09153 }

static int wait_for_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Note:
expects the pvt to be locked

Definition at line 5336 of file chan_iax2.c.

References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, and chan_iax2_pvt::peercallno.

Referenced by iax2_indicate(), and iax2_setoption().

05337 {
05338    unsigned short callno = pvt->callno;
05339 
05340    if (!pvt->peercallno) {
05341       /* We don't know the remote side's call number, yet.  :( */
05342       int count = 10;
05343       while (count-- && pvt && !pvt->peercallno) {
05344          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05345          pvt = iaxs[callno];
05346       }
05347       if (!pvt->peercallno) {
05348          return -1;
05349       }
05350    }
05351 
05352    return 0;
05353 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", } [static]

Definition at line 14896 of file chan_iax2.c.

char accountcode[AST_MAX_ACCOUNT_CODE] [static]

int adsi = 0 [static]

Definition at line 383 of file chan_iax2.c.

int amaflags = 0 [static]

Definition at line 382 of file chan_iax2.c.

Referenced by ast_async_goto().

Definition at line 14896 of file chan_iax2.c.

int authdebug = 0 [static]

Definition at line 290 of file chan_iax2.c.

int autokill = 0 [static]

Definition at line 291 of file chan_iax2.c.

struct ao2_container* callno_limits [static]

Table containing custom callno limit rules for a range of ip addresses.

Definition at line 891 of file chan_iax2.c.

struct ao2_container* callno_pool [static]

table of available call numbers

Definition at line 846 of file chan_iax2.c.

const unsigned int CALLNO_POOL_BUCKETS = 2699 [static]

Definition at line 851 of file chan_iax2.c.

struct ao2_container* callno_pool_trunk [static]

table of available trunk call numbers

Definition at line 849 of file chan_iax2.c.

struct ao2_container* calltoken_ignores [static]

Table containing ip addresses not requiring calltoken validation

Definition at line 894 of file chan_iax2.c.

struct ast_cli_entry cli_iax2[] [static]

Definition at line 14211 of file chan_iax2.c.

unsigned int cos

Definition at line 301 of file chan_iax2.c.

struct sockaddr_in debugaddr [static]

uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048 [static]

Definition at line 896 of file chan_iax2.c.

uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static]

Definition at line 898 of file chan_iax2.c.

char default_parkinglot[AST_MAX_CONTEXT] [static]

int defaultsockfd = -1 [static]

Definition at line 313 of file chan_iax2.c.

int delayreject = 0 [static]

Definition at line 384 of file chan_iax2.c.

struct iax_frame* first

Definition at line 862 of file chan_iax2.c.

struct { ... } frame_queue[IAX_MAX_CALLS + 1] [static]

a list of frames that may need to be retransmitted

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

Referenced by __attempt_transmit(), complete_transfer(), handle_cli_iax2_show_stats(), pvt_destructor(), resend_with_token(), socket_process(), transmit_frame(), and vnak_retransmit().

int global_max_trunk_mtu [static]

Maximum MTU, 0 if not used

Definition at line 263 of file chan_iax2.c.

uint16_t global_maxcallno [static]

Definition at line 900 of file chan_iax2.c.

uint16_t global_maxcallno_nonval [static]

Total num of call numbers allowed to be allocated without calltoken validation

Definition at line 903 of file chan_iax2.c.

int global_rtautoclear = 120 [static]

Definition at line 435 of file chan_iax2.c.

struct ast_flags64 globalflags = { 0 } [static]

Definition at line 387 of file chan_iax2.c.

iax2_format iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static]

Definition at line 365 of file chan_iax2.c.

Initial value:

 {
   AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
   AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
}

Definition at line 14753 of file chan_iax2.c.

int iax2_encryption = 0 [static]

Definition at line 385 of file chan_iax2.c.

int(* iax2_regfunk)(const char *username, int onoff) = NULL [static]

struct ast_switch iax2_switch [static]

Definition at line 14097 of file chan_iax2.c.

struct ast_channel_tech iax2_tech [static]

Definition at line 1216 of file chan_iax2.c.

Initial value:

 {
   .type = "IAX2_VARIABLE",
   .duplicate = iax2_dup_variable_datastore,
   .destroy = iax2_free_variable_datastore,
}

Definition at line 1330 of file chan_iax2.c.

Another container of iax2_pvt structures.

Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.

Definition at line 1075 of file chan_iax2.c.

Another container of iax2_pvt structures.

* Active IAX2 pvt stucts used during transfering a call are stored here.

Definition at line 1091 of file chan_iax2.c.

int iaxactivethreadcount = 0 [static]

Definition at line 635 of file chan_iax2.c.

Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().

int iaxcompat = 0 [static]

Definition at line 292 of file chan_iax2.c.

int iaxdebug = 0 [static]

Definition at line 367 of file chan_iax2.c.

int iaxdefaultdpcache = 10 * 60 [static]

Definition at line 295 of file chan_iax2.c.

int iaxdefaulttimeout = 5 [static]

Definition at line 297 of file chan_iax2.c.

int iaxdynamicthreadcount = 0 [static]

Definition at line 633 of file chan_iax2.c.

Referenced by find_idle_thread(), and iax2_process_thread().

int iaxdynamicthreadnum = 0 [static]

Definition at line 634 of file chan_iax2.c.

Referenced by find_idle_thread().

int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static]

Definition at line 632 of file chan_iax2.c.

Referenced by find_idle_thread(), and set_config().

Initial value:

 {
   .name = "IAXPEER",
   .read = function_iaxpeer,
}

Definition at line 14017 of file chan_iax2.c.

struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS+1] [static]

an array of iax2 pvt structures

The container for active chan_iax2_pvt structures is implemented as an array for extremely quick direct access to the correct pvt structure based on the local call number. The local call number is used as the index into the array where the associated pvt structure is stored.

Definition at line 1064 of file chan_iax2.c.

ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static]

chan_iax2_pvt structure locks

These locks are used when accessing a pvt structure in the iaxs array. The index used here is the same as used in the iaxs array. It is the local call number for the associated pvt struct.

Definition at line 1084 of file chan_iax2.c.

int iaxthreadcount = DEFAULT_THREAD_COUNT [static]

Definition at line 631 of file chan_iax2.c.

Referenced by handle_cli_iax2_show_threads(), set_config(), and start_network_thread().

int iaxtrunkdebug = 0 [static]

Definition at line 369 of file chan_iax2.c.

Initial value:

 {
   .name = "IAXVAR",
   .read = acf_iaxvar_read,
   .write = acf_iaxvar_write,
}

Definition at line 9935 of file chan_iax2.c.

struct io_context* io [static]

Definition at line 360 of file chan_iax2.c.

int jittertargetextra = 40 [static]

Definition at line 283 of file chan_iax2.c.

int lagrq_time = 10 [static]

Definition at line 279 of file chan_iax2.c.

char language[MAX_LANGUAGE] = "" [static]

Definition at line 270 of file chan_iax2.c.

struct iax_frame* last

Definition at line 862 of file chan_iax2.c.

int last_authmethod = 0 [static]

Definition at line 293 of file chan_iax2.c.

const time_t MAX_CALLTOKEN_DELAY = 10 [static]

Definition at line 868 of file chan_iax2.c.

int max_reg_expire [static]

Definition at line 305 of file chan_iax2.c.

int max_retries = 4 [static]

Definition at line 277 of file chan_iax2.c.

int maxauthreq = 3 [static]

Definition at line 276 of file chan_iax2.c.

int maxjitterbuffer = 1000 [static]

Definition at line 280 of file chan_iax2.c.

int maxjitterinterps = 10 [static]

Definition at line 282 of file chan_iax2.c.

int maxnontrunkcall = 1 [static]

Definition at line 1165 of file chan_iax2.c.

int maxtrunkcall = TRUNK_CALL_START [static]

Definition at line 1164 of file chan_iax2.c.

int min_reg_expire [static]

Definition at line 304 of file chan_iax2.c.

char mohinterpret[MAX_MUSICCLASS] [static]

Definition at line 380 of file chan_iax2.c.

char mohsuggest[MAX_MUSICCLASS] [static]

struct ast_netsock_list* netsock [static]

Definition at line 311 of file chan_iax2.c.

pthread_t netthreadid = AST_PTHREADT_NULL [static]

Definition at line 389 of file chan_iax2.c.

int network_change_event_sched_id = -1 [static]

Definition at line 274 of file chan_iax2.c.

subscription id for network change events

Definition at line 273 of file chan_iax2.c.

struct ast_netsock_list* outsock [static]

used if sourceaddress specified and bindaddr == INADDR_ANY

Definition at line 312 of file chan_iax2.c.

char* papp = "IAX2Provision" [static]

Definition at line 11974 of file chan_iax2.c.

struct ao2_container* peercnts [static]

Table containing peercnt objects for every ip address consuming a callno

Definition at line 888 of file chan_iax2.c.

struct ao2_container* peers [static]

Definition at line 882 of file chan_iax2.c.

Initial value:

Definition at line 14743 of file chan_iax2.c.

int ping_time = 21 [static]

Definition at line 278 of file chan_iax2.c.

struct ast_codec_pref prefs [static]

struct { ... } qos [static]

int randomcalltokendata [static]

Definition at line 866 of file chan_iax2.c.

char regcontext[AST_MAX_CONTEXT] = "" [static]

Definition at line 271 of file chan_iax2.c.

int resyncthreshold = 1000 [static]

Definition at line 281 of file chan_iax2.c.

struct ast_sched_context* sched [static]

Definition at line 361 of file chan_iax2.c.

int srvlookup = 0 [static]

Definition at line 307 of file chan_iax2.c.

Referenced by build_peer().

const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static]

Definition at line 256 of file chan_iax2.c.

int test_losspct = 0 [static]

Definition at line 371 of file chan_iax2.c.

struct ast_timer* timer [static]

unsigned int tos

Definition at line 300 of file chan_iax2.c.

uint16_t total_nonval_callno_used = 0 [static]

Definition at line 905 of file chan_iax2.c.

Definition at line 864 of file chan_iax2.c.

int trunk_maxmtu [static]

Definition at line 264 of file chan_iax2.c.

int trunk_nmaxmtu [static]

Trunk MTU statistics

Definition at line 264 of file chan_iax2.c.

int trunk_timed [static]

Definition at line 264 of file chan_iax2.c.

int trunk_untimed [static]

Definition at line 264 of file chan_iax2.c.

int trunkfreq = 20 [static]

Definition at line 287 of file chan_iax2.c.

int trunkmaxsize = MAX_TRUNKDATA [static]

Definition at line 288 of file chan_iax2.c.

struct ao2_container* users [static]

Definition at line 885 of file chan_iax2.c.

Initial value:

Definition at line 14748 of file chan_iax2.c.


Generated on Sat Feb 11 06:34:36 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6