Wed Aug 18 22:34:08 2010

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/aes.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/event.h"
#include "asterisk/astobj2.h"
#include "asterisk/timing.h"
#include "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  frame_queue
 a list of frames that may need to be retransmitted More...
struct  iax2_context
struct  iax2_dpcache
struct  iax2_peer
struct  iax2_pkt_buf
struct  iax2_registry
struct  iax2_thread
struct  iax2_trunk_peer
struct  iax2_user
struct  iax_dual
struct  iax_firmware
struct  iax_rr
struct  idle_list
struct  parsed_dial_string
struct  peercnt
struct  registrations
struct  signaling_queue_entry
struct  tpeers

Defines

#define ACN_FORMAT1   "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
#define ACN_FORMAT2   "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
#define CALLNO_TO_PTR(a)   ((void *)(unsigned long)(a))
#define CALLTOKEN_HASH_FORMAT   "%s%d%u%d"
#define CALLTOKEN_IE_FORMAT   "%u?%s"
#define DEBUG_SCHED_MULTITHREAD
#define DEBUG_SUPPORT
#define DEFAULT_CONTEXT   "default"
#define DEFAULT_DROP   3
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAX_THREAD_COUNT   100
#define DEFAULT_MAXMS   2000
#define DEFAULT_RETRY_TIME   1000
#define DEFAULT_THREAD_COUNT   10
#define DEFAULT_TRUNKDATA   640 * 10
#define FORMAT   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n"
#define FORMAT   "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
#define FORMAT   "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
#define FORMAT   "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
#define FORMAT2   "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
#define FORMAT2   "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
#define FORMAT2   "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
#define FORMAT2   "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
#define FORMATB   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
#define GAMMA   (0.01)
#define IAX2_TRUNK_PREFACE   (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
#define IAX_CALLENCRYPTED(pvt)   (ast_test_flag(pvt, IAX_ENCRYPTED) && ast_test_flag(pvt, IAX_KEYPOPULATED))
#define IAX_CAPABILITY_FULLBANDWIDTH   (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED)
#define IAX_CAPABILITY_LOWBANDWIDTH
#define IAX_CAPABILITY_LOWFREE
#define IAX_CAPABILITY_MEDBANDWIDTH
#define IAX_DEBUGDIGEST(msg, key)
#define MARK_IAX_SUBCLASS_TX   0x8000
#define MAX_JITTER_BUFFER   50
#define MAX_PEER_BUCKETS   563
#define MAX_RETRY_TIME   10000
#define MAX_TIMESTAMP_SKEW   160
#define MAX_TRUNK_MTU   1240
 Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240.
#define MAX_TRUNKDATA   640 * 200
#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS
#define MEMORY_SIZE   100
#define MIN_JITTER_BUFFER   10
#define MIN_RETRY_TIME   100
#define MIN_REUSE_TIME   60
#define PTR_TO_CALLNO(a)   ((unsigned short)(unsigned long)(a))
#define SCHED_MULTITHREADED
#define schedule_action(func, data)   __schedule_action(func, data, __PRETTY_FUNCTION__)
#define TRUNK_CALL_START   IAX_MAX_CALLS / 2
#define TS_GAP_FOR_JB_RESYNC   5000

Enumerations

enum  {
  CACHE_FLAG_EXISTS = (1 << 0), CACHE_FLAG_NONEXISTENT = (1 << 1), CACHE_FLAG_CANEXIST = (1 << 2), CACHE_FLAG_PENDING = (1 << 3),
  CACHE_FLAG_TIMEOUT = (1 << 4), CACHE_FLAG_TRANSMITTED = (1 << 5), CACHE_FLAG_UNKNOWN = (1 << 6), CACHE_FLAG_MATCHMORE = (1 << 7)
}
enum  { NEW_PREVENT = 0, NEW_ALLOW = 1, NEW_FORCE = 2, NEW_ALLOW_CALLTOKEN_VALIDATED = 3 }
enum  calltoken_peer_enum { CALLTOKEN_DEFAULT = 0, CALLTOKEN_YES = 1, CALLTOKEN_AUTO = 2, CALLTOKEN_NO = 3 }
 Call token validation settings. More...
enum  iax2_flags {
  IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3),
  IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7),
  IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11), IAX_ENCRYPTED = (1 << 12),
  IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15), IAX_CODEC_NOCAP = (1 << 16),
  IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19), IAX_FORCEJITTERBUF = (1 << 20),
  IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22), IAX_TRANSFERMEDIA = (1 << 23), IAX_MAXAUTHREQ = (1 << 24),
  IAX_DELAYPBXSTART = (1 << 25), IAX_ALLOWFWDOWNLOAD = (1 << 26), IAX_SHRINKCALLERID = (1 << 27)
}
enum  iax2_state { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) }
enum  iax2_thread_iostate { IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_SCHEDREADY }
enum  iax2_thread_type { IAX_THREAD_TYPE_POOL, IAX_THREAD_TYPE_DYNAMIC }
enum  iax_reg_state {
  REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED,
  REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH
}
enum  iax_transfer_state {
  TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED,
  TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED,
  TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS
}

Functions

static void __attempt_transmit (const void *data)
static void __auth_reject (const void *nothing)
static void __auto_congest (const void *nothing)
static void __auto_hangup (const void *nothing)
static int __do_deliver (void *data)
static void __expire_registry (const void *data)
static int __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
static void __get_from_jb (const void *p)
static void __iax2_do_register_s (const void *data)
static void __iax2_poke_noanswer (const void *data)
static void __iax2_poke_peer_s (const void *data)
static int __iax2_show_peers (int manager, int fd, struct mansession *s, int argc, char *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)
static struct ast_channelast_iax2_new (int callno, int state, int capability)
 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 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)
static char * complete_iax2_unregister (const char *line, const char *word, int pos, int state)
static int complete_transfer (int callno, struct iax_ies *ies)
static unsigned char compress_subclass (int subclass)
static void construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
static int create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
static int create_callno_pools (void)
static int decode_frame (ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static int decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static void defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here)
 Queue the last read full frame for processing by a certain thread.
static void delete_users (void)
static void destroy_firmware (struct iax_firmware *cur)
static void dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
static void * dp_lookup_thread (void *data)
static int encrypt_frame (ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
static int expire_registry (const void *data)
static struct iax2_dpcachefind_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
static int find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame)
static int find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame)
static struct iax2_threadfind_idle_thread (void)
static struct iax2_peerfind_peer (const char *name, int realtime)
static struct iax2_trunk_peerfind_tpeer (struct sockaddr_in *sin, int fd)
static struct iax2_userfind_user (const char *name)
static unsigned int fix_peerts (struct timeval *rxtrunktime, int callno, unsigned int ts)
static void free_context (struct iax2_context *con)
static void free_signaling_queue_entry (struct signaling_queue_entry *s)
static int function_iaxpeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int get_auth_methods (const char *value)
static int get_encrypt_methods (const char *s)
static int get_from_jb (const void *p)
static struct callno_entryget_unused_callno (int trunk, int validated)
static int handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct sockaddr_in *sin, int fd)
static char * handle_cli_iax2_provision (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_debug_jb (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_debug_trunk (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_mtu (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Set trunk MTU from CLI.
static char * handle_cli_iax2_show_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_callno_limits (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_firmware (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_netstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show one peer in detail.
static char * handle_cli_iax2_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_test_losspct (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void handle_deferred_full_frames (struct iax2_thread *thread)
 Handle any deferred full frames for this thread.
static int handle_error (void)
static int iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno)
 Acknowledgment received for OUR registration.
static int attribute_pure iax2_allow_new (int frametype, int subclass, int inbound)
static void iax2_ami_channelupdate (struct chan_iax2_pvt *pvt)
 Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers.
static int iax2_answer (struct ast_channel *c)
static int iax2_append_register (const char *hostname, const char *username, const char *secret, const char *porta)
static enum ast_bridge_result iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
static int iax2_call (struct ast_channel *c, char *dest, int timeout)
static int iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 part of the IAX2 dial plan switch interface
static unsigned int iax2_datetime (const char *tz)
static void iax2_destroy (int callno)
static void iax2_destroy_helper (struct chan_iax2_pvt *pvt)
static int iax2_devicestate (void *data)
 Part of the device state notification system ---.
static int iax2_digit_begin (struct ast_channel *c, char digit)
static int iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration)
static int iax2_do_register (struct iax2_registry *reg)
static int iax2_do_register_s (const void *data)
static void iax2_dprequest (struct iax2_dpcache *dp, int callno)
static void * iax2_dup_variable_datastore (void *)
static int iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Execute IAX2 dialplan switch.
static int iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 switch interface.
static int iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan)
static void iax2_frame_free (struct iax_frame *fr)
static void iax2_free_variable_datastore (void *)
static int iax2_getpeername (struct sockaddr_in sin, char *host, int len)
static int iax2_getpeertrunk (struct sockaddr_in sin)
static int iax2_hangup (struct ast_channel *c)
static int iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen)
static int iax2_key_rotate (const void *vpvt)
static int iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 Switch interface.
static int iax2_poke_noanswer (const void *data)
static int iax2_poke_peer (struct iax2_peer *peer, int heldcall)
static int iax2_poke_peer_cb (void *obj, void *arg, int flags)
static int iax2_poke_peer_s (const void *data)
static int iax2_predestroy (int callno)
static void * iax2_process_thread (void *data)
static void iax2_process_thread_cleanup (void *data)
static int iax2_prov_app (struct ast_channel *chan, void *data)
static int iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
static int iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen)
 Queue a control frame on the ast_channel owner.
static int iax2_queue_frame (int callno, struct ast_frame *f)
 Queue a frame to a call's owning asterisk channel.
static int iax2_queue_hangup (int callno)
 Queue a hangup frame on the ast_channel owner.
static struct ast_frameiax2_read (struct ast_channel *c)
static int iax2_register (const char *value, int lineno)
static struct ast_channeliax2_request (const char *type, int format, void *data, int *cause)
static int iax2_sched_add (struct sched_context *con, int when, ast_sched_cb callback, const void *data)
static int iax2_sched_replace (int id, struct 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)
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 match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
static void memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
static void memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
static void merge_encryption (struct chan_iax2_pvt *p, unsigned int enc)
static void mwi_event_cb (const struct ast_event *event, void *userdata)
static void * network_thread (void *ignore)
static struct chan_iax2_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 sockaddr_in *sin)
static void peercnt_remove (struct peercnt *peercnt)
static int peercnt_remove_by_addr (struct sockaddr_in *sin)
static int peercnt_remove_cb (const void *obj)
static void poke_all_peers (void)
static int prune_addr_range_cb (void *obj, void *arg, int flags)
static void prune_peers (void)
static void prune_users (void)
static int pvt_cmp_cb (void *obj, void *arg, int flags)
static void pvt_destructor (void *obj)
static int pvt_hash_cb (const void *obj, const int flags)
static int queue_signalling (struct chan_iax2_pvt *pvt, struct ast_frame *f)
 All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.
static int raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
static struct iax2_peerrealtime_peer (const char *peername, struct sockaddr_in *sin)
static void realtime_update_peer (const char *peername, struct sockaddr_in *sin, time_t regtime)
static struct iax2_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 void * sched_thread (void *ignore)
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_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_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
static int try_firmware (char *s)
static int try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static int uncompress_subclass (unsigned char csub)
static void unlink_peer (struct iax2_peer *peer)
static int unload_module (void)
static void unlock_both (unsigned short callno0, unsigned short callno1)
static void unwrap_timestamp (struct iax_frame *fr)
static void update_jbsched (struct chan_iax2_pvt *pvt)
static void update_max_nontrunk (void)
static void update_max_trunk (void)
static int update_packet (struct iax_frame *f)
static int update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
static int user_cmp_cb (void *obj, void *arg, int flags)
static int user_delme_cb (void *obj, void *arg, int flags)
static void user_destructor (void *obj)
static int user_hash_cb (const void *obj, const int flags)
static struct iax2_useruser_ref (struct iax2_user *user)
static struct iax2_useruser_unref (struct iax2_user *user)
static void vnak_retransmit (int callno, int last)
static int wait_for_peercallno (struct chan_iax2_pvt *pvt)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, }
static char accountcode [AST_MAX_ACCOUNT_CODE]
static int adsi = 0
static int amaflags = 0
static struct ast_module_infoast_module_info = &__mod_info
static int authdebug = 1
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
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_flags globalflags = { 0 }
static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH
static int iax2_encryption = 0
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
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 struct ast_netsock_listoutsock
static char * papp = "IAX2Provision"
static char * pdescrip
static struct ao2_containerpeercnts
static struct ao2_containerpeers
static int ping_time = 21
static struct ast_codec_pref prefs
static char * psyn = "Provision a calling IAXy with a given template"
struct {
   unsigned int   cos
   unsigned int   tos
qos
static int randomcalltokendata
static char regcontext [AST_MAX_CONTEXT] = ""
static int resyncthreshold = 1000
static struct sched_contextsched
static ast_cond_t sched_cond
static ast_mutex_t sched_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP )
static pthread_t schedthreadid = AST_PTHREADT_NULL
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 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


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

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

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

Referenced by handle_call_token().

#define CALLTOKEN_IE_FORMAT   "%u?%s"

Referenced by handle_call_token().

#define DEBUG_SCHED_MULTITHREAD

Definition at line 104 of file chan_iax2.c.

#define DEBUG_SUPPORT

Definition at line 120 of file chan_iax2.c.

#define DEFAULT_CONTEXT   "default"

Definition at line 139 of file chan_iax2.c.

Referenced by check_access(), and handle_cli_iax2_show_users().

#define DEFAULT_DROP   3

Definition at line 118 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

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

Referenced by build_peer().

#define DEFAULT_MAX_THREAD_COUNT   100

Definition at line 115 of file chan_iax2.c.

#define DEFAULT_MAXMS   2000

Definition at line 206 of file chan_iax2.c.

#define DEFAULT_RETRY_TIME   1000

Definition at line 116 of file chan_iax2.c.

Referenced by __find_callno(), and complete_transfer().

#define DEFAULT_THREAD_COUNT   10

Definition at line 114 of file chan_iax2.c.

#define DEFAULT_TRUNKDATA   640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 488 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

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

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

#define FORMAT   "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"

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

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

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

#define FORMAT2   "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"

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

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

#define GAMMA   (0.01)

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

Referenced by iax2_trunk_queue().

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

Definition at line 211 of file chan_iax2.c.

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

#define IAX_CAPABILITY_FULLBANDWIDTH   (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED)

Definition at line 188 of file chan_iax2.c.

Referenced by cache_get_callno_locked(), and set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH

Value:

Definition at line 197 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWFREE

Value:

Definition at line 202 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH

Definition at line 190 of file chan_iax2.c.

Referenced by set_config().

#define IAX_DEBUGDIGEST ( msg,
key   ) 

Definition at line 214 of file chan_iax2.c.

Referenced by iax2_key_rotate(), and socket_process().

#define MARK_IAX_SUBCLASS_TX   0x8000

Definition at line 496 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 485 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 743 of file chan_iax2.c.

Referenced by load_objects().

#define MAX_RETRY_TIME   10000

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

#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 134 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 155 of file chan_iax2.c.

Referenced by set_config(), and set_config_destroy().

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

Definition at line 747 of file chan_iax2.c.

Referenced by load_module(), and load_objects().

#define MEMORY_SIZE   100

Definition at line 117 of file chan_iax2.c.

#define MIN_JITTER_BUFFER   10

Definition at line 486 of file chan_iax2.c.

#define MIN_RETRY_TIME   100

Definition at line 482 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME   60

Definition at line 122 of file chan_iax2.c.

Referenced by make_trunk(), and sched_delay_remove().

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

Definition at line 111 of file chan_iax2.c.

Referenced by __auto_congest(), __get_from_jb(), acf_channel_read(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), iax2_write(), and scheduled_destroy().

#define SCHED_MULTITHREADED

Definition at line 100 of file chan_iax2.c.

#define schedule_action ( func,
data   )     __schedule_action(func, data, __PRETTY_FUNCTION__)

Definition at line 1270 of file chan_iax2.c.

Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().

#define TRUNK_CALL_START   IAX_MAX_CALLS / 2

Definition at line 957 of file chan_iax2.c.

Referenced by __find_callno(), create_callno_pools(), make_trunk(), replace_callno(), update_max_nontrunk(), and update_max_trunk().

#define TS_GAP_FOR_JB_RESYNC   5000

Definition at line 493 of file chan_iax2.c.


Enumeration Type Documentation

anonymous enum

Enumerator:
CACHE_FLAG_EXISTS  Extension exists
CACHE_FLAG_NONEXISTENT  Extension is nonexistent
CACHE_FLAG_CANEXIST  Extension can exist
CACHE_FLAG_PENDING  Waiting to hear back response
CACHE_FLAG_TIMEOUT  Timed out
CACHE_FLAG_TRANSMITTED  Request transmitted
CACHE_FLAG_UNKNOWN  Timeout
CACHE_FLAG_MATCHMORE  Matchmore

Definition at line 803 of file chan_iax2.c.

00803      {
00804    /*! Extension exists */
00805    CACHE_FLAG_EXISTS      = (1 << 0),
00806    /*! Extension is nonexistent */
00807    CACHE_FLAG_NONEXISTENT = (1 << 1),
00808    /*! Extension can exist */
00809    CACHE_FLAG_CANEXIST    = (1 << 2),
00810    /*! Waiting to hear back response */
00811    CACHE_FLAG_PENDING     = (1 << 3),
00812    /*! Timed out */
00813    CACHE_FLAG_TIMEOUT     = (1 << 4),
00814    /*! Request transmitted */
00815    CACHE_FLAG_TRANSMITTED = (1 << 5),
00816    /*! Timeout */
00817    CACHE_FLAG_UNKNOWN     = (1 << 6),
00818    /*! Matchmore */
00819    CACHE_FLAG_MATCHMORE   = (1 << 7),
00820 };

anonymous enum

Enumerator:
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 1727 of file chan_iax2.c.

01727      {
01728    /* do not allow a new call number, only search ones in use for match */
01729    NEW_PREVENT = 0,
01730    /* search for match first, then allow a new one to be allocated */
01731    NEW_ALLOW = 1,
01732    /* do not search for match, force a new call number */
01733    NEW_FORCE = 2,
01734    /* do not search for match, force a new call number.  Signifies call number
01735     * has been calltoken validated */
01736    NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01737 };

enum calltoken_peer_enum

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

00310                          {
00311    /*! \brief Default calltoken required unless the ip is in the ignorelist */
00312    CALLTOKEN_DEFAULT = 0,
00313    /*! \brief Require call token validation. */
00314    CALLTOKEN_YES = 1,
00315    /*! \brief Require call token validation after a successful registration
00316     *         using call token validation occurs. */
00317    CALLTOKEN_AUTO = 2,
00318    /*! \brief Do not require call token validation. */
00319    CALLTOKEN_NO = 3,
00320 };

enum iax2_flags

Enumerator:
IAX_HASCALLERID  CallerID has been specified
IAX_DELME  Needs to be deleted
IAX_TEMPONLY  Temporary (realtime)
IAX_TRUNK  Treat as a trunk
IAX_NOTRANSFER  Don't native bridge
IAX_USEJITTERBUF  Use jitter buffer
IAX_DYNAMIC  dynamic peer
IAX_SENDANI  Send ANI along with CallerID
IAX_ALREADYGONE  Already disconnected
IAX_PROVISION  This is a provisioning request
IAX_QUELCH  Whether or not we quelch audio
IAX_ENCRYPTED  Whether we should assume encrypted tx/rx
IAX_KEYPOPULATED  Whether we have a key populated
IAX_CODEC_USER_FIRST  are we willing to let the other guy choose the codec?
IAX_CODEC_NOPREFS  Force old behaviour by turning off prefs
IAX_CODEC_NOCAP  only consider requested format and ignore capabilities
IAX_RTCACHEFRIENDS  let realtime stay till your reload
IAX_RTUPDATE  Send a realtime update
IAX_RTAUTOCLEAR  erase me on expire
IAX_FORCEJITTERBUF  Force jitterbuffer, even when bridged to a channel that can take jitter
IAX_RTIGNOREREGEXPIRE  When using realtime, ignore registration expiration
IAX_TRUNKTIMESTAMPS  Send trunk timestamps
IAX_TRANSFERMEDIA  When doing IAX2 transfers, transfer media only
IAX_MAXAUTHREQ  Maximum outstanding AUTHREQ restriction is in place
IAX_DELAYPBXSTART  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
IAX_ALLOWFWDOWNLOAD  Allow the FWDOWNL command?
IAX_SHRINKCALLERID  Turn on and off caller id shrinking

Definition at line 270 of file chan_iax2.c.

00270                 {
00271    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00272    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00273    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00274    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00275    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00276    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00277    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00278    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00279         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00280    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00281    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00282    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00283    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00284    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00285    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00286    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00287    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00288    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00289    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00290    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00291    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00292    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00293    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00294    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00295    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00296    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00297                        response, so that we've achieved a three-way handshake with
00298                        them before sending voice or anything else*/
00299    IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */
00300    IAX_SHRINKCALLERID = (1 << 27),   /*!< Turn on and off caller id shrinking */
00301 };

enum iax2_state

Enumerator:
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 259 of file chan_iax2.c.

00259                 {
00260    IAX_STATE_STARTED =        (1 << 0),
00261    IAX_STATE_AUTHENTICATED =  (1 << 1),
00262    IAX_STATE_TBD =            (1 << 2),
00263 };

enum iax2_thread_iostate

Enumerator:
IAX_IOSTATE_IDLE 
IAX_IOSTATE_READY 
IAX_IOSTATE_PROCESSING 
IAX_IOSTATE_SCHEDREADY 

Definition at line 844 of file chan_iax2.c.

enum iax2_thread_type

Enumerator:
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 851 of file chan_iax2.c.

00851                       {
00852    IAX_THREAD_TYPE_POOL,
00853    IAX_THREAD_TYPE_DYNAMIC,
00854 };

enum iax_reg_state

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

enum iax_transfer_state

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


Function Documentation

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

Definition at line 3213 of file chan_iax2.c.

References AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), attempt_transmit(), iax_frame::callno, chan_iax2_pvt::error, f, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxs, iax2_trunk_peer::list, LOG_WARNING, MAX_RETRY_TIME, ast_format::name, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), send_packet(), update_packet(), and iax2_registry::us.

Referenced by attempt_transmit().

03214 {
03215    /* Attempt to transmit the frame to the remote peer...
03216       Called without iaxsl held. */
03217    struct iax_frame *f = (struct iax_frame *)data;
03218    int freeme = 0;
03219    int callno = f->callno;
03220    /* Make sure this call is still active */
03221    if (callno) 
03222       ast_mutex_lock(&iaxsl[callno]);
03223    if (callno && iaxs[callno]) {
03224       if ((f->retries < 0) /* Already ACK'd */ ||
03225           (f->retries >= max_retries) /* Too many attempts */) {
03226             /* Record an error if we've transmitted too many times */
03227             if (f->retries >= max_retries) {
03228                if (f->transfer) {
03229                   /* Transfer timeout */
03230                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03231                } else if (f->final) {
03232                   if (f->final) 
03233                      iax2_destroy(callno);
03234                } else {
03235                   if (iaxs[callno]->owner)
03236                      ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno);
03237                   iaxs[callno]->error = ETIMEDOUT;
03238                   if (iaxs[callno]->owner) {
03239                      struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03240                      /* Hangup the fd */
03241                      iax2_queue_frame(callno, &fr); /* XXX */
03242                      /* Remember, owner could disappear */
03243                      if (iaxs[callno] && iaxs[callno]->owner)
03244                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03245                   } else {
03246                      if (iaxs[callno]->reg) {
03247                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03248                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03249                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03250                      }
03251                      iax2_destroy(callno);
03252                   }
03253                }
03254 
03255             }
03256             freeme = 1;
03257       } else {
03258          /* Update it if it needs it */
03259          update_packet(f);
03260          /* Attempt transmission */
03261          send_packet(f);
03262          f->retries++;
03263          /* Try again later after 10 times as long */
03264          f->retrytime *= 10;
03265          if (f->retrytime > MAX_RETRY_TIME)
03266             f->retrytime = MAX_RETRY_TIME;
03267          /* Transfer messages max out at one second */
03268          if (f->transfer && (f->retrytime > 1000))
03269             f->retrytime = 1000;
03270          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03271       }
03272    } else {
03273       /* Make sure it gets freed */
03274       f->retries = -1;
03275       freeme = 1;
03276    }
03277    if (callno)
03278       ast_mutex_unlock(&iaxsl[callno]);
03279    /* Do not try again */
03280    if (freeme) {
03281       /* Don't attempt delivery, just remove it from the queue */
03282       AST_LIST_LOCK(&frame_queue);
03283       AST_LIST_REMOVE(&frame_queue, f, list);
03284       AST_LIST_UNLOCK(&frame_queue);
03285       f->retrans = -1; /* this is safe because this is the scheduled function */
03286       /* Free the IAX frame */
03287       iax2_frame_free(f);
03288    }
03289 }

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

Definition at line 8440 of file chan_iax2.c.

References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, and send_command_final().

Referenced by auth_reject().

08441 {
08442    /* Called from IAX thread only, without iaxs lock */
08443    int callno = (int)(long)(nothing);
08444    struct iax_ie_data ied;
08445    ast_mutex_lock(&iaxsl[callno]);
08446    if (iaxs[callno]) {
08447       memset(&ied, 0, sizeof(ied));
08448       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08449          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08450          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08451       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08452          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08453          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08454       }
08455       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08456    }
08457    ast_mutex_unlock(&iaxsl[callno]);
08458 }

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

Definition at line 4323 of file chan_iax2.c.

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

Referenced by auto_congest().

04324 {
04325    int callno = PTR_TO_CALLNO(nothing);
04326    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
04327    ast_mutex_lock(&iaxsl[callno]);
04328    if (iaxs[callno]) {
04329       iaxs[callno]->initid = -1;
04330       iax2_queue_frame(callno, &f);
04331       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04332    }
04333    ast_mutex_unlock(&iaxsl[callno]);
04334 }

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

Definition at line 8489 of file chan_iax2.c.

References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, and send_command_final().

Referenced by auto_hangup().

08490 {
08491    /* Called from IAX thread only, without iaxs lock */
08492    int callno = (int)(long)(nothing);
08493    struct iax_ie_data ied;
08494    ast_mutex_lock(&iaxsl[callno]);
08495    if (iaxs[callno]) {
08496       memset(&ied, 0, sizeof(ied));
08497       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
08498       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
08499       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
08500    }
08501    ast_mutex_unlock(&iaxsl[callno]);
08502 }

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

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

Referenced by __get_from_jb(), and schedule_delivery().

03009 {
03010    /* Just deliver the packet by using queueing.  This is called by
03011      the IAX thread with the iaxsl lock held. */
03012    struct iax_frame *fr = data;
03013    fr->retrans = -1;
03014    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03015    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
03016       iax2_queue_frame(fr->callno, &fr->af);
03017    /* Free our iax frame */
03018    iax2_frame_free(fr);
03019    /* And don't run again */
03020    return 0;
03021 }

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

Definition at line 8088 of file chan_iax2.c.

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

Referenced by expire_registry().

08089 {
08090    struct iax2_peer *peer = (struct iax2_peer *) data;
08091 
08092    if (!peer)
08093       return;
08094 
08095    peer->expire = -1;
08096 
08097    ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08098    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08099       realtime_update_peer(peer->name, &peer->addr, 0);
08100    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08101    /* modify entry in peercnts table as _not_ registered */
08102    peercnt_modify(0, 0, &peer->addr);
08103    /* Reset the address */
08104    memset(&peer->addr, 0, sizeof(peer->addr));
08105    /* Reset expiry value */
08106    peer->expiry = min_reg_expire;
08107    if (!ast_test_flag(peer, IAX_TEMPONLY))
08108       ast_db_del("IAX/Registry", peer->name);
08109    register_peer_exten(peer, 0);
08110    ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
08111    if (iax2_regfunk)
08112       iax2_regfunk(peer->name, 0);
08113 
08114    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
08115       unlink_peer(peer);
08116 
08117    peer_unref(peer);
08118 }

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

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

Referenced by find_callno(), and find_callno_locked().

02486 {
02487    int res = 0;
02488    int x;
02489    /* this call is calltoken validated as long as it is either NEW_FORCE
02490     * or NEW_ALLOW_CALLTOKEN_VALIDATED */
02491    int validated = (new > NEW_ALLOW) ? 1 : 0;
02492    char host[80];
02493 
02494    if (new <= NEW_ALLOW) {
02495       if (callno) {
02496          struct chan_iax2_pvt *pvt;
02497          struct chan_iax2_pvt tmp_pvt = {
02498             .callno = dcallno,
02499             .peercallno = callno,
02500             .transfercallno = callno,
02501             /* hack!! */
02502             .frames_received = check_dcallno,
02503          };
02504 
02505          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02506          /* this works for finding normal call numbers not involving transfering */ 
02507          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02508             if (return_locked) {
02509                ast_mutex_lock(&iaxsl[pvt->callno]);
02510             }
02511             res = pvt->callno;
02512             ao2_ref(pvt, -1);
02513             pvt = NULL;
02514             return res;
02515          }
02516          /* this searches for transfer call numbers that might not get caught otherwise */
02517          memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02518          memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02519          if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02520             if (return_locked) {
02521                ast_mutex_lock(&iaxsl[pvt->callno]);
02522             }
02523             res = pvt->callno;
02524             ao2_ref(pvt, -1);
02525             pvt = NULL;
02526             return res;
02527          }
02528       }
02529          /* This will occur on the first response to a message that we initiated,
02530        * such as a PING. */
02531       if (dcallno) {
02532          ast_mutex_lock(&iaxsl[dcallno]);
02533       }
02534       if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02535          iaxs[dcallno]->peercallno = callno;
02536          res = dcallno;
02537          store_by_peercallno(iaxs[dcallno]);
02538          if (!res || !return_locked) {
02539             ast_mutex_unlock(&iaxsl[dcallno]);
02540          }
02541          return res;
02542       }
02543       if (dcallno) {
02544          ast_mutex_unlock(&iaxsl[dcallno]);
02545       }
02546 #ifdef IAX_OLD_FIND
02547       /* If we get here, we SHOULD NOT find a call structure for this
02548          callno; if we do, it means that there is a call structure that
02549          has a peer callno but did NOT get entered into the hash table,
02550          which is bad.
02551 
02552          If we find a call structure using this old, slow method, output a log
02553          message so we'll know about it. After a few months of leaving this in
02554          place, if we don't hear about people seeing these messages, we can
02555          remove this code for good.
02556       */
02557 
02558       for (x = 1; !res && x < maxnontrunkcall; x++) {
02559          ast_mutex_lock(&iaxsl[x]);
02560          if (iaxs[x]) {
02561             /* Look for an exact match */
02562             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02563                res = x;
02564             }
02565          }
02566          if (!res || !return_locked)
02567             ast_mutex_unlock(&iaxsl[x]);
02568       }
02569       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02570          ast_mutex_lock(&iaxsl[x]);
02571          if (iaxs[x]) {
02572             /* Look for an exact match */
02573             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02574                res = x;
02575             }
02576          }
02577          if (!res || !return_locked)
02578             ast_mutex_unlock(&iaxsl[x]);
02579       }
02580 #endif
02581    }
02582    if (!res && (new >= NEW_ALLOW)) {
02583       struct callno_entry *callno_entry;
02584       /* It may seem odd that we look through the peer list for a name for
02585        * this *incoming* call.  Well, it is weird.  However, users don't
02586        * have an IP address/port number that we can match against.  So,
02587        * this is just checking for a peer that has that IP/port and
02588        * assuming that we have a user of the same name.  This isn't always
02589        * correct, but it will be changed if needed after authentication. */
02590       if (!iax2_getpeername(*sin, host, sizeof(host)))
02591          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02592 
02593       if (peercnt_add(sin)) {
02594          /* This address has hit its callnumber limit.  When the limit
02595           * is reached, the connection is not added to the peercnts table.*/
02596          return 0;
02597       }
02598 
02599       if (!(callno_entry = get_unused_callno(0, validated))) {
02600          /* since we ran out of space, remove the peercnt
02601           * entry we added earlier */
02602          peercnt_remove_by_addr(sin);
02603          ast_log(LOG_WARNING, "No more space\n");
02604          return 0;
02605       }
02606       x = callno_entry->callno;
02607       ast_mutex_lock(&iaxsl[x]);
02608 
02609       iaxs[x] = new_iax(sin, host);
02610       update_max_nontrunk();
02611       if (iaxs[x]) {
02612          if (iaxdebug)
02613             ast_debug(1, "Creating new call structure %d\n", x);
02614          iaxs[x]->callno_entry = callno_entry;
02615          iaxs[x]->sockfd = sockfd;
02616          iaxs[x]->addr.sin_port = sin->sin_port;
02617          iaxs[x]->addr.sin_family = sin->sin_family;
02618          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02619          iaxs[x]->peercallno = callno;
02620          iaxs[x]->callno = x;
02621          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02622          iaxs[x]->expiry = min_reg_expire;
02623          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02624          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02625          iaxs[x]->amaflags = amaflags;
02626          ast_copy_flags(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02627          
02628          ast_string_field_set(iaxs[x], accountcode, accountcode);
02629          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02630          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02631          ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02632 
02633          if (iaxs[x]->peercallno) {
02634             store_by_peercallno(iaxs[x]);
02635          }
02636       } else {
02637          ast_log(LOG_WARNING, "Out of resources\n");
02638          ast_mutex_unlock(&iaxsl[x]);
02639          replace_callno(callno_entry);
02640          return 0;
02641       }
02642       if (!return_locked)
02643          ast_mutex_unlock(&iaxsl[x]);
02644       res = x;
02645    }
02646    return res;
02647 }

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

Definition at line 3776 of file chan_iax2.c.

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

Referenced by get_from_jb().

03777 {
03778    int callno = PTR_TO_CALLNO(p);
03779    struct chan_iax2_pvt *pvt = NULL;
03780    struct iax_frame *fr;
03781    jb_frame frame;
03782    int ret;
03783    long ms;
03784    long next;
03785    struct timeval now = ast_tvnow();
03786    
03787    /* Make sure we have a valid private structure before going on */
03788    ast_mutex_lock(&iaxsl[callno]);
03789    pvt = iaxs[callno];
03790    if (!pvt) {
03791       /* No go! */
03792       ast_mutex_unlock(&iaxsl[callno]);
03793       return;
03794    }
03795 
03796    pvt->jbid = -1;
03797    
03798    /* round up a millisecond since ast_sched_runq does; */
03799    /* prevents us from spinning while waiting for our now */
03800    /* to catch up with runq's now */
03801    now.tv_usec += 1000;
03802    
03803    ms = ast_tvdiff_ms(now, pvt->rxcore);
03804    
03805    if(ms >= (next = jb_next(pvt->jb))) {
03806       ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
03807       switch(ret) {
03808       case JB_OK:
03809          fr = frame.data;
03810          __do_deliver(fr);
03811          /* __do_deliver() can cause the call to disappear */
03812          pvt = iaxs[callno];
03813          break;
03814       case JB_INTERP:
03815       {
03816          struct ast_frame af = { 0, };
03817          
03818          /* create an interpolation frame */
03819          af.frametype = AST_FRAME_VOICE;
03820          af.subclass = pvt->voiceformat;
03821          af.samples  = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
03822          af.src  = "IAX2 JB interpolation";
03823          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03824          af.offset = AST_FRIENDLY_OFFSET;
03825          
03826          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
03827           * which we'd need to malloc, and then it would free it.  That seems like a drag */
03828          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03829             iax2_queue_frame(callno, &af);
03830             /* iax2_queue_frame() could cause the call to disappear */
03831             pvt = iaxs[callno];
03832          }
03833       }
03834          break;
03835       case JB_DROP:
03836          iax2_frame_free(frame.data);
03837          break;
03838       case JB_NOFRAME:
03839       case JB_EMPTY:
03840          /* do nothing */
03841          break;
03842       default:
03843          /* shouldn't happen */
03844          break;
03845       }
03846    }
03847    if (pvt)
03848       update_jbsched(pvt);
03849    ast_mutex_unlock(&iaxsl[callno]);
03850 }

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

Definition at line 7762 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

07763 {
07764    struct iax2_registry *reg = (struct iax2_registry *)data;
07765    reg->expire = -1;
07766    iax2_do_register(reg);
07767 }

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

Definition at line 11273 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, iax2_peer::pokefreqnotok, and sched.

Referenced by iax2_poke_noanswer().

11274 {
11275    struct iax2_peer *peer = (struct iax2_peer *)data;
11276    int callno;
11277 
11278    if (peer->lastms > -1) {
11279       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11280       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11281       ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
11282    }
11283    if ((callno = peer->callno) > 0) {
11284       ast_mutex_lock(&iaxsl[callno]);
11285       iax2_destroy(callno);
11286       ast_mutex_unlock(&iaxsl[callno]);
11287    }
11288    peer->callno = 0;
11289    peer->lastms = -1;
11290    /* Try again quickly */
11291    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11292    if (peer->pokeexpire == -1)
11293       peer_unref(peer);
11294 }

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

Definition at line 8552 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

08553 {
08554    struct iax2_peer *peer = (struct iax2_peer *)data;
08555    iax2_poke_peer(peer, 0);
08556    peer_unref(peer);
08557 }

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

Definition at line 6217 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_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, name, peer_status(), peer_unref(), peers, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, status, and iax2_peer::username.

Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().

06218 {
06219    regex_t regexbuf;
06220    int havepattern = 0;
06221    int total_peers = 0;
06222    int online_peers = 0;
06223    int offline_peers = 0;
06224    int unmonitored_peers = 0;
06225    struct ao2_iterator i;
06226 
06227 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
06228 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
06229 
06230    struct iax2_peer *peer = NULL;
06231    char name[256];
06232    int registeredonly=0;
06233    char *term = manager ? "\r\n" : "\n";
06234    char idtext[256] = "";
06235    switch (argc) {
06236    case 6:
06237       if (!strcasecmp(argv[3], "registered"))
06238          registeredonly = 1;
06239       else
06240          return RESULT_SHOWUSAGE;
06241       if (!strcasecmp(argv[4], "like")) {
06242          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06243             return RESULT_SHOWUSAGE;
06244          havepattern = 1;
06245       } else
06246          return RESULT_SHOWUSAGE;
06247       break;
06248    case 5:
06249       if (!strcasecmp(argv[3], "like")) {
06250          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06251             return RESULT_SHOWUSAGE;
06252          havepattern = 1;
06253       } else
06254          return RESULT_SHOWUSAGE;
06255       break;
06256    case 4:
06257       if (!strcasecmp(argv[3], "registered"))
06258          registeredonly = 1;
06259       else
06260          return RESULT_SHOWUSAGE;
06261       break;
06262    case 3:
06263       break;
06264    default:
06265       return RESULT_SHOWUSAGE;
06266    }
06267 
06268 
06269    if (!s)
06270       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
06271 
06272    i = ao2_iterator_init(peers, 0);
06273    for (peer = ao2_iterator_next(&i); peer; 
06274       peer_unref(peer), peer = ao2_iterator_next(&i)) {
06275       char nm[20];
06276       char status[20];
06277       char srch[2000];
06278       int retstatus;
06279 
06280       if (registeredonly && !peer->addr.sin_addr.s_addr)
06281          continue;
06282       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
06283          continue;
06284 
06285       if (!ast_strlen_zero(peer->username))
06286          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06287       else
06288          ast_copy_string(name, peer->name, sizeof(name));
06289       
06290       retstatus = peer_status(peer, status, sizeof(status));
06291       if (retstatus > 0)
06292          online_peers++;
06293       else if (!retstatus)
06294          offline_peers++;
06295       else
06296          unmonitored_peers++;
06297       
06298       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06299       
06300       snprintf(srch, sizeof(srch), FORMAT, name, 
06301           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
06302           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06303           nm,
06304           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
06305           peer->encmethods ? "(E)" : "   ", status, term);
06306       
06307       if (s)
06308          astman_append(s, 
06309             "Event: PeerEntry\r\n%s"
06310             "Channeltype: IAX2\r\n"
06311             "ChanObjectType: peer\r\n"
06312             "ObjectName: %s\r\n"
06313             "IPaddress: %s\r\n"
06314             "IPport: %d\r\n"
06315             "Dynamic: %s\r\n"
06316             "Status: %s\r\n\r\n",
06317             idtext,
06318             name,
06319             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
06320             ntohs(peer->addr.sin_port),
06321             ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no",
06322             status);
06323       
06324       else
06325          ast_cli(fd, FORMAT, name, 
06326             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
06327             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06328             nm,
06329             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
06330             peer->encmethods ? "(E)" : "   ", status, term);
06331       total_peers++;
06332    }
06333    ao2_iterator_destroy(&i);
06334 
06335    if (!s)
06336       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
06337 
06338    if (havepattern)
06339       regfree(&regexbuf);
06340 
06341    return RESULT_SUCCESS;
06342 #undef FORMAT
06343 #undef FORMAT2
06344 }

static void __reg_module ( void   )  [static]

Definition at line 13752 of file chan_iax2.c.

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

Definition at line 1245 of file chan_iax2.c.

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

01246 {
01247    struct iax2_thread *thread = NULL;
01248    static time_t lasterror;
01249    static time_t t;
01250 
01251    thread = find_idle_thread();
01252 
01253    if (thread != NULL) {
01254       thread->schedfunc = func;
01255       thread->scheddata = data;
01256       thread->iostate = IAX_IOSTATE_SCHEDREADY;
01257 #ifdef DEBUG_SCHED_MULTITHREAD
01258       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01259 #endif
01260       signal_condition(&thread->lock, &thread->cond);
01261       return 0;
01262    }
01263    time(&t);
01264    if (t != lasterror) 
01265       ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01266    lasterror = t;
01267 
01268    return -1;
01269 }

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

References f, iax2_send(), and queue_signalling().

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

06970 {
06971    struct ast_frame f = { 0, };
06972    int res = 0;
06973 
06974    f.frametype = type;
06975    f.subclass = command;
06976    f.datalen = datalen;
06977    f.src = __FUNCTION__;
06978    f.data.ptr = (void *) data;
06979 
06980    if ((res = queue_signalling(i, &f)) <= 0) {
06981       return res;
06982    }
06983 
06984    return iax2_send(i, &f, ts, seqno, now, transfer, final);
06985 }

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

Definition at line 1338 of file chan_iax2.c.

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

Referenced by send_lagrq().

01339 {
01340    int callno = (long) data;
01341 
01342    ast_mutex_lock(&iaxsl[callno]);
01343 
01344    if (iaxs[callno]) {
01345       if (iaxs[callno]->peercallno) {
01346          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01347          iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01348       } else {
01349          /* I am the schedule, so I'm allowed to do this */
01350          iaxs[callno]->lagid = -1;
01351       }
01352    } else {
01353       ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01354    }
01355 
01356    ast_mutex_unlock(&iaxsl[callno]);
01357 }

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

Definition at line 1293 of file chan_iax2.c.

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

Referenced by send_ping().

01294 {
01295    int callno = (long) data;
01296 
01297    ast_mutex_lock(&iaxsl[callno]);
01298 
01299    if (iaxs[callno]) {
01300       if (iaxs[callno]->peercallno) {
01301          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01302          iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01303       } else {
01304          /* I am the schedule, so I'm allowed to do this */
01305          iaxs[callno]->pingid = -1;
01306       }
01307    } else {
01308       ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01309    }
01310 
01311    ast_mutex_unlock(&iaxsl[callno]);
01312 }

static int __unload_module ( void   )  [static]

Definition at line 13439 of file chan_iax2.c.

References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_signal(), ast_context_destroy(), ast_context_find(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_release(), AST_PTHREADT_NULL, ast_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), callno_limits, calltoken_ignores, cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, iax_peercallno_pvts, iax_provision_unload(), iax_transfercallno_pvts, iaxactivethreadcount, iaxs, netsock, outsock, papp, peercnts, peers, reload_firmware(), sched, sched_context_destroy(), sched_lock, thread, timer, and users.

13440 {
13441    struct iax2_thread *thread = NULL;
13442    struct ast_context *con;
13443    int x;
13444 
13445    /* Make sure threads do not hold shared resources when they are canceled */
13446    
13447    /* Grab the sched lock resource to keep it away from threads about to die */
13448    /* Cancel the network thread, close the net socket */
13449    if (netthreadid != AST_PTHREADT_NULL) {
13450       AST_LIST_LOCK(&frame_queue);
13451       ast_mutex_lock(&sched_lock);
13452       pthread_cancel(netthreadid);
13453       ast_cond_signal(&sched_cond);
13454       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
13455       AST_LIST_UNLOCK(&frame_queue);
13456       pthread_join(netthreadid, NULL);
13457    }
13458    if (schedthreadid != AST_PTHREADT_NULL) {
13459       ast_mutex_lock(&sched_lock);
13460       pthread_cancel(schedthreadid);
13461       ast_cond_signal(&sched_cond);
13462       ast_mutex_unlock(&sched_lock);
13463       pthread_join(schedthreadid, NULL);
13464    }
13465 
13466    /* Call for all threads to halt */
13467    AST_LIST_LOCK(&idle_list);
13468    while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list)))
13469       pthread_cancel(thread->threadid);
13470    AST_LIST_UNLOCK(&idle_list);
13471 
13472    AST_LIST_LOCK(&active_list);
13473    while ((thread = AST_LIST_REMOVE_HEAD(&active_list, list)))
13474       pthread_cancel(thread->threadid);
13475    AST_LIST_UNLOCK(&active_list);
13476 
13477    AST_LIST_LOCK(&dynamic_list);
13478    while ((thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list)))
13479       pthread_cancel(thread->threadid);
13480    AST_LIST_UNLOCK(&dynamic_list);
13481    
13482    /* Wait for threads to exit */
13483    while(0 < iaxactivethreadcount)
13484       usleep(10000);
13485    
13486    ast_netsock_release(netsock);
13487    ast_netsock_release(outsock);
13488    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13489       if (iaxs[x]) {
13490          iax2_destroy(x);
13491       }
13492    }
13493    ast_manager_unregister( "IAXpeers" );
13494    ast_manager_unregister( "IAXpeerlist" );
13495    ast_manager_unregister( "IAXnetstats" );
13496    ast_unregister_application(papp);
13497    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
13498    ast_unregister_switch(&iax2_switch);
13499    ast_channel_unregister(&iax2_tech);
13500    delete_users();
13501    iax_provision_unload();
13502    sched_context_destroy(sched);
13503    reload_firmware(1);
13504 
13505    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13506       ast_mutex_destroy(&iaxsl[x]);
13507    }
13508 
13509    ao2_ref(peers, -1);
13510    ao2_ref(users, -1);
13511    ao2_ref(iax_peercallno_pvts, -1);
13512    ao2_ref(iax_transfercallno_pvts, -1);
13513    ao2_ref(peercnts, -1);
13514    ao2_ref(callno_limits, -1);
13515    ao2_ref(calltoken_ignores, -1);
13516    ao2_ref(callno_pool, -1);
13517    ao2_ref(callno_pool_trunk, -1);
13518    if (timer) {
13519       ast_timer_close(timer);
13520    }
13521 
13522    con = ast_context_find(regcontext);
13523    if (con)
13524       ast_context_destroy(con, "IAX2");
13525    ast_unload_realtime("iaxpeers");
13526    return 0;
13527 }

static void __unreg_module ( void   )  [static]

Definition at line 13752 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 13224 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_tech, iaxs, LOG_ERROR, chan_iax2_pvt::osptoken, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, and chan_iax2_pvt::username.

13225 {
13226    struct chan_iax2_pvt *pvt;
13227    unsigned int callno;
13228    int res = 0;
13229 
13230    if (!chan || chan->tech != &iax2_tech) {
13231       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13232       return -1;
13233    }
13234 
13235    callno = PTR_TO_CALLNO(chan->tech_pvt);
13236    ast_mutex_lock(&iaxsl[callno]);
13237    if (!(pvt = iaxs[callno])) {
13238       ast_mutex_unlock(&iaxsl[callno]);
13239       return -1;
13240    }
13241 
13242    if (!strcasecmp(args, "osptoken")) {
13243       ast_copy_string(buf, pvt->osptoken, buflen);
13244    } else if (!strcasecmp(args, "peerip")) {
13245       ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13246    } else if (!strcasecmp(args, "peername")) {
13247       ast_copy_string(buf, pvt->username, buflen);
13248    } else {
13249       res = -1;
13250    }
13251 
13252    ast_mutex_unlock(&iaxsl[callno]);
13253 
13254    return res;
13255 }

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

Definition at line 9220 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, chan, ast_datastore::data, ast_var_t::entries, iax2_variable_datastore_info, and var.

09221 {
09222    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09223    AST_LIST_HEAD(, ast_var_t) *varlist;
09224    struct ast_var_t *var;
09225 
09226    if (!variablestore) {
09227       *buf = '\0';
09228       return 0;
09229    }
09230    varlist = variablestore->data;
09231 
09232    AST_LIST_LOCK(varlist);
09233    AST_LIST_TRAVERSE(varlist, var, entries) {
09234       if (strcmp(var->name, data) == 0) {
09235          ast_copy_string(buf, var->value, len);
09236          break;
09237       }
09238    }
09239    AST_LIST_UNLOCK(varlist);
09240    return 0;
09241 }

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

Definition at line 9243 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(), chan, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_var_t::entries, iax2_variable_datastore_info, ast_datastore::inheritance, LOG_ERROR, and var.

09244 {
09245    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09246    AST_LIST_HEAD(, ast_var_t) *varlist;
09247    struct ast_var_t *var;
09248 
09249    if (!variablestore) {
09250       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09251       if (!variablestore) {
09252          ast_log(LOG_ERROR, "Memory allocation error\n");
09253          return -1;
09254       }
09255       varlist = ast_calloc(1, sizeof(*varlist));
09256       if (!varlist) {
09257          ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09258          return -1;
09259       }
09260 
09261       AST_LIST_HEAD_INIT(varlist);
09262       variablestore->data = varlist;
09263       variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09264       ast_channel_datastore_add(chan, variablestore);
09265    } else
09266       varlist = variablestore->data;
09267 
09268    AST_LIST_LOCK(varlist);
09269    AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09270       if (strcmp(var->name, data) == 0) {
09271          AST_LIST_REMOVE_CURRENT(entries);
09272          ast_var_delete(var);
09273          break;
09274       }
09275    }
09276    AST_LIST_TRAVERSE_SAFE_END;
09277    var = ast_var_assign(data, value);
09278    if (var)
09279       AST_LIST_INSERT_TAIL(varlist, var, entries);
09280    else
09281       ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09282    AST_LIST_UNLOCK(varlist);
09283    return 0;
09284 }

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

Definition at line 2238 of file chan_iax2.c.

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

Referenced by set_config().

02239 {
02240    struct addr_range tmp;
02241    struct addr_range *addr_range = NULL;
02242    struct ast_ha *ha = NULL;
02243    int error = 0;
02244 
02245    if (ast_strlen_zero(addr)) {
02246       ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02247       return -1;
02248    }
02249 
02250    ha = ast_append_ha("permit", addr, NULL, &error);
02251 
02252    /* check for valid config information */
02253    if (error) {
02254       ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02255       return -1;
02256    }
02257 
02258    ast_copy_ha(ha, &tmp.ha);
02259    /* find or create the addr_range */
02260    if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02261       ao2_lock(addr_range);
02262       addr_range->delme = 0;
02263       ao2_unlock(addr_range);
02264    } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02265       /* copy over config data into addr_range object */
02266       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
02267       ao2_link(calltoken_ignores, addr_range);
02268    } else {
02269       ast_free_ha(ha);
02270       return -1;
02271    }
02272 
02273    ast_free_ha(ha);
02274    ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02275 
02276    return 0;
02277 }

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

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

04398 {
04399    /* first make sure their are two empty bytes left in ied->buf */
04400    if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04401       ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;  /* type */
04402       ied->buf[ied->pos++] = 0;   /* data size,  ZERO in this case */
04403       pvt->calltoken_ie_len = 2;
04404    }
04405 }

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

Definition at line 1900 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.

Referenced by load_objects().

01901 {
01902    struct addr_range *lim1 = obj, *lim2 = arg;
01903    return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) &&
01904       (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ?
01905       CMP_MATCH | CMP_STOP : 0;
01906 }

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

Definition at line 1887 of file chan_iax2.c.

References addr_range::delme.

Referenced by set_config_destroy().

01888 {
01889    struct addr_range *lim = obj;
01890    lim->delme = 1;
01891    return 0;
01892 }

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

Definition at line 1894 of file chan_iax2.c.

References addr_range::ha, and ast_ha::netaddr.

Referenced by load_objects().

01895 {
01896    const struct addr_range *lim = obj;
01897    return abs((int) lim->ha.netaddr.s_addr);
01898 }

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

Definition at line 1920 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.

Referenced by calltoken_required(), and set_peercnt_limit().

01921 {
01922    struct addr_range *addr_range = obj;
01923    struct sockaddr_in *sin = arg;
01924 
01925    if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) {
01926       return CMP_MATCH | CMP_STOP;
01927    }
01928    return 0;
01929 }

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

Definition at line 7026 of file chan_iax2.c.

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

Referenced by check_access().

07027 {
07028    while(con) {
07029       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07030          return -1;
07031       con = con->next;
07032    }
07033    return 0;
07034 }

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

Definition at line 6731 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_show_netstats(), and manager_iax2_show_netstats().

06732 {
06733    int x;
06734    int numchans = 0;
06735    char first_message[10] = { 0, };
06736    char last_message[10] = { 0, };
06737 #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"
06738 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
06739    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06740       ast_mutex_lock(&iaxsl[x]);
06741       if (iaxs[x]) {
06742          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
06743          jb_info jbinfo;
06744          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06745          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06746 
06747          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06748             jb_getinfo(iaxs[x]->jb, &jbinfo);
06749             localjitter = jbinfo.jitter;
06750             localdelay = jbinfo.current - jbinfo.min;
06751             locallost = jbinfo.frames_lost;
06752             locallosspct = jbinfo.losspct/1000;
06753             localdropped = jbinfo.frames_dropped;
06754             localooo = jbinfo.frames_ooo;
06755          } else {
06756             localjitter = -1;
06757             localdelay = 0;
06758             locallost = -1;
06759             locallosspct = -1;
06760             localdropped = 0;
06761             localooo = -1;
06762          }
06763          if (s)
06764             astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06765                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06766                iaxs[x]->pingtime,
06767                localjitter,
06768                localdelay,
06769                locallost,
06770                locallosspct,
06771                localdropped,
06772                localooo,
06773                iaxs[x]->frames_received/1000,
06774                iaxs[x]->remote_rr.jitter,
06775                iaxs[x]->remote_rr.delay,
06776                iaxs[x]->remote_rr.losscnt,
06777                iaxs[x]->remote_rr.losspct,
06778                iaxs[x]->remote_rr.dropped,
06779                iaxs[x]->remote_rr.ooo,
06780                iaxs[x]->remote_rr.packets/1000,
06781                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06782                first_message,
06783                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06784                last_message);
06785          else
06786             ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06787                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06788                iaxs[x]->pingtime,
06789                localjitter,
06790                localdelay,
06791                locallost,
06792                locallosspct,
06793                localdropped,
06794                localooo,
06795                iaxs[x]->frames_received/1000,
06796                iaxs[x]->remote_rr.jitter,
06797                iaxs[x]->remote_rr.delay,
06798                iaxs[x]->remote_rr.losscnt,
06799                iaxs[x]->remote_rr.losspct,
06800                iaxs[x]->remote_rr.dropped,
06801                iaxs[x]->remote_rr.ooo,
06802                iaxs[x]->remote_rr.packets/1000,
06803                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06804                first_message,
06805                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06806                last_message);
06807          numchans++;
06808       }
06809       ast_mutex_unlock(&iaxsl[x]);
06810    }
06811 
06812    return numchans;
06813 }

static struct ast_channel* ast_iax2_new ( int  callno,
int  state,
int  capability 
) [static]

Create new call, interface with the PBX core.

Definition at line 5308 of file chan_iax2.c.

References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, chan_iax2_pvt::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_calloc, ast_channel_alloc, ast_channel_datastore_add(), ast_channel_free(), ast_copy_string(), ast_datastore_alloc, ast_datastore_free(), ast_debug, ast_free, ast_hangup(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_var_assign(), chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, chan_iax2_pvt::cid_name, chan_iax2_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, chan_iax2_pvt::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, chan_iax2_pvt::dnid, ast_var_t::entries, ast_channel::exten, chan_iax2_pvt::exten, chan_iax2_pvt::host, iax2_ami_channelupdate(), iax2_tech, iax2_variable_datastore_info, iaxs, chan_iax2_pvt::iaxvars, ast_datastore::inheritance, chan_iax2_pvt::language, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, parkinglot, chan_iax2_pvt::parkinglot, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_channel::rawreadformat, ast_channel::rawwriteformat, chan_iax2_pvt::rdnis, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, ast_variable::value, var, chan_iax2_pvt::vars, and ast_channel::writeformat.

Referenced by iax2_request(), and socket_process().

05309 {
05310    struct ast_channel *tmp;
05311    struct chan_iax2_pvt *i;
05312    struct ast_variable *v = NULL;
05313 
05314    if (!(i = iaxs[callno])) {
05315       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05316       return NULL;
05317    }
05318 
05319    /* Don't hold call lock */
05320    ast_mutex_unlock(&iaxsl[callno]);
05321    tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
05322    ast_mutex_lock(&iaxsl[callno]);
05323    if (i != iaxs[callno]) {
05324       if (tmp) {
05325          /* unlock and relock iaxsl[callno] to preserve locking order */
05326          ast_mutex_unlock(&iaxsl[callno]);
05327          ast_channel_free(tmp);
05328          ast_mutex_lock(&iaxsl[callno]);
05329       }
05330       return NULL;
05331    }
05332    iax2_ami_channelupdate(i);
05333    if (!tmp)
05334       return NULL;
05335    tmp->tech = &iax2_tech;
05336    /* We can support any format by default, until we get restricted */
05337    tmp->nativeformats = capability;
05338    tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05339    tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05340    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05341 
05342    if (!ast_strlen_zero(i->parkinglot))
05343       ast_string_field_set(tmp, parkinglot, i->parkinglot);
05344    /* Don't use ast_set_callerid() here because it will
05345     * generate a NewCallerID event before the NewChannel event */
05346    if (!ast_strlen_zero(i->ani))
05347       tmp->cid.cid_ani = ast_strdup(i->ani);
05348    else
05349       tmp->cid.cid_ani = ast_strdup(i->cid_num);
05350    tmp->cid.cid_dnid = ast_strdup(i->dnid);
05351    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05352    tmp->cid.cid_pres = i->calling_pres;
05353    tmp->cid.cid_ton = i->calling_ton;
05354    tmp->cid.cid_tns = i->calling_tns;
05355    if (!ast_strlen_zero(i->language))
05356       ast_string_field_set(tmp, language, i->language);
05357    if (!ast_strlen_zero(i->accountcode))
05358       ast_string_field_set(tmp, accountcode, i->accountcode);
05359    if (i->amaflags)
05360       tmp->amaflags = i->amaflags;
05361    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05362    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05363    if (i->adsi)
05364       tmp->adsicpe = i->peeradsicpe;
05365    else
05366       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05367    i->owner = tmp;
05368    i->capability = capability;
05369 
05370    /* Set inherited variables */
05371    if (i->vars) {
05372       for (v = i->vars ; v ; v = v->next)
05373          pbx_builtin_setvar_helper(tmp, v->name, v->value);
05374    }
05375    if (i->iaxvars) {
05376       struct ast_datastore *variablestore;
05377       struct ast_variable *var, *prev = NULL;
05378       AST_LIST_HEAD(, ast_var_t) *varlist;
05379       ast_debug(1, "Loading up the channel with IAXVARs\n");
05380       varlist = ast_calloc(1, sizeof(*varlist));
05381       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05382       if (variablestore && varlist) {
05383          variablestore->data = varlist;
05384          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05385          AST_LIST_HEAD_INIT(varlist);
05386          for (var = i->iaxvars; var; var = var->next) {
05387             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05388             if (prev)
05389                ast_free(prev);
05390             prev = var;
05391             if (!newvar) {
05392                /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
05393                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05394             } else {
05395                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05396             }
05397          }
05398          if (prev)
05399             ast_free(prev);
05400          i->iaxvars = NULL;
05401          ast_channel_datastore_add(i->owner, variablestore);
05402       } else {
05403          if (variablestore) {
05404             ast_datastore_free(variablestore);
05405          }
05406          if (varlist) {
05407             ast_free(varlist);
05408          }
05409       }
05410    }
05411 
05412    if (state != AST_STATE_DOWN) {
05413       if (ast_pbx_start(tmp)) {
05414          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05415          ast_hangup(tmp);
05416          i->owner = NULL;
05417          return NULL;
05418       }
05419    }
05420 
05421    ast_module_ref(ast_module_info->self);
05422    return tmp;
05423 }

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

Definition at line 3291 of file chan_iax2.c.

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and network_thread().

03292 {
03293 #ifdef SCHED_MULTITHREADED
03294    if (schedule_action(__attempt_transmit, data))
03295 #endif      
03296       __attempt_transmit(data);
03297    return 0;
03298 }

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

Definition at line 8474 of file chan_iax2.c.

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

Referenced by socket_process().

08475 {
08476    /* Schedule sending the authentication failure in one second, to prevent
08477       guessing */
08478    if (iaxs[callno]) {
08479       iaxs[callno]->authfail = failcode;
08480       if (delayreject) {
08481          iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 
08482             sched, 1000, auth_reject, (void *)(long)callno);
08483       } else
08484          auth_reject((void *)(long)callno);
08485    }
08486    return 0;
08487 }

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

Definition at line 8460 of file chan_iax2.c.

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

Referenced by auth_fail().

08461 {
08462    int callno = (int)(long)(data);
08463    ast_mutex_lock(&iaxsl[callno]);
08464    if (iaxs[callno])
08465       iaxs[callno]->authid = -1;
08466    ast_mutex_unlock(&iaxsl[callno]);
08467 #ifdef SCHED_MULTITHREADED
08468    if (schedule_action(__auth_reject, data))
08469 #endif      
08470       __auth_reject(data);
08471    return 0;
08472 }

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

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

07594 {
07595    int res = -1;
07596    int x;
07597    if (!ast_strlen_zero(keyn)) {
07598       if (!(authmethods & IAX_AUTH_RSA)) {
07599          if (ast_strlen_zero(secret)) 
07600             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));
07601       } else if (ast_strlen_zero(challenge)) {
07602          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
07603       } else {
07604          char sig[256];
07605          struct ast_key *key;
07606          key = ast_key_get(keyn, AST_KEY_PRIVATE);
07607          if (!key) {
07608             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
07609          } else {
07610             if (ast_sign(key, (char*)challenge, sig)) {
07611                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
07612                res = -1;
07613             } else {
07614                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
07615                res = 0;
07616             }
07617          }
07618       }
07619    } 
07620    /* Fall back */
07621    if (res && !ast_strlen_zero(secret)) {
07622       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
07623          struct MD5Context md5;
07624          unsigned char digest[16];
07625          char digres[128];
07626          MD5Init(&md5);
07627          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
07628          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
07629          MD5Final(digest, &md5);
07630          /* If they support md5, authenticate with it.  */
07631          for (x=0;x<16;x++)
07632             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
07633          if (pvt) {
07634             build_encryption_keys(digest, pvt);
07635          }
07636          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
07637          res = 0;
07638       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
07639          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
07640          res = 0;
07641       } else
07642          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
07643    }
07644    return res;
07645 }

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 7651 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_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_var_assign(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, chan_iax2_pvt::callno, iax_ies::challenge, ast_datastore::data, DATASTORE_INHERIT_FOREVER, iax_ies::encmethods, ast_var_t::entries, iax2_variable_datastore_info, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, iaxs, ast_datastore::inheritance, LOG_ERROR, iax2_peer::mask, merge_encryption(), iax2_peer::name, iax2_peer::outkey, peer_unref(), peers, realtime_peer(), iax2_peer::secret, send_command(), iax2_peer::username, iax_ies::username, var, and iax_ies::vars.

Referenced by socket_process().

07652 {
07653    struct iax2_peer *peer = NULL;
07654    /* Start pessimistic */
07655    int res = -1;
07656    int authmethods = 0;
07657    struct iax_ie_data ied;
07658    uint16_t callno = p->callno;
07659 
07660    memset(&ied, 0, sizeof(ied));
07661    
07662    if (ies->username)
07663       ast_string_field_set(p, username, ies->username);
07664    if (ies->challenge)
07665       ast_string_field_set(p, challenge, ies->challenge);
07666    if (ies->authmethods)
07667       authmethods = ies->authmethods;
07668    if (authmethods & IAX_AUTH_MD5)
07669       merge_encryption(p, ies->encmethods);
07670    else
07671       p->encmethods = 0;
07672 
07673    /* Check for override RSA authentication first */
07674    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
07675       /* Normal password authentication */
07676       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
07677    } else {
07678       struct ao2_iterator i = ao2_iterator_init(peers, 0);
07679       while ((peer = ao2_iterator_next(&i))) {
07680          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
07681              /* No peer specified at our end, or this is the peer */
07682              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
07683              /* No username specified in peer rule, or this is the right username */
07684              && (!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)))
07685              /* No specified host, or this is our host */
07686             ) {
07687             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
07688             if (!res) {
07689                peer_unref(peer);
07690                break;
07691             }
07692          }
07693          peer_unref(peer);
07694       }
07695       ao2_iterator_destroy(&i);
07696       if (!peer) {
07697          /* We checked our list and didn't find one.  It's unlikely, but possible, 
07698             that we're trying to authenticate *to* a realtime peer */
07699          const char *peer_name = ast_strdupa(p->peer);
07700          ast_mutex_unlock(&iaxsl[callno]);
07701          if ((peer = realtime_peer(peer_name, NULL))) {
07702             ast_mutex_lock(&iaxsl[callno]);
07703             if (!(p = iaxs[callno])) {
07704                peer_unref(peer);
07705                return -1;
07706             }
07707             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
07708             peer_unref(peer);
07709          }
07710          if (!peer) {
07711             ast_mutex_lock(&iaxsl[callno]);
07712             if (!(p = iaxs[callno]))
07713                return -1;
07714          }
07715       }
07716    }
07717    if (ies->encmethods)
07718       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
07719    if (!res) {
07720       struct ast_datastore *variablestore;
07721       struct ast_variable *var, *prev = NULL;
07722       AST_LIST_HEAD(, ast_var_t) *varlist;
07723       varlist = ast_calloc(1, sizeof(*varlist));
07724       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
07725       if (variablestore && varlist && p->owner) {
07726          variablestore->data = varlist;
07727          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
07728          AST_LIST_HEAD_INIT(varlist);
07729          for (var = ies->vars; var; var = var->next) {
07730             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
07731             if (prev)
07732                ast_free(prev);
07733             prev = var;
07734             if (!newvar) {
07735                /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */
07736                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07737             } else {
07738                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
07739             }
07740          }
07741          if (prev)
07742             ast_free(prev);
07743          ies->vars = NULL;
07744          ast_channel_datastore_add(p->owner, variablestore);
07745       } else {
07746          if (p->owner)
07747             ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07748          if (variablestore)
07749             ast_datastore_free(variablestore);
07750          if (varlist)
07751             ast_free(varlist);
07752       }
07753    }
07754 
07755    if (!res)
07756       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
07757    return res;
07758 }

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

References ao2_find, AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_random(), ast_set_flag, ast_string_field_set, ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::challenge, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, iaxs, OBJ_POINTER, send_command(), send_command_final(), user, user_unref(), chan_iax2_pvt::username, and users.

Referenced by socket_process().

07305 {
07306    struct iax_ie_data ied;
07307    int res = -1, authreq_restrict = 0;
07308    char challenge[10];
07309    struct chan_iax2_pvt *p = iaxs[call_num];
07310 
07311    memset(&ied, 0, sizeof(ied));
07312 
07313    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
07314    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07315       struct iax2_user *user, tmp_user = {
07316          .name = p->username, 
07317       };
07318 
07319       user = ao2_find(users, &tmp_user, OBJ_POINTER);
07320       if (user) {
07321          if (user->curauthreq == user->maxauthreq)
07322             authreq_restrict = 1;
07323          else
07324             user->curauthreq++;
07325          user = user_unref(user);
07326       }
07327    }
07328 
07329    /* If the AUTHREQ limit test failed, send back an error */
07330    if (authreq_restrict) {
07331       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07332       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07333       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07334       return 0;
07335    }
07336 
07337    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07338    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07339       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07340       ast_string_field_set(p, challenge, challenge);
07341       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
07342       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07343    }
07344    if (p->encmethods)
07345       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07346 
07347    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07348 
07349    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07350 
07351    if (p->encmethods)
07352       ast_set_flag(p, IAX_ENCRYPTED);
07353 
07354    return res;
07355 }

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

Definition at line 7357 of file chan_iax2.c.

References ao2_find, ast_atomic_fetchadd_int(), ast_check_signature, ast_clear_flag, ast_copy_string(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::challenge, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, LOG_WARNING, md5(), iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), OBJ_POINTER, iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user, user_unref(), chan_iax2_pvt::username, and users.

Referenced by socket_process().

07358 {
07359    char requeststr[256];
07360    char md5secret[256] = "";
07361    char secret[256] = "";
07362    char rsasecret[256] = "";
07363    int res = -1; 
07364    int x;
07365    struct iax2_user *user, tmp_user = {
07366       .name = p->username, 
07367    };
07368 
07369    if (p->authrej) {
07370       return res;
07371    }
07372    user = ao2_find(users, &tmp_user, OBJ_POINTER);
07373    if (user) {
07374       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07375          ast_atomic_fetchadd_int(&user->curauthreq, -1);
07376          ast_clear_flag(p, IAX_MAXAUTHREQ);
07377       }
07378       ast_string_field_set(p, host, user->name);
07379       user = user_unref(user);
07380    }
07381 
07382    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07383       return res;
07384    if (ies->password)
07385       ast_copy_string(secret, ies->password, sizeof(secret));
07386    if (ies->md5_result)
07387       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07388    if (ies->rsa_result)
07389       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07390    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07391       struct ast_key *key;
07392       char *keyn;
07393       char tmpkey[256];
07394       char *stringp=NULL;
07395       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07396       stringp=tmpkey;
07397       keyn = strsep(&stringp, ":");
07398       while(keyn) {
07399          key = ast_key_get(keyn, AST_KEY_PUBLIC);
07400          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07401             res = 0;
07402             break;
07403          } else if (!key)
07404             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07405          keyn = strsep(&stringp, ":");
07406       }
07407    } else if (p->authmethods & IAX_AUTH_MD5) {
07408       struct MD5Context md5;
07409       unsigned char digest[16];
07410       char *tmppw, *stringp;
07411       
07412       tmppw = ast_strdupa(p->secret);
07413       stringp = tmppw;
07414       while((tmppw = strsep(&stringp, ";"))) {
07415          MD5Init(&md5);
07416          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07417          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07418          MD5Final(digest, &md5);
07419          /* If they support md5, authenticate with it.  */
07420          for (x=0;x<16;x++)
07421             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
07422          if (!strcasecmp(requeststr, md5secret)) {
07423             res = 0;
07424             break;
07425          }
07426       }
07427    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07428       if (!strcmp(secret, p->secret))
07429          res = 0;
07430    }
07431    return res;
07432 }

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

Definition at line 4336 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

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

04337 {
04338 #ifdef SCHED_MULTITHREADED
04339    if (schedule_action(__auto_congest, data))
04340 #endif      
04341       __auto_congest(data);
04342    return 0;
04343 }

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

Definition at line 8504 of file chan_iax2.c.

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

Referenced by iax2_dprequest(), and iax2_provision().

08505 {
08506    int callno = (int)(long)(data);
08507    ast_mutex_lock(&iaxsl[callno]);
08508    if (iaxs[callno]) {
08509       iaxs[callno]->autoid = -1;
08510    }
08511    ast_mutex_unlock(&iaxsl[callno]);
08512 #ifdef SCHED_MULTITHREADED
08513    if (schedule_action(__auto_hangup, data))
08514 #endif      
08515       __auto_hangup(data);
08516    return 0;
08517 }

static void build_callno_limits ( struct ast_variable v  )  [static]

Definition at line 2183 of file chan_iax2.c.

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

Referenced by set_config().

02184 {
02185    struct addr_range *addr_range = NULL;
02186    struct addr_range tmp;
02187    struct ast_ha *ha;
02188    int limit;
02189    int error;
02190    int found;
02191 
02192    for (; v; v = v->next) {
02193       limit = -1;
02194       error = 0;
02195       found = 0;
02196       ha = ast_append_ha("permit", v->name, NULL, &error);
02197 
02198       /* check for valid config information */
02199       if (error) {
02200          ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02201          continue;
02202       } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02203          ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02204          ast_free_ha(ha);
02205          continue;
02206       }
02207 
02208       ast_copy_ha(ha, &tmp.ha);
02209       /* find or create the addr_range */
02210       if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02211          ao2_lock(addr_range);
02212          found = 1;
02213       } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02214          ast_free_ha(ha);
02215          return; /* out of memory */
02216       }
02217 
02218       /* copy over config data into addr_range object */
02219       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
02220       ast_free_ha(ha); /* cleanup the tmp ha */
02221       addr_range->limit = limit;
02222       addr_range->delme = 0;
02223 
02224       /* cleanup */
02225       if (found) {
02226          ao2_unlock(addr_range);
02227       } else {
02228          ao2_link(callno_limits, addr_range);
02229       }
02230       ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02231    }
02232 }

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

Definition at line 11593 of file chan_iax2.c.

References ast_calloc, and ast_copy_string().

Referenced by build_user().

11594 {
11595    struct iax2_context *con;
11596 
11597    if ((con = ast_calloc(1, sizeof(*con))))
11598       ast_copy_string(con->context, context, sizeof(con->context));
11599    
11600    return con;
11601 }

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

Definition at line 5766 of file chan_iax2.c.

References ast_aes_decrypt_key, ast_aes_encrypt_key, build_rand_pad(), chan_iax2_pvt::ecx, chan_iax2_pvt::mydcx, and chan_iax2_pvt::semirand.

Referenced by build_encryption_keys(), and iax2_key_rotate().

05767 {
05768    /* it is required to hold the corresponding decrypt key to our encrypt key
05769     * in the pvt struct because queued frames occasionally need to be decrypted and
05770     * re-encrypted when updated for a retransmission */
05771    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
05772    ast_aes_encrypt_key(digest, &pvt->ecx);
05773    ast_aes_decrypt_key(digest, &pvt->mydcx);
05774 }

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

Definition at line 5760 of file chan_iax2.c.

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

Referenced by authenticate(), and decrypt_frame().

05761 {
05762    build_ecx_key(digest, pvt);
05763    ast_aes_decrypt_key(digest, &pvt->dcx);
05764 }

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

Create peer structure based on configuration.

Definition at line 11741 of file chan_iax2.c.

References ao2_alloc, ao2_find, ast_append_ha(), ast_callerid_split(), ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_false(), ast_free_ha(), ast_get_ip(), ast_log(), ast_parse_allow_disallow(), AST_SCHED_DEL, ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cid_name, cid_num, context, iax2_peer::dbsecret, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, inet_aton(), iax2_peer::inkeys, ast_variable::lineno, LOG_WARNING, mailbox, mwi_event_cb(), ast_variable::name, iax2_peer::name, ast_variable::next, OBJ_POINTER, iax2_peer::outkey, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), iax2_peer::peercontext, peers, prefs, regexten, S_OR, sched, secret, strsep(), timer, unlink_peer(), ast_variable::value, and zonetag.

11742 {
11743    struct iax2_peer *peer = NULL;
11744    struct ast_ha *oldha = NULL;
11745    int maskfound = 0;
11746    int found = 0;
11747    int firstpass = 1;
11748    struct iax2_peer tmp_peer = {
11749       .name = name,
11750    };
11751 
11752    if (!temponly) {
11753       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
11754       if (peer && !ast_test_flag(peer, IAX_DELME))
11755          firstpass = 0;
11756    }
11757 
11758    if (peer) {
11759       found++;
11760       if (firstpass) {
11761          oldha = peer->ha;
11762          peer->ha = NULL;
11763       }
11764       unlink_peer(peer);
11765    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
11766       peer->expire = -1;
11767       peer->pokeexpire = -1;
11768       peer->sockfd = defaultsockfd;
11769       if (ast_string_field_init(peer, 32))
11770          peer = peer_unref(peer);
11771    }
11772 
11773    if (peer) {
11774       if (firstpass) {
11775          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11776          peer->encmethods = iax2_encryption;
11777          peer->adsi = adsi;
11778          ast_string_field_set(peer,secret,"");
11779          if (!found) {
11780             ast_string_field_set(peer, name, name);
11781             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
11782             peer->expiry = min_reg_expire;
11783          }
11784          peer->prefs = prefs;
11785          peer->capability = iax2_capability;
11786          peer->smoothing = 0;
11787          peer->pokefreqok = DEFAULT_FREQ_OK;
11788          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
11789          peer->maxcallno = 0;
11790          peercnt_modify(0, 0, &peer->addr);
11791          peer->calltoken_required = CALLTOKEN_DEFAULT;
11792          ast_string_field_set(peer,context,"");
11793          ast_string_field_set(peer,peercontext,"");
11794          ast_clear_flag(peer, IAX_HASCALLERID);
11795          ast_string_field_set(peer, cid_name, "");
11796          ast_string_field_set(peer, cid_num, "");
11797          ast_string_field_set(peer, mohinterpret, mohinterpret);
11798          ast_string_field_set(peer, mohsuggest, mohsuggest);
11799       }
11800 
11801       if (!v) {
11802          v = alt;
11803          alt = NULL;
11804       }
11805       while(v) {
11806          if (!strcasecmp(v->name, "secret")) {
11807             ast_string_field_set(peer, secret, v->value);
11808          } else if (!strcasecmp(v->name, "mailbox")) {
11809             ast_string_field_set(peer, mailbox, v->value);
11810          } else if (!strcasecmp(v->name, "hasvoicemail")) {
11811             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
11812                ast_string_field_set(peer, mailbox, name);
11813             }
11814          } else if (!strcasecmp(v->name, "mohinterpret")) {
11815             ast_string_field_set(peer, mohinterpret, v->value);
11816          } else if (!strcasecmp(v->name, "mohsuggest")) {
11817             ast_string_field_set(peer, mohsuggest, v->value);
11818          } else if (!strcasecmp(v->name, "dbsecret")) {
11819             ast_string_field_set(peer, dbsecret, v->value);
11820          } else if (!strcasecmp(v->name, "trunk")) {
11821             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
11822             if (ast_test_flag(peer, IAX_TRUNK) && !timer) {
11823                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
11824                ast_clear_flag(peer, IAX_TRUNK);
11825             }
11826          } else if (!strcasecmp(v->name, "auth")) {
11827             peer->authmethods = get_auth_methods(v->value);
11828          } else if (!strcasecmp(v->name, "encryption")) {
11829             peer->encmethods |= get_encrypt_methods(v->value);
11830          } else if (!strcasecmp(v->name, "transfer")) {
11831             if (!strcasecmp(v->value, "mediaonly")) {
11832                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
11833             } else if (ast_true(v->value)) {
11834                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11835             } else 
11836                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11837          } else if (!strcasecmp(v->name, "jitterbuffer")) {
11838             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
11839          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
11840             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
11841          } else if (!strcasecmp(v->name, "host")) {
11842             if (!strcasecmp(v->value, "dynamic")) {
11843                /* They'll register with us */
11844                ast_set_flag(peer, IAX_DYNAMIC); 
11845                if (!found) {
11846                   /* Initialize stuff iff we're not found, otherwise
11847                      we keep going with what we had */
11848                   memset(&peer->addr.sin_addr, 0, 4);
11849                   if (peer->addr.sin_port) {
11850                      /* If we've already got a port, make it the default rather than absolute */
11851                      peer->defaddr.sin_port = peer->addr.sin_port;
11852                      peer->addr.sin_port = 0;
11853                   }
11854                }
11855             } else {
11856                /* Non-dynamic.  Make sure we become that way if we're not */
11857                AST_SCHED_DEL(sched, peer->expire);
11858                ast_clear_flag(peer, IAX_DYNAMIC);
11859                if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
11860                   return peer_unref(peer);
11861                if (!peer->addr.sin_port)
11862                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
11863             }
11864             if (!maskfound)
11865                inet_aton("255.255.255.255", &peer->mask);
11866          } else if (!strcasecmp(v->name, "defaultip")) {
11867             if (ast_get_ip(&peer->defaddr, v->value))
11868                return peer_unref(peer);
11869          } else if (!strcasecmp(v->name, "sourceaddress")) {
11870             peer_set_srcaddr(peer, v->value);
11871          } else if (!strcasecmp(v->name, "permit") ||
11872                   !strcasecmp(v->name, "deny")) {
11873             peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
11874          } else if (!strcasecmp(v->name, "mask")) {
11875             maskfound++;
11876             inet_aton(v->value, &peer->mask);
11877          } else if (!strcasecmp(v->name, "context")) {
11878             ast_string_field_set(peer, context, v->value);
11879          } else if (!strcasecmp(v->name, "regexten")) {
11880             ast_string_field_set(peer, regexten, v->value);
11881          } else if (!strcasecmp(v->name, "peercontext")) {
11882             ast_string_field_set(peer, peercontext, v->value);
11883          } else if (!strcasecmp(v->name, "port")) {
11884             if (ast_test_flag(peer, IAX_DYNAMIC))
11885                peer->defaddr.sin_port = htons(atoi(v->value));
11886             else
11887                peer->addr.sin_port = htons(atoi(v->value));
11888          } else if (!strcasecmp(v->name, "username")) {
11889             ast_string_field_set(peer, username, v->value);
11890          } else if (!strcasecmp(v->name, "allow")) {
11891             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
11892          } else if (!strcasecmp(v->name, "disallow")) {
11893             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
11894          } else if (!strcasecmp(v->name, "callerid")) {
11895             if (!ast_strlen_zero(v->value)) {
11896                char name2[80];
11897                char num2[80];
11898                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
11899                ast_string_field_set(peer, cid_name, name2);
11900                ast_string_field_set(peer, cid_num, num2);
11901             } else {
11902                ast_string_field_set(peer, cid_name, "");
11903                ast_string_field_set(peer, cid_num, "");
11904             }
11905             ast_set_flag(peer, IAX_HASCALLERID);
11906          } else if (!strcasecmp(v->name, "fullname")) {
11907             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
11908             ast_set_flag(peer, IAX_HASCALLERID);
11909          } else if (!strcasecmp(v->name, "cid_number")) {
11910             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
11911             ast_set_flag(peer, IAX_HASCALLERID);
11912          } else if (!strcasecmp(v->name, "sendani")) {
11913             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
11914          } else if (!strcasecmp(v->name, "inkeys")) {
11915             ast_string_field_set(peer, inkeys, v->value);
11916          } else if (!strcasecmp(v->name, "outkey")) {
11917             ast_string_field_set(peer, outkey, v->value);
11918          } else if (!strcasecmp(v->name, "qualify")) {
11919             if (!strcasecmp(v->value, "no")) {
11920                peer->maxms = 0;
11921             } else if (!strcasecmp(v->value, "yes")) {
11922                peer->maxms = DEFAULT_MAXMS;
11923             } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
11924                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);
11925                peer->maxms = 0;
11926             }
11927          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
11928             peer->smoothing = ast_true(v->value);
11929          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
11930             if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
11931                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);
11932             }
11933          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
11934             if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
11935                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);
11936             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
11937          } else if (!strcasecmp(v->name, "timezone")) {
11938             ast_string_field_set(peer, zonetag, v->value);
11939          } else if (!strcasecmp(v->name, "adsi")) {
11940             peer->adsi = ast_true(v->value);
11941          } else if (!strcasecmp(v->name, "maxcallnumbers")) {
11942             if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
11943                ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
11944             } else {
11945                peercnt_modify(1, peer->maxcallno, &peer->addr);
11946             }
11947          } else if (!strcasecmp(v->name, "requirecalltoken")) {
11948             /* default is required unless in optional ip list */
11949             if (ast_false(v->value)) {
11950                peer->calltoken_required = CALLTOKEN_NO;
11951             } else if (!strcasecmp(v->value, "auto")) {
11952                peer->calltoken_required = CALLTOKEN_AUTO;
11953             } else if (ast_true(v->value)) {
11954                peer->calltoken_required = CALLTOKEN_YES;
11955             } else {
11956                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
11957             }
11958          } /* else if (strcasecmp(v->name,"type")) */
11959          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
11960          v = v->next;
11961          if (!v) {
11962             v = alt;
11963             alt = NULL;
11964          }
11965       }
11966       if (!peer->authmethods)
11967          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11968       ast_clear_flag(peer, IAX_DELME); 
11969       /* Make sure these are IPv4 addresses */
11970       peer->addr.sin_family = AF_INET;
11971    }
11972 
11973    if (oldha)
11974       ast_free_ha(oldha);
11975 
11976    if (!ast_strlen_zero(peer->mailbox)) {
11977       char *mailbox, *context;
11978       context = mailbox = ast_strdupa(peer->mailbox);
11979       strsep(&context, "@");
11980       if (ast_strlen_zero(context))
11981          context = "default";
11982       peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
11983          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
11984          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
11985          AST_EVENT_IE_END);
11986    }
11987 
11988    return peer;
11989 }

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

Definition at line 5750 of file chan_iax2.c.

References ast_random().

Referenced by build_ecx_key(), and update_packet().

05751 {
05752    long tmp;
05753    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
05754       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
05755       buf += sizeof(tmp);
05756       len -= sizeof(tmp);
05757    }
05758 }

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

Create in-memory user structure from configuration.

Definition at line 12005 of file chan_iax2.c.

References ao2_alloc, ao2_find, ao2_unlink, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_false(), ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cid_name, cid_num, cleanup(), iax2_user::dbsecret, format, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, ast_variable::lineno, LOG_WARNING, ast_variable::name, iax2_user::name, ast_variable::next, OBJ_POINTER, parkinglot, prefs, secret, timer, user, user_destructor(), user_unref(), users, and ast_variable::value.

12006 {
12007    struct iax2_user *user = NULL;
12008    struct iax2_context *con, *conl = NULL;
12009    struct ast_ha *oldha = NULL;
12010    struct iax2_context *oldcon = NULL;
12011    int format;
12012    int firstpass=1;
12013    int oldcurauthreq = 0;
12014    char *varname = NULL, *varval = NULL;
12015    struct ast_variable *tmpvar = NULL;
12016    struct iax2_user tmp_user = {
12017       .name = name,
12018    };
12019 
12020    if (!temponly) {
12021       user = ao2_find(users, &tmp_user, OBJ_POINTER);
12022       if (user && !ast_test_flag(user, IAX_DELME))
12023          firstpass = 0;
12024    }
12025 
12026    if (user) {
12027       if (firstpass) {
12028          oldcurauthreq = user->curauthreq;
12029          oldha = user->ha;
12030          oldcon = user->contexts;
12031          user->ha = NULL;
12032          user->contexts = NULL;
12033       }
12034       /* Already in the list, remove it and it will be added back (or FREE'd) */
12035       ao2_unlink(users, user);
12036    } else {
12037       user = ao2_alloc(sizeof(*user), user_destructor);
12038    }
12039    
12040    if (user) {
12041       if (firstpass) {
12042          ast_string_field_free_memory(user);
12043          memset(user, 0, sizeof(struct iax2_user));
12044          if (ast_string_field_init(user, 32)) {
12045             user = user_unref(user);
12046             goto cleanup;
12047          }
12048          user->maxauthreq = maxauthreq;
12049          user->curauthreq = oldcurauthreq;
12050          user->prefs = prefs;
12051          user->capability = iax2_capability;
12052          user->encmethods = iax2_encryption;
12053          user->adsi = adsi;
12054          user->calltoken_required = CALLTOKEN_DEFAULT;
12055          ast_string_field_set(user, name, name);
12056          ast_string_field_set(user, language, language);
12057          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
12058          ast_clear_flag(user, IAX_HASCALLERID);
12059          ast_string_field_set(user, cid_name, "");
12060          ast_string_field_set(user, cid_num, "");
12061          ast_string_field_set(user, accountcode, accountcode);
12062          ast_string_field_set(user, mohinterpret, mohinterpret);
12063          ast_string_field_set(user, mohsuggest, mohsuggest);
12064       }
12065       if (!v) {
12066          v = alt;
12067          alt = NULL;
12068       }
12069       while(v) {
12070          if (!strcasecmp(v->name, "context")) {
12071             con = build_context(v->value);
12072             if (con) {
12073                if (conl)
12074                   conl->next = con;
12075                else
12076                   user->contexts = con;
12077                conl = con;
12078             }
12079          } else if (!strcasecmp(v->name, "permit") ||
12080                   !strcasecmp(v->name, "deny")) {
12081             user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12082          } else if (!strcasecmp(v->name, "setvar")) {
12083             varname = ast_strdupa(v->value);
12084             if (varname && (varval = strchr(varname,'='))) {
12085                *varval = '\0';
12086                varval++;
12087                if((tmpvar = ast_variable_new(varname, varval, ""))) {
12088                   tmpvar->next = user->vars; 
12089                   user->vars = tmpvar;
12090                }
12091             }
12092          } else if (!strcasecmp(v->name, "allow")) {
12093             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12094          } else if (!strcasecmp(v->name, "disallow")) {
12095             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12096          } else if (!strcasecmp(v->name, "trunk")) {
12097             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
12098             if (ast_test_flag(user, IAX_TRUNK) && !timer) {
12099                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12100                ast_clear_flag(user, IAX_TRUNK);
12101             }
12102          } else if (!strcasecmp(v->name, "auth")) {
12103             user->authmethods = get_auth_methods(v->value);
12104          } else if (!strcasecmp(v->name, "encryption")) {
12105             user->encmethods |= get_encrypt_methods(v->value);
12106          } else if (!strcasecmp(v->name, "transfer")) {
12107             if (!strcasecmp(v->value, "mediaonly")) {
12108                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
12109             } else if (ast_true(v->value)) {
12110                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12111             } else 
12112                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12113          } else if (!strcasecmp(v->name, "codecpriority")) {
12114             if(!strcasecmp(v->value, "caller"))
12115                ast_set_flag(user, IAX_CODEC_USER_FIRST);
12116             else if(!strcasecmp(v->value, "disabled"))
12117                ast_set_flag(user, IAX_CODEC_NOPREFS);
12118             else if(!strcasecmp(v->value, "reqonly")) {
12119                ast_set_flag(user, IAX_CODEC_NOCAP);
12120                ast_set_flag(user, IAX_CODEC_NOPREFS);
12121             }
12122          } else if (!strcasecmp(v->name, "jitterbuffer")) {
12123             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
12124          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12125             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12126          } else if (!strcasecmp(v->name, "dbsecret")) {
12127             ast_string_field_set(user, dbsecret, v->value);
12128          } else if (!strcasecmp(v->name, "secret")) {
12129             if (!ast_strlen_zero(user->secret)) {
12130                char *old = ast_strdupa(user->secret);
12131 
12132                ast_string_field_build(user, secret, "%s;%s", old, v->value);
12133             } else
12134                ast_string_field_set(user, secret, v->value);
12135          } else if (!strcasecmp(v->name, "callerid")) {
12136             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12137                char name2[80];
12138                char num2[80];
12139                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12140                ast_string_field_set(user, cid_name, name2);
12141                ast_string_field_set(user, cid_num, num2);
12142                ast_set_flag(user, IAX_HASCALLERID);
12143             } else {
12144                ast_clear_flag(user, IAX_HASCALLERID);
12145                ast_string_field_set(user, cid_name, "");
12146                ast_string_field_set(user, cid_num, "");
12147             }
12148          } else if (!strcasecmp(v->name, "fullname")) {
12149             if (!ast_strlen_zero(v->value)) {
12150                ast_string_field_set(user, cid_name, v->value);
12151                ast_set_flag(user, IAX_HASCALLERID);
12152             } else {
12153                ast_string_field_set(user, cid_name, "");
12154                if (ast_strlen_zero(user->cid_num))
12155                   ast_clear_flag(user, IAX_HASCALLERID);
12156             }
12157          } else if (!strcasecmp(v->name, "cid_number")) {
12158             if (!ast_strlen_zero(v->value)) {
12159                ast_string_field_set(user, cid_num, v->value);
12160                ast_set_flag(user, IAX_HASCALLERID);
12161             } else {
12162                ast_string_field_set(user, cid_num, "");
12163                if (ast_strlen_zero(user->cid_name))
12164                   ast_clear_flag(user, IAX_HASCALLERID);
12165             }
12166          } else if (!strcasecmp(v->name, "accountcode")) {
12167             ast_string_field_set(user, accountcode, v->value);
12168          } else if (!strcasecmp(v->name, "mohinterpret")) {
12169             ast_string_field_set(user, mohinterpret, v->value);
12170          } else if (!strcasecmp(v->name, "mohsuggest")) {
12171             ast_string_field_set(user, mohsuggest, v->value);
12172          } else if (!strcasecmp(v->name, "parkinglot")) {
12173             ast_string_field_set(user, parkinglot, v->value);
12174          } else if (!strcasecmp(v->name, "language")) {
12175             ast_string_field_set(user, language, v->value);
12176          } else if (!strcasecmp(v->name, "amaflags")) {
12177             format = ast_cdr_amaflags2int(v->value);
12178             if (format < 0) {
12179                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12180             } else {
12181                user->amaflags = format;
12182             }
12183          } else if (!strcasecmp(v->name, "inkeys")) {
12184             ast_string_field_set(user, inkeys, v->value);
12185          } else if (!strcasecmp(v->name, "maxauthreq")) {
12186             user->maxauthreq = atoi(v->value);
12187             if (user->maxauthreq < 0)
12188                user->maxauthreq = 0;
12189          } else if (!strcasecmp(v->name, "adsi")) {
12190             user->adsi = ast_true(v->value);
12191          } else if (!strcasecmp(v->name, "requirecalltoken")) {
12192             /* default is required unless in optional ip list */
12193             if (ast_false(v->value)) {
12194                user->calltoken_required = CALLTOKEN_NO;
12195             } else if (!strcasecmp(v->value, "auto")) {
12196                user->calltoken_required = CALLTOKEN_AUTO;
12197             } else if (ast_true(v->value)) {
12198                user->calltoken_required = CALLTOKEN_YES;
12199             } else {
12200                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12201             }
12202          } /* else if (strcasecmp(v->name,"type")) */
12203          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
12204          v = v->next;
12205          if (!v) {
12206             v = alt;
12207             alt = NULL;
12208          }
12209       }
12210       if (!user->authmethods) {
12211          if (!ast_strlen_zero(user->secret)) {
12212             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12213             if (!ast_strlen_zero(user->inkeys))
12214                user->authmethods |= IAX_AUTH_RSA;
12215          } else if (!ast_strlen_zero(user->inkeys)) {
12216             user->authmethods = IAX_AUTH_RSA;
12217          } else {
12218             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12219          }
12220       }
12221       ast_clear_flag(user, IAX_DELME);
12222    }
12223 cleanup:
12224    if (oldha)
12225       ast_free_ha(oldha);
12226    if (oldcon)
12227       free_context(oldcon);
12228    return user;
12229 }

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

Definition at line 12813 of file chan_iax2.c.

References add_empty_calltoken_ie(), ARRAY_LEN, ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), chan_iax2_pvt::capability, create_addr(), find_callno_locked(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, iaxs, LOG_WARNING, NEW_FORCE, parse_dial_string(), secret, and send_command().

Referenced by find_cache().

12814 {
12815    struct sockaddr_in sin;
12816    int x;
12817    int callno;
12818    struct iax_ie_data ied;
12819    struct create_addr_info cai;
12820    struct parsed_dial_string pds;
12821    char *tmpstr;
12822 
12823    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
12824       /* Look for an *exact match* call.  Once a call is negotiated, it can only
12825          look up entries for a single context */
12826       if (!ast_mutex_trylock(&iaxsl[x])) {
12827          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
12828             return x;
12829          ast_mutex_unlock(&iaxsl[x]);
12830       }
12831    }
12832 
12833    /* No match found, we need to create a new one */
12834 
12835    memset(&cai, 0, sizeof(cai));
12836    memset(&ied, 0, sizeof(ied));
12837    memset(&pds, 0, sizeof(pds));
12838 
12839    tmpstr = ast_strdupa(data);
12840    parse_dial_string(tmpstr, &pds);
12841 
12842    if (ast_strlen_zero(pds.peer)) {
12843       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
12844       return -1;
12845    }
12846 
12847    /* Populate our address from the given */
12848    if (create_addr(pds.peer, NULL, &sin, &cai))
12849       return -1;
12850 
12851    ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
12852       pds.peer, pds.username, pds.password, pds.context);
12853 
12854    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12855    if (callno < 1) {
12856       ast_log(LOG_WARNING, "Unable to create call\n");
12857       return -1;
12858    }
12859 
12860    ast_string_field_set(iaxs[callno], dproot, data);
12861    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
12862 
12863    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
12864    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
12865    /* the string format is slightly different from a standard dial string,
12866       because the context appears in the 'exten' position
12867    */
12868    if (pds.exten)
12869       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
12870    if (pds.username)
12871       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
12872    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
12873    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
12874    /* Keep password handy */
12875    if (pds.password)
12876       ast_string_field_set(iaxs[callno], secret, pds.password);
12877    if (pds.key)
12878       ast_string_field_set(iaxs[callno], outkey, pds.key);
12879    /* Start the call going */
12880    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
12881    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
12882 
12883    return callno;
12884 }

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

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

05603 {
05604    /* Returns where in "receive time" we are.  That is, how many ms
05605       since we received (or would have received) the frame with timestamp 0 */
05606    int ms;
05607 #ifdef IAXTESTS
05608    int jit;
05609 #endif /* IAXTESTS */
05610    /* Setup rxcore if necessary */
05611    if (ast_tvzero(p->rxcore)) {
05612       p->rxcore = ast_tvnow();
05613       if (iaxdebug)
05614          ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
05615                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
05616       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
05617 #if 1
05618       if (iaxdebug)
05619          ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
05620                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
05621 #endif
05622    }
05623 
05624    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
05625 #ifdef IAXTESTS
05626    if (test_jit) {
05627       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
05628          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
05629          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
05630             jit = -jit;
05631          ms += jit;
05632       }
05633    }
05634    if (test_late) {
05635       ms += test_late;
05636       test_late = 0;
05637    }
05638 #endif /* IAXTESTS */
05639    return ms;
05640 }

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

Definition at line 5469 of file chan_iax2.c.

References ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_samp2tv(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, f, iaxs, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, and chan_iax2_pvt::offset.

Referenced by iax2_send(), and socket_process().

05470 {
05471    int ms;
05472    int voice = 0;
05473    int genuine = 0;
05474    int adjust;
05475    int rate = ast_format_rate(f->subclass) / 1000;
05476    struct timeval *delivery = NULL;
05477 
05478 
05479    /* What sort of frame do we have?: voice is self-explanatory
05480       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
05481       non-genuine frames are CONTROL frames [ringing etc], DTMF
05482       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
05483       the others need a timestamp slaved to the voice frames so that they go in sequence
05484    */
05485    if (f) {
05486       if (f->frametype == AST_FRAME_VOICE) {
05487          voice = 1;
05488          delivery = &f->delivery;
05489       } else if (f->frametype == AST_FRAME_IAX) {
05490          genuine = 1;
05491       } else if (f->frametype == AST_FRAME_CNG) {
05492          p->notsilenttx = 0;  
05493       }
05494    }
05495    if (ast_tvzero(p->offset)) {
05496       p->offset = ast_tvnow();
05497       /* Round to nearest 20ms for nice looking traces */
05498       p->offset.tv_usec -= p->offset.tv_usec % 20000;
05499    }
05500    /* If the timestamp is specified, just send it as is */
05501    if (ts)
05502       return ts;
05503    /* If we have a time that the frame arrived, always use it to make our timestamp */
05504    if (delivery && !ast_tvzero(*delivery)) {
05505       ms = ast_tvdiff_ms(*delivery, p->offset);
05506       if (ms < 0) {
05507          ms = 0;
05508       }
05509       if (iaxdebug)
05510          ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05511    } else {
05512       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05513       if (ms < 0)
05514          ms = 0;
05515       if (voice) {
05516          /* On a voice frame, use predicted values if appropriate */
05517          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05518             /* Adjust our txcore, keeping voice and non-voice synchronized */
05519             /* AN EXPLANATION:
05520                When we send voice, we usually send "calculated" timestamps worked out
05521                on the basis of the number of samples sent. When we send other frames,
05522                we usually send timestamps worked out from the real clock.
05523                The problem is that they can tend to drift out of step because the 
05524                   source channel's clock and our clock may not be exactly at the same rate.
05525                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
05526                for this call.  Moving it adjusts timestamps for non-voice frames.
05527                We make the adjustment in the style of a moving average.  Each time we
05528                adjust p->offset by 10% of the difference between our clock-derived
05529                timestamp and the predicted timestamp.  That's why you see "10000"
05530                below even though IAX2 timestamps are in milliseconds.
05531                The use of a moving average avoids offset moving too radically.
05532                Generally, "adjust" roams back and forth around 0, with offset hardly
05533                changing at all.  But if a consistent different starts to develop it
05534                will be eliminated over the course of 10 frames (200-300msecs) 
05535             */
05536             adjust = (ms - p->nextpred);
05537             if (adjust < 0)
05538                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05539             else if (adjust > 0)
05540                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05541 
05542             if (!p->nextpred) {
05543                p->nextpred = ms; /*f->samples / rate;*/
05544                if (p->nextpred <= p->lastsent)
05545                   p->nextpred = p->lastsent + 3;
05546             }
05547             ms = p->nextpred;
05548          } else {
05549                 /* in this case, just use the actual
05550             * time, since we're either way off
05551             * (shouldn't happen), or we're  ending a
05552             * silent period -- and seed the next
05553             * predicted time.  Also, round ms to the
05554             * next multiple of frame size (so our
05555             * silent periods are multiples of
05556             * frame size too) */
05557 
05558             if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05559                ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05560                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05561 
05562             if (f->samples >= rate) /* check to make sure we dont core dump */
05563             {
05564                int diff = ms % (f->samples / rate);
05565                if (diff)
05566                    ms += f->samples/rate - diff;
05567             }
05568 
05569             p->nextpred = ms;
05570             p->notsilenttx = 1;
05571          }
05572       } else if ( f->frametype == AST_FRAME_VIDEO ) {
05573          /*
05574          * IAX2 draft 03 says that timestamps MUST be in order.
05575          * It does not say anything about several frames having the same timestamp
05576          * When transporting video, we can have a frame that spans multiple iax packets
05577          * (so called slices), so it would make sense to use the same timestamp for all of
05578          * them
05579          * We do want to make sure that frames don't go backwards though
05580          */
05581          if ( (unsigned int)ms < p->lastsent )
05582             ms = p->lastsent;
05583       } else {
05584          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
05585             it's a genuine frame */
05586          if (genuine) {
05587             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
05588             if (ms <= p->lastsent)
05589                ms = p->lastsent + 3;
05590          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05591             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
05592             ms = p->lastsent + 3;
05593          }
05594       }
05595    }
05596    p->lastsent = ms;
05597    if (voice)
05598       p->nextpred = p->nextpred + f->samples / rate;
05599    return ms;
05600 }

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

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

05426 {
05427    unsigned long int mssincetx; /* unsigned to handle overflows */
05428    long int ms, pred;
05429 
05430    tpeer->trunkact = *now;
05431    mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05432    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05433       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
05434       tpeer->txtrunktime = *now;
05435       tpeer->lastsent = 999999;
05436    }
05437    /* Update last transmit time now */
05438    tpeer->lasttxtime = *now;
05439    
05440    /* Calculate ms offset */
05441    ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05442    /* Predict from last value */
05443    pred = tpeer->lastsent + sampms;
05444    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05445       ms = pred;
05446    
05447    /* We never send the same timestamp twice, so fudge a little if we must */
05448    if (ms == tpeer->lastsent)
05449       ms = tpeer->lastsent + 1;
05450    tpeer->lastsent = ms;
05451    return ms;
05452 }

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

Definition at line 2388 of file chan_iax2.c.

References ast_random().

Referenced by create_callno_pools().

02389 {
02390    return abs(ast_random());
02391 }

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

Definition at line 1936 of file chan_iax2.c.

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

Referenced by handle_call_token().

01937 {
01938    struct addr_range *addr_range;
01939    struct iax2_peer *peer = NULL;
01940    struct iax2_user *user = NULL;
01941    /* if no username is given, check for guest accounts */
01942    const char *find = S_OR(name, "guest");
01943    int res = 1;  /* required by default */
01944    int optional = 0;
01945    enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
01946    /* There are only two cases in which calltoken validation is not required.
01947     * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
01948     *         the peer definition has not set the requirecalltoken option.
01949     * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
01950     */
01951 
01952    /* ----- Case 1 ----- */
01953    if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
01954       ao2_ref(addr_range, -1);
01955       optional = 1;
01956    }
01957 
01958    /* ----- Case 2 ----- */
01959    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
01960       calltoken_required = user->calltoken_required;
01961    } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
01962       calltoken_required = user->calltoken_required;
01963    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
01964       calltoken_required = peer->calltoken_required;
01965    } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
01966       calltoken_required = peer->calltoken_required;
01967    }
01968 
01969    if (peer) {
01970       peer_unref(peer);
01971    }
01972    if (user) {
01973       user_unref(user);
01974    }
01975 
01976    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);
01977    if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
01978       (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
01979       res = 0;
01980    }
01981 
01982    return res;
01983 }

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

Definition at line 7037 of file chan_iax2.c.

References chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variable_new(), chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, chan_iax2_pvt::capability, iax_ies::capability, cid_name, cid_num, iax_ies::codec_prefs, chan_iax2_pvt::context, context, DEFAULT_CONTEXT, iax_ies::dnid, chan_iax2_pvt::encmethods, exten, ast_variable::file, iax_ies::format, globalflags, iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iax_ies::language, LOG_WARNING, ast_variable::name, ast_variable::next, parkinglot, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, chan_iax2_pvt::prefs, prefs, iax_ies::rdnis, realtime_user(), secret, user, user_unref(), iax_ies::username, users, ast_variable::value, chan_iax2_pvt::vars, iax_ies::version, and version.

Referenced by socket_process().

07038 {
07039    /* Start pessimistic */
07040    int res = -1;
07041    int version = 2;
07042    struct iax2_user *user = NULL, *best = NULL;
07043    int bestscore = 0;
07044    int gotcapability = 0;
07045    struct ast_variable *v = NULL, *tmpvar = NULL;
07046    struct ao2_iterator i;
07047 
07048    if (!iaxs[callno])
07049       return res;
07050    if (ies->called_number)
07051       ast_string_field_set(iaxs[callno], exten, ies->called_number);
07052    if (ies->calling_number) {
07053       if (ast_test_flag(&globalflags, IAX_SHRINKCALLERID)) { 
07054          ast_shrink_phone_number(ies->calling_number);
07055       }
07056       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07057    }
07058    if (ies->calling_name)
07059       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07060    if (ies->calling_ani)
07061       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07062    if (ies->dnid)
07063       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07064    if (ies->rdnis)
07065       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07066    if (ies->called_context)
07067       ast_string_field_set(iaxs[callno], context, ies->called_context);
07068    if (ies->language)
07069       ast_string_field_set(iaxs[callno], language, ies->language);
07070    if (ies->username)
07071       ast_string_field_set(iaxs[callno], username, ies->username);
07072    if (ies->calling_ton > -1)
07073       iaxs[callno]->calling_ton = ies->calling_ton;
07074    if (ies->calling_tns > -1)
07075       iaxs[callno]->calling_tns = ies->calling_tns;
07076    if (ies->calling_pres > -1)
07077       iaxs[callno]->calling_pres = ies->calling_pres;
07078    if (ies->format)
07079       iaxs[callno]->peerformat = ies->format;
07080    if (ies->adsicpe)
07081       iaxs[callno]->peeradsicpe = ies->adsicpe;
07082    if (ies->capability) {
07083       gotcapability = 1;
07084       iaxs[callno]->peercapability = ies->capability;
07085    } 
07086    if (ies->version)
07087       version = ies->version;
07088 
07089    /* Use provided preferences until told otherwise for actual preferences */
07090    if(ies->codec_prefs) {
07091       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07092       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07093    }
07094 
07095    if (!gotcapability) 
07096       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07097    if (version > IAX_PROTO_VERSION) {
07098       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
07099          ast_inet_ntoa(sin->sin_addr), version);
07100       return res;
07101    }
07102    /* Search the userlist for a compatible entry, and fill in the rest */
07103    i = ao2_iterator_init(users, 0);
07104    while ((user = ao2_iterator_next(&i))) {
07105       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
07106          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
07107          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
07108          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
07109               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
07110          if (!ast_strlen_zero(iaxs[callno]->username)) {
07111             /* Exact match, stop right now. */
07112             if (best)
07113                user_unref(best);
07114             best = user;
07115             break;
07116          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07117             /* No required authentication */
07118             if (user->ha) {
07119                /* There was host authentication and we passed, bonus! */
07120                if (bestscore < 4) {
07121                   bestscore = 4;
07122                   if (best)
07123                      user_unref(best);
07124                   best = user;
07125                   continue;
07126                }
07127             } else {
07128                /* No host access, but no secret, either, not bad */
07129                if (bestscore < 3) {
07130                   bestscore = 3;
07131                   if (best)
07132                      user_unref(best);
07133                   best = user;
07134                   continue;
07135                }
07136             }
07137          } else {
07138             if (user->ha) {
07139                /* Authentication, but host access too, eh, it's something.. */
07140                if (bestscore < 2) {
07141                   bestscore = 2;
07142                   if (best)
07143                      user_unref(best);
07144                   best = user;
07145                   continue;
07146                }
07147             } else {
07148                /* Authentication and no host access...  This is our baseline */
07149                if (bestscore < 1) {
07150                   bestscore = 1;
07151                   if (best)
07152                      user_unref(best);
07153                   best = user;
07154                   continue;
07155                }
07156             }
07157          }
07158       }
07159       user_unref(user);
07160    }
07161    ao2_iterator_destroy(&i);
07162    user = best;
07163    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07164       user = realtime_user(iaxs[callno]->username, sin);
07165       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
07166           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
07167          user = user_unref(user);
07168       }
07169    }
07170    if (user) {
07171       /* We found our match (use the first) */
07172       /* copy vars */
07173       for (v = user->vars ; v ; v = v->next) {
07174          if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07175             tmpvar->next = iaxs[callno]->vars; 
07176             iaxs[callno]->vars = tmpvar;
07177          }
07178       }
07179       /* If a max AUTHREQ restriction is in place, activate it */
07180       if (user->maxauthreq > 0)
07181          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
07182       iaxs[callno]->prefs = user->prefs;
07183       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
07184       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
07185       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
07186       iaxs[callno]->encmethods = user->encmethods;
07187       /* Store the requested username if not specified */
07188       if (ast_strlen_zero(iaxs[callno]->username))
07189          ast_string_field_set(iaxs[callno], username, user->name);
07190       /* Store whether this is a trunked call, too, of course, and move if appropriate */
07191       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
07192       iaxs[callno]->capability = user->capability;
07193       /* And use the default context */
07194       if (ast_strlen_zero(iaxs[callno]->context)) {
07195          if (user->contexts)
07196             ast_string_field_set(iaxs[callno], context, user->contexts->context);
07197          else
07198             ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07199       }
07200       /* And any input keys */
07201       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07202       /* And the permitted authentication methods */
07203       iaxs[callno]->authmethods = user->authmethods;
07204       iaxs[callno]->adsi = user->adsi;
07205       /* If the user has callerid, override the remote caller id. */
07206       if (ast_test_flag(user, IAX_HASCALLERID)) {
07207          iaxs[callno]->calling_tns = 0;
07208          iaxs[callno]->calling_ton = 0;
07209          ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07210          ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07211          ast_string_field_set(iaxs[callno], ani, user->cid_num);
07212          iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07213       } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07214          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07215       } /* else user is allowed to set their own CID settings */
07216       if (!ast_strlen_zero(user->accountcode))
07217          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07218       if (!ast_strlen_zero(user->mohinterpret))
07219          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07220       if (!ast_strlen_zero(user->mohsuggest))
07221          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07222       if (!ast_strlen_zero(user->parkinglot))
07223          ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07224       if (user->amaflags)
07225          iaxs[callno]->amaflags = user->amaflags;
07226       if (!ast_strlen_zero(user->language))
07227          ast_string_field_set(iaxs[callno], language, user->language);
07228       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
07229       /* Keep this check last */
07230       if (!ast_strlen_zero(user->dbsecret)) {
07231          char *family, *key=NULL;
07232          char buf[80];
07233          family = ast_strdupa(user->dbsecret);
07234          key = strchr(family, '/');
07235          if (key) {
07236             *key = '\0';
07237             key++;
07238          }
07239          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07240             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07241          else
07242             ast_string_field_set(iaxs[callno], secret, buf);
07243       } else
07244          ast_string_field_set(iaxs[callno], secret, user->secret);
07245       res = 0;
07246       user = user_unref(user);
07247    } else {
07248        /* user was not found, but we should still fake an AUTHREQ.
07249         * Set authmethods to the last known authmethod used by the system
07250         * Set a fake secret, it's not looked at, just required to attempt authentication.
07251         * Set authrej so the AUTHREP is rejected without even looking at its contents */
07252       iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07253       ast_string_field_set(iaxs[callno], secret, "badsecret");
07254       iaxs[callno]->authrej = 1;
07255       if (!ast_strlen_zero(iaxs[callno]->username)) {
07256          /* only send the AUTHREQ if a username was specified. */
07257          res = 0;
07258       }
07259    }
07260    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
07261    return res;
07262 }

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

Definition at line 8828 of file chan_iax2.c.

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

Referenced by socket_process().

08829 {
08830    unsigned int ourver;
08831    char rsi[80];
08832    snprintf(rsi, sizeof(rsi), "si-%s", si);
08833    if (iax_provision_version(&ourver, rsi, 1))
08834       return 0;
08835    ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
08836    if (ourver != ver) 
08837       iax2_provision(sin, sockfd, NULL, rsi, 1);
08838    return 0;
08839 }

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

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

Referenced by peer_set_srcaddr().

11620 {
11621    int sd;
11622    int res;
11623    
11624    sd = socket(AF_INET, SOCK_DGRAM, 0);
11625    if (sd < 0) {
11626       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
11627       return -1;
11628    }
11629 
11630    res = bind(sd, sa, salen);
11631    if (res < 0) {
11632       ast_debug(1, "Can't bind: %s\n", strerror(errno));
11633       close(sd);
11634       return 1;
11635    }
11636 
11637    close(sd);
11638    return 0;
11639 }

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

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

07814 {
07815    char exten[256] = "";
07816    int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
07817    struct iax2_dpcache *dp = NULL;
07818    
07819    if (ies->called_number)
07820       ast_copy_string(exten, ies->called_number, sizeof(exten));
07821    
07822    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
07823       status = CACHE_FLAG_EXISTS;
07824    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
07825       status = CACHE_FLAG_CANEXIST;
07826    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
07827       status = CACHE_FLAG_NONEXISTENT;
07828 
07829    if (ies->refresh)
07830       expiry = ies->refresh;
07831    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
07832       matchmore = CACHE_FLAG_MATCHMORE;
07833    
07834    AST_LIST_LOCK(&dpcache);
07835    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
07836       if (strcmp(dp->exten, exten))
07837          continue;
07838       AST_LIST_REMOVE_CURRENT(peer_list);
07839       dp->callno = 0;
07840       dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
07841       if (dp->flags & CACHE_FLAG_PENDING) {
07842          dp->flags &= ~CACHE_FLAG_PENDING;
07843          dp->flags |= status;
07844          dp->flags |= matchmore;
07845       }
07846       /* Wake up waiters */
07847       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
07848          if (dp->waiters[x] > -1) {
07849             if (write(dp->waiters[x], "asdf", 4) < 0) {
07850             }
07851          }
07852       }
07853    }
07854    AST_LIST_TRAVERSE_SAFE_END;
07855    AST_LIST_UNLOCK(&dpcache);
07856 
07857    return 0;
07858 }

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

Definition at line 3545 of file chan_iax2.c.

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

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

03546 {
03547    int which = 0;
03548    struct iax2_peer *peer;
03549    char *res = NULL;
03550    int wordlen = strlen(word);
03551    struct ao2_iterator i;
03552 
03553    i = ao2_iterator_init(peers, 0);
03554    while ((peer = ao2_iterator_next(&i))) {
03555       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
03556          res = ast_strdup(peer->name);
03557          peer_unref(peer);
03558          break;
03559       }
03560       peer_unref(peer);
03561    }
03562    ao2_iterator_destroy(&i);
03563 
03564    return res;
03565 }

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

Definition at line 6458 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_unregister().

06459 {
06460    int which = 0;
06461    struct iax2_peer *p = NULL;
06462    char *res = NULL;
06463    int wordlen = strlen(word);
06464 
06465    /* 0 - iax2; 1 - unregister; 2 - <peername> */
06466    if (pos == 2) {
06467       struct ao2_iterator i = ao2_iterator_init(peers, 0);
06468       while ((p = ao2_iterator_next(&i))) {
06469          if (!strncasecmp(p->name, word, wordlen) && 
06470             ++which > state && p->expire > 0) {
06471             res = ast_strdup(p->name);
06472             peer_unref(p);
06473             break;
06474          }
06475          peer_unref(p);
06476       }
06477       ao2_iterator_destroy(&i);
06478    }
06479 
06480    return res;
06481 }

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

Definition at line 7860 of file chan_iax2.c.

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

Referenced by socket_process().

07861 {
07862    int peercallno = 0;
07863    struct chan_iax2_pvt *pvt = iaxs[callno];
07864    struct iax_frame *cur;
07865    jb_frame frame;
07866 
07867    if (ies->callno)
07868       peercallno = ies->callno;
07869 
07870    if (peercallno < 1) {
07871       ast_log(LOG_WARNING, "Invalid transfer request\n");
07872       return -1;
07873    }
07874    remove_by_transfercallno(pvt);
07875    /* since a transfer has taken place, the address will change.
07876     * This must be accounted for in the peercnts table.  Remove
07877     * the old address and add the new one */
07878    peercnt_remove_by_addr(&pvt->addr);
07879    peercnt_add(&pvt->transfer);
07880    /* now copy over the new address */
07881    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
07882    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
07883    /* Reset sequence numbers */
07884    pvt->oseqno = 0;
07885    pvt->rseqno = 0;
07886    pvt->iseqno = 0;
07887    pvt->aseqno = 0;
07888 
07889    if (pvt->peercallno) {
07890       remove_by_peercallno(pvt);
07891    }
07892    pvt->peercallno = peercallno;
07893    /*this is where the transfering call swiches hash tables */
07894    store_by_peercallno(pvt);
07895    pvt->transferring = TRANSFER_NONE;
07896    pvt->svoiceformat = -1;
07897    pvt->voiceformat = 0;
07898    pvt->svideoformat = -1;
07899    pvt->videoformat = 0;
07900    pvt->transfercallno = 0;
07901    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
07902    memset(&pvt->offset, 0, sizeof(pvt->offset));
07903    /* reset jitterbuffer */
07904    while(jb_getall(pvt->jb,&frame) == JB_OK)
07905       iax2_frame_free(frame.data);
07906    jb_reset(pvt->jb);
07907    pvt->lag = 0;
07908    pvt->last = 0;
07909    pvt->lastsent = 0;
07910    pvt->nextpred = 0;
07911    pvt->pingtime = DEFAULT_RETRY_TIME;
07912    AST_LIST_LOCK(&frame_queue);
07913    AST_LIST_TRAVERSE(&frame_queue, cur, list) {
07914       /* We must cancel any packets that would have been transmitted
07915          because now we're talking to someone new.  It's okay, they
07916          were transmitted to someone that didn't care anyway. */
07917       if (callno == cur->callno) 
07918          cur->retries = -1;
07919    }
07920    AST_LIST_UNLOCK(&frame_queue);
07921    return 0; 
07922 }

static unsigned char compress_subclass ( int  subclass  )  [static]

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

01370 {
01371    int x;
01372    int power=-1;
01373    /* If it's 128 or smaller, just return it */
01374    if (subclass < IAX_FLAG_SC_LOG)
01375       return subclass;
01376    /* Otherwise find its power */
01377    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01378       if (subclass & (1 << x)) {
01379          if (power > -1) {
01380             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01381             return 0;
01382          } else
01383             power = x;
01384       }
01385    }
01386    return power | IAX_FLAG_SC_LOG;
01387 }

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

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

08842 {
08843    jb_info stats;
08844    jb_getinfo(pvt->jb, &stats);
08845    
08846    memset(iep, 0, sizeof(*iep));
08847 
08848    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
08849    if(stats.frames_in == 0) stats.frames_in = 1;
08850    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
08851    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
08852    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
08853    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
08854    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
08855 }

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

Definition at line 4234 of file chan_iax2.c.

References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ast_clear_flag, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags, ast_copy_string(), ast_db_get(), ast_debug, ast_get_ip_or_srv(), ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, iax2_peer::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_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::mohinterpret, create_addr_info::mohinterpret, iax2_peer::mohsuggest, create_addr_info::mohsuggest, ast_channel::nativeformats, iax2_peer::outkey, create_addr_info::outkey, peer_unref(), iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.

04235 {
04236    struct iax2_peer *peer;
04237    int res = -1;
04238    struct ast_codec_pref ourprefs;
04239 
04240    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
04241    cai->sockfd = defaultsockfd;
04242    cai->maxtime = 0;
04243    sin->sin_family = AF_INET;
04244 
04245    if (!(peer = find_peer(peername, 1))) {
04246       cai->found = 0;
04247       if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
04248          ast_log(LOG_WARNING, "No such host: %s\n", peername);
04249          return -1;
04250       }
04251       sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04252       /* use global iax prefs for unknown peer/user */
04253       /* But move the calling channel's native codec to the top of the preference list */
04254       memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04255       if (c)
04256          ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04257       ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04258       return 0;
04259    }
04260 
04261    cai->found = 1;
04262    
04263    /* if the peer has no address (current or default), return failure */
04264    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
04265       goto return_unref;
04266 
04267    /* if the peer is being monitored and is currently unreachable, return failure */
04268    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04269       goto return_unref;
04270 
04271    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
04272    cai->maxtime = peer->maxms;
04273    cai->capability = peer->capability;
04274    cai->encmethods = peer->encmethods;
04275    cai->sockfd = peer->sockfd;
04276    cai->adsi = peer->adsi;
04277    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04278    /* Move the calling channel's native codec to the top of the preference list */
04279    if (c) {
04280       ast_debug(1, "prepending %x to prefs\n", c->nativeformats);
04281       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04282    }
04283    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04284    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04285    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04286    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04287    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04288    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04289    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04290    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04291    if (ast_strlen_zero(peer->dbsecret)) {
04292       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04293    } else {
04294       char *family;
04295       char *key = NULL;
04296 
04297       family = ast_strdupa(peer->dbsecret);
04298       key = strchr(family, '/');
04299       if (key)
04300          *key++ = '\0';
04301       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04302          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04303          goto return_unref;
04304       }
04305    }
04306 
04307    if (peer->addr.sin_addr.s_addr) {
04308       sin->sin_addr = peer->addr.sin_addr;
04309       sin->sin_port = peer->addr.sin_port;
04310    } else {
04311       sin->sin_addr = peer->defaddr.sin_addr;
04312       sin->sin_port = peer->defaddr.sin_port;
04313    }
04314 
04315    res = 0;
04316 
04317 return_unref:
04318    peer_unref(peer);
04319 
04320    return res;
04321 }

static int create_callno_pools ( void   )  [static]

Definition at line 2393 of file chan_iax2.c.

References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, callno_hash(), IAX_MAX_CALLS, and TRUNK_CALL_START.

Referenced by load_objects().

02394 {
02395    uint16_t i;
02396 
02397    if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02398       return -1;
02399    }
02400 
02401    if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02402       return -1;
02403    }
02404 
02405    /* start at 2, 0 and 1 are reserved */
02406    for (i = 2; i <= IAX_MAX_CALLS; i++) {
02407       struct callno_entry *callno_entry;
02408 
02409       if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02410          return -1;
02411       }
02412 
02413       callno_entry->callno = i;
02414 
02415       if (i < TRUNK_CALL_START) {
02416          ao2_link(callno_pool, callno_entry);
02417       } else {
02418          ao2_link(callno_pool_trunk, callno_entry);
02419       }
02420 
02421       ao2_ref(callno_entry, -1);
02422    }
02423 
02424    return 0;
02425 }

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

References ast_debug, AST_FRAME_VIDEO, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, f, IAX_FLAG_FULL, memcpy_decrypt(), ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::type, and uncompress_subclass().

Referenced by decrypt_frame(), and update_packet().

05825 {
05826    int padding;
05827    unsigned char *workspace;
05828 
05829    workspace = alloca(*datalen);
05830    memset(f, 0, sizeof(*f));
05831    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05832       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05833       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
05834          return -1;
05835       /* Decrypt */
05836       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
05837 
05838       padding = 16 + (workspace[15] & 0x0f);
05839       if (iaxdebug)
05840          ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
05841       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
05842          return -1;
05843 
05844       *datalen -= padding;
05845       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05846       f->frametype = fh->type;
05847       if (f->frametype == AST_FRAME_VIDEO) {
05848          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
05849       } else {
05850          f->subclass = uncompress_subclass(fh->csub);
05851       }
05852    } else {
05853       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05854       if (iaxdebug)
05855          ast_debug(1, "Decoding mini with length %d\n", *datalen);
05856       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
05857          return -1;
05858       /* Decrypt */
05859       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
05860       padding = 16 + (workspace[15] & 0x0f);
05861       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
05862          return -1;
05863       *datalen -= padding;
05864       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05865    }
05866    return 0;
05867 }

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

Definition at line 5910 of file chan_iax2.c.

References ast_set_flag, ast_strdupa, ast_test_flag, build_encryption_keys(), decode_frame(), f, IAX_KEYPOPULATED, iaxs, md5(), MD5Final(), MD5Init(), MD5Update(), secret, and strsep().

Referenced by socket_process().

05911 {
05912    int res=-1;
05913    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
05914       /* Search for possible keys, given secrets */
05915       struct MD5Context md5;
05916       unsigned char digest[16];
05917       char *tmppw, *stringp;
05918       
05919       tmppw = ast_strdupa(iaxs[callno]->secret);
05920       stringp = tmppw;
05921       while ((tmppw = strsep(&stringp, ";"))) {
05922          MD5Init(&md5);
05923          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05924          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05925          MD5Final(digest, &md5);
05926          build_encryption_keys(digest, iaxs[callno]);
05927          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05928          if (!res) {
05929             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
05930             break;
05931          }
05932       }
05933    } else 
05934       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05935    return res;
05936 }

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

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

Referenced by socket_read().

08989 {
08990    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
08991    struct ast_iax2_full_hdr *fh, *cur_fh;
08992 
08993    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
08994       return;
08995 
08996    pkt_buf->len = from_here->buf_len;
08997    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
08998 
08999    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09000    ast_mutex_lock(&to_here->lock);
09001    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09002       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09003       if (fh->oseqno < cur_fh->oseqno) {
09004          AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09005          break;
09006       }
09007    }
09008    AST_LIST_TRAVERSE_SAFE_END
09009 
09010    if (!cur_pkt_buf)
09011       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09012    
09013    ast_mutex_unlock(&to_here->lock);
09014 }

static void delete_users ( void   )  [static]

Definition at line 12249 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::entry, iax2_registry::expire, iax2_destroy(), iaxs, peer_delme_cb(), peers, chan_iax2_pvt::reg, sched, user_delme_cb(), and users.

12250 {
12251    struct iax2_registry *reg;
12252 
12253    ao2_callback(users, 0, user_delme_cb, NULL);
12254 
12255    AST_LIST_LOCK(&registrations);
12256    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
12257       AST_SCHED_DEL(sched, reg->expire);
12258       if (reg->callno) {
12259          int callno = reg->callno;
12260          ast_mutex_lock(&iaxsl[callno]);
12261          if (iaxs[callno]) {
12262             iaxs[callno]->reg = NULL;
12263             iax2_destroy(callno);
12264          }
12265          ast_mutex_unlock(&iaxsl[callno]);
12266       }
12267       if (reg->dnsmgr)
12268          ast_dnsmgr_release(reg->dnsmgr);
12269       ast_free(reg);
12270    }
12271    AST_LIST_UNLOCK(&registrations);
12272 
12273    ao2_callback(peers, 0, peer_delme_cb, NULL);
12274 }

static void destroy_firmware ( struct iax_firmware cur  )  [static]

Definition at line 2749 of file chan_iax2.c.

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

Referenced by reload_firmware().

02750 {
02751    /* Close firmware */
02752    if (cur->fwh) {
02753       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02754    }
02755    close(cur->fd);
02756    ast_free(cur);
02757 }

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

Definition at line 8689 of file chan_iax2.c.

References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_IAX, ast_ignore_pattern(), ast_matchmore_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_parking_ext(), IAX_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxs, and send_command().

Referenced by dp_lookup_thread(), and socket_process().

08690 {
08691    unsigned short dpstatus = 0;
08692    struct iax_ie_data ied1;
08693    int mm;
08694 
08695    memset(&ied1, 0, sizeof(ied1));
08696    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
08697    /* Must be started */
08698    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
08699       dpstatus = IAX_DPSTATUS_EXISTS;
08700    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
08701       dpstatus = IAX_DPSTATUS_CANEXIST;
08702    } else {
08703       dpstatus = IAX_DPSTATUS_NONEXISTENT;
08704    }
08705    if (ast_ignore_pattern(context, callednum))
08706       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
08707    if (mm)
08708       dpstatus |= IAX_DPSTATUS_MATCHMORE;
08709    if (!skiplock)
08710       ast_mutex_lock(&iaxsl[callno]);
08711    if (iaxs[callno]) {
08712       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
08713       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
08714       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
08715       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
08716    }
08717    if (!skiplock)
08718       ast_mutex_unlock(&iaxsl[callno]);
08719 }

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

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

08722 {
08723    /* Look up for dpreq */
08724    struct dpreq_data *dpr = data;
08725    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
08726    if (dpr->callerid)
08727       ast_free(dpr->callerid);
08728    ast_free(dpr);
08729    return NULL;
08730 }

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

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

05870 {
05871    int padding;
05872    unsigned char *workspace;
05873    workspace = alloca(*datalen + 32);
05874    if (!workspace)
05875       return -1;
05876    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05877       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05878       if (iaxdebug)
05879          ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
05880       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
05881       padding = 16 + (padding & 0xf);
05882       memcpy(workspace, poo, padding);
05883       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05884       workspace[15] &= 0xf0;
05885       workspace[15] |= (padding & 0xf);
05886       if (iaxdebug)
05887          ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
05888       *datalen += padding;
05889       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
05890       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
05891          memcpy(poo, workspace + *datalen - 32, 32);
05892    } else {
05893       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05894       if (iaxdebug)
05895          ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
05896       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
05897       padding = 16 + (padding & 0xf);
05898       memcpy(workspace, poo, padding);
05899       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05900       workspace[15] &= 0xf0;
05901       workspace[15] |= (padding & 0x0f);
05902       *datalen += padding;
05903       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
05904       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
05905          memcpy(poo, workspace + *datalen - 32, 32);
05906    }
05907    return 0;
05908 }

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

Definition at line 8120 of file chan_iax2.c.

References __expire_registry(), and schedule_action.

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

08121 {
08122 #ifdef SCHED_MULTITHREADED
08123    if (schedule_action(__expire_registry, data))
08124 #endif      
08125       __expire_registry(data);
08126    return 0;
08127 }

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

Definition at line 12886 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, chan, errno, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, iax2_dprequest(), IAX_STATE_STARTED, iaxs, LOG_WARNING, iax2_dpcache::orig, iax2_dpcache::peercontext, and iax2_dpcache::waiters.

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

12887 {
12888    struct iax2_dpcache *dp = NULL;
12889    struct timeval now = ast_tvnow();
12890    int x, com[2], timeout, old = 0, outfd, doabort, callno;
12891    struct ast_channel *c = NULL;
12892    struct ast_frame *f = NULL;
12893 
12894    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
12895       if (ast_tvcmp(now, dp->expiry) > 0) {
12896          AST_LIST_REMOVE_CURRENT(cache_list);
12897          if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
12898             ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
12899          else
12900             ast_free(dp);
12901          continue;
12902       }
12903       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
12904          break;
12905    }
12906    AST_LIST_TRAVERSE_SAFE_END;
12907 
12908    if (!dp) {
12909       /* No matching entry.  Create a new one. */
12910       /* First, can we make a callno? */
12911       if ((callno = cache_get_callno_locked(data)) < 0) {
12912          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
12913          return NULL;
12914       }
12915       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
12916          ast_mutex_unlock(&iaxsl[callno]);
12917          return NULL;
12918       }
12919       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
12920       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
12921       dp->expiry = ast_tvnow();
12922       dp->orig = dp->expiry;
12923       /* Expires in 30 mins by default */
12924       dp->expiry.tv_sec += iaxdefaultdpcache;
12925       dp->flags = CACHE_FLAG_PENDING;
12926       for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
12927          dp->waiters[x] = -1;
12928       /* Insert into the lists */
12929       AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
12930       AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
12931       /* Send the request if we're already up */
12932       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
12933          iax2_dprequest(dp, callno);
12934       ast_mutex_unlock(&iaxsl[callno]);
12935    }
12936 
12937    /* By here we must have a dp */
12938    if (dp->flags & CACHE_FLAG_PENDING) {
12939       /* Okay, here it starts to get nasty.  We need a pipe now to wait
12940          for a reply to come back so long as it's pending */
12941       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
12942          /* Find an empty slot */
12943          if (dp->waiters[x] < 0)
12944             break;
12945       }
12946       if (x >= ARRAY_LEN(dp->waiters)) {
12947          ast_log(LOG_WARNING, "No more waiter positions available\n");
12948          return NULL;
12949       }
12950       if (pipe(com)) {
12951          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
12952          return NULL;
12953       }
12954       dp->waiters[x] = com[1];
12955       /* Okay, now we wait */
12956       timeout = iaxdefaulttimeout * 1000;
12957       /* Temporarily unlock */
12958       AST_LIST_UNLOCK(&dpcache);
12959       /* Defer any dtmf */
12960       if (chan)
12961          old = ast_channel_defer_dtmf(chan);
12962       doabort = 0;
12963       while(timeout) {
12964          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
12965          if (outfd > -1)
12966             break;
12967          if (!c)
12968             continue;
12969          if (!(f = ast_read(c))) {
12970             doabort = 1;
12971             break;
12972          }
12973          ast_frfree(f);
12974       }
12975       if (!timeout) {
12976          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
12977       }
12978       AST_LIST_LOCK(&dpcache);
12979       dp->waiters[x] = -1;
12980       close(com[1]);
12981       close(com[0]);
12982       if (doabort) {
12983          /* Don't interpret anything, just abort.  Not sure what th epoint
12984            of undeferring dtmf on a hung up channel is but hey whatever */
12985          if (!old && chan)
12986             ast_channel_undefer_dtmf(chan);
12987          return NULL;
12988       }
12989       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
12990          /* Now to do non-independent analysis the results of our wait */
12991          if (dp->flags & CACHE_FLAG_PENDING) {
12992             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
12993                pending.  Don't let it take as long to timeout. */
12994             dp->flags &= ~CACHE_FLAG_PENDING;
12995             dp->flags |= CACHE_FLAG_TIMEOUT;
12996             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
12997                systems without leaving it unavailable once the server comes back online */
12998             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
12999             for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13000                if (dp->waiters[x] > -1) {
13001                   if (write(dp->waiters[x], "asdf", 4) < 0) {
13002                      ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13003                   }
13004                }
13005             }
13006          }
13007       }
13008       /* Our caller will obtain the rest */
13009       if (!old && chan)
13010          ast_channel_undefer_dtmf(chan);
13011    }
13012    return dp;  
13013 }

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

References __find_callno().

Referenced by iax2_poke_peer(), and socket_process().

02649                                                                                                                                     {
02650 
02651    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02652 }

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

02654                                                                                                                                            {
02655 
02656    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02657 }

static struct iax2_thread* find_idle_thread ( void   )  [static]

Definition at line 1181 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_detached_background, iax2_process_thread(), IAX_THREAD_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, iax2_trunk_peer::list, and thread.

Referenced by __schedule_action(), and socket_read().

01182 {
01183    struct iax2_thread *thread = NULL;
01184 
01185    /* Pop the head of the idle list off */
01186    AST_LIST_LOCK(&idle_list);
01187    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01188    AST_LIST_UNLOCK(&idle_list);
01189 
01190    /* If we popped a thread off the idle list, just return it */
01191    if (thread) {
01192       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01193       return thread;
01194    }
01195 
01196    /* Pop the head of the dynamic list off */
01197    AST_LIST_LOCK(&dynamic_list);
01198    thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01199    AST_LIST_UNLOCK(&dynamic_list);
01200 
01201    /* If we popped a thread off the dynamic list, just return it */
01202    if (thread) {
01203       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01204       return thread;
01205    }
01206 
01207    /* If we can't create a new dynamic thread for any reason, return no thread at all */
01208    if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01209       return NULL;
01210 
01211    /* Set default values */
01212    ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01213    thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01214    thread->type = IAX_THREAD_TYPE_DYNAMIC;
01215 
01216    /* Initialize lock and condition */
01217    ast_mutex_init(&thread->lock);
01218    ast_cond_init(&thread->cond, NULL);
01219    ast_mutex_init(&thread->init_lock);
01220    ast_cond_init(&thread->init_cond, NULL);
01221    ast_mutex_lock(&thread->init_lock);
01222 
01223    /* Create thread and send it on it's way */
01224    if (ast_pthread_create_detached_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01225       ast_cond_destroy(&thread->cond);
01226       ast_mutex_destroy(&thread->lock);
01227       ast_free(thread);
01228       return NULL;
01229    }
01230 
01231    /* this thread is not processing a full frame (since it is idle),
01232       so ensure that the field for the full frame call number is empty */
01233    memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01234 
01235    /* Wait for the thread to be ready before returning it to the caller */
01236    ast_cond_wait(&thread->init_cond, &thread->init_lock);
01237 
01238    /* Done with init_lock */
01239    ast_mutex_unlock(&thread->init_lock);
01240 
01241    return thread;
01242 }

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

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

References ao2_find, iax2_peer::name, OBJ_POINTER, peers, and realtime_peer().

01448 {
01449    struct iax2_peer *peer = NULL;
01450    struct iax2_peer tmp_peer = {
01451       .name = name,
01452    };
01453 
01454    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01455 
01456    /* Now go for realtime if applicable */
01457    if(!peer && realtime)
01458       peer = realtime_peer(name, NULL);
01459 
01460    return peer;
01461 }

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

Definition at line 5642 of file chan_iax2.c.

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

Referenced by iax2_trunk_queue(), and socket_process_meta().

05643 {
05644    struct iax2_trunk_peer *tpeer = NULL;
05645    
05646    /* Finds and locks trunk peer */
05647    AST_LIST_LOCK(&tpeers);
05648 
05649    AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
05650       if (!inaddrcmp(&tpeer->addr, sin)) {
05651          ast_mutex_lock(&tpeer->lock);
05652          break;
05653       }
05654    }
05655 
05656    if (!tpeer) {
05657       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
05658          ast_mutex_init(&tpeer->lock);
05659          tpeer->lastsent = 9999;
05660          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
05661          tpeer->trunkact = ast_tvnow();
05662          ast_mutex_lock(&tpeer->lock);
05663          tpeer->sockfd = fd;
05664 #ifdef SO_NO_CHECK
05665          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
05666 #endif
05667          ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
05668          AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
05669       }
05670    }
05671 
05672    AST_LIST_UNLOCK(&tpeers);
05673 
05674    return tpeer;
05675 }

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

Definition at line 1475 of file chan_iax2.c.

References ao2_find, iax2_user::name, OBJ_POINTER, and users.

01476 {
01477    struct iax2_user tmp_user = {
01478       .name = name,
01479    };
01480 
01481    return ao2_find(users, &tmp_user, OBJ_POINTER);
01482 }

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

Definition at line 5454 of file chan_iax2.c.

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

Referenced by socket_process_meta().

05455 {
05456    long ms; /* NOT unsigned */
05457    if (ast_tvzero(iaxs[callno]->rxcore)) {
05458       /* Initialize rxcore time if appropriate */
05459       iaxs[callno]->rxcore = ast_tvnow();
05460       /* Round to nearest 20ms so traces look pretty */
05461       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05462    }
05463    /* Calculate difference between trunk and channel */
05464    ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05465    /* Return as the sum of trunk time and the difference between trunk and real time */
05466    return ms + ts;
05467 }

static void free_context ( struct iax2_context con  )  [static]

Definition at line 11383 of file chan_iax2.c.

References ast_free, and iax2_context::next.

Referenced by build_user(), and user_destructor().

11384 {
11385    struct iax2_context *conl;
11386    while(con) {
11387       conl = con;
11388       con = con->next;
11389       ast_free(conl);
11390    }
11391 }

static void free_signaling_queue_entry ( struct signaling_queue_entry s  )  [static]

Definition at line 1575 of file chan_iax2.c.

References ast_free, and s.

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

01576 {
01577    ast_free(s->f.data.ptr);
01578    ast_free(s);
01579 }

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

Definition at line 13136 of file chan_iax2.c.

References iax2_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strdupa, ast_test_flag, iax2_peer::capability, chan, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, iax2_peer::mailbox, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.

13137 {
13138    struct iax2_peer *peer;
13139    char *peername, *colname;
13140 
13141    peername = ast_strdupa(data);
13142 
13143    /* if our channel, return the IP address of the endpoint of current channel */
13144    if (!strcmp(peername,"CURRENTCHANNEL")) {
13145            unsigned short callno;
13146       if (chan->tech != &iax2_tech)
13147          return -1;
13148       callno = PTR_TO_CALLNO(chan->tech_pvt);   
13149       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13150       return 0;
13151    }
13152 
13153    if ((colname = strchr(peername, ',')))
13154       *colname++ = '\0';
13155    else
13156       colname = "ip";
13157 
13158    if (!(peer = find_peer(peername, 1)))
13159       return -1;
13160 
13161    if (!strcasecmp(colname, "ip")) {
13162       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
13163    } else  if (!strcasecmp(colname, "status")) {
13164       peer_status(peer, buf, len); 
13165    } else  if (!strcasecmp(colname, "mailbox")) {
13166       ast_copy_string(buf, peer->mailbox, len);
13167    } else  if (!strcasecmp(colname, "context")) {
13168       ast_copy_string(buf, peer->context, len);
13169    } else  if (!strcasecmp(colname, "expire")) {
13170       snprintf(buf, len, "%d", peer->expire);
13171    } else  if (!strcasecmp(colname, "dynamic")) {
13172       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13173    } else  if (!strcasecmp(colname, "callerid_name")) {
13174       ast_copy_string(buf, peer->cid_name, len);
13175    } else  if (!strcasecmp(colname, "callerid_num")) {
13176       ast_copy_string(buf, peer->cid_num, len);
13177    } else  if (!strcasecmp(colname, "codecs")) {
13178       ast_getformatname_multiple(buf, len -1, peer->capability);
13179    } else  if (!strncasecmp(colname, "codec[", 6)) {
13180       char *codecnum, *ptr;
13181       int codec = 0;
13182       
13183       codecnum = strchr(colname, '[');
13184       *codecnum = '\0';
13185       codecnum++;
13186       if ((ptr = strchr(codecnum, ']'))) {
13187          *ptr = '\0';
13188       }
13189       if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13190          ast_copy_string(buf, ast_getformatname(codec), len);
13191       } else {
13192          buf[0] = '\0';
13193       }
13194    } else {
13195       buf[0] = '\0';
13196    }
13197 
13198    peer_unref(peer);
13199 
13200    return 0;
13201 }

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

Definition at line 11603 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

11604 {
11605    int methods = 0;
11606    if (strstr(value, "rsa"))
11607       methods |= IAX_AUTH_RSA;
11608    if (strstr(value, "md5"))
11609       methods |= IAX_AUTH_MD5;
11610    if (strstr(value, "plaintext"))
11611       methods |= IAX_AUTH_PLAINTEXT;
11612    return methods;
11613 }

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

Definition at line 1324 of file chan_iax2.c.

References ast_true(), and IAX_ENCRYPT_AES128.

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

01325 {
01326    int e;
01327    if (!strcasecmp(s, "aes128"))
01328       e = IAX_ENCRYPT_AES128;
01329    else if (ast_true(s))
01330       e = IAX_ENCRYPT_AES128;
01331    else
01332       e = 0;
01333    return e;
01334 }

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

Definition at line 3852 of file chan_iax2.c.

References __get_from_jb(), and schedule_action.

Referenced by update_jbsched().

03853 {
03854 #ifdef SCHED_MULTITHREADED
03855    if (schedule_action(__get_from_jb, data))
03856 #endif      
03857       __get_from_jb(data);
03858    return 0;
03859 }

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

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

02327 {
02328    struct callno_entry *callno_entry = NULL;
02329    if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02330       ast_log(LOG_WARNING, "Out of CallNumbers\n");
02331       /* Minor optimization for the extreme case. */
02332       return NULL;
02333    }
02334 
02335    /* the callno_pool container is locked here primarily to ensure thread
02336     * safety of the total_nonval_callno_used check and increment */
02337    ao2_lock(callno_pool);
02338 
02339    /* only a certain number of nonvalidated call numbers should be allocated.
02340     * If there ever is an attack, this separates the calltoken validating
02341     * users from the non calltoken validating users. */
02342    if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02343       ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02344       ao2_unlock(callno_pool);
02345       return NULL;
02346    }
02347 
02348    /* unlink the object from the container, taking over ownership
02349     * of the reference the container had to the object */
02350    callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02351 
02352    if (callno_entry) {
02353       callno_entry->validated = validated;
02354       if (!validated) {
02355          total_nonval_callno_used++;
02356       }
02357    }
02358 
02359    ao2_unlock(callno_pool);
02360    return callno_entry;
02361 }

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

References ast_inet_ntoa(), ast_log(), ast_sha1_hash(), ast_str_alloca, ast_str_buffer, ast_str_set(), buf, 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().

04533 {
04534 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"  /* address + port + ts + randomcalldata */
04535 #define CALLTOKEN_IE_FORMAT   "%u?%s"     /* time + ? + (40 char hash) */
04536    struct ast_str *buf = ast_str_alloca(256);
04537    time_t t = time(NULL);
04538    char hash[41]; /* 40 char sha1 hash */
04539    int subclass = uncompress_subclass(fh->csub);
04540 
04541    /* ----- Case 1 ----- */
04542    if (ies->calltoken && !ies->calltokendata) {  /* empty calltoken is provided, client supports calltokens */
04543       struct iax_ie_data ied = {
04544          .buf = { 0 },
04545          .pos = 0,
04546       };
04547 
04548       /* create the hash with their address data and our timestamp */
04549       ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04550       ast_sha1_hash(hash, ast_str_buffer(buf));
04551 
04552       ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04553       iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04554       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04555 
04556       return 1;
04557 
04558    /* ----- Case 2 ----- */
04559    } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */
04560       char *rec_hash = NULL;    /* the received hash, make sure it matches with ours. */
04561       char *rec_ts = NULL;      /* received timestamp */
04562       unsigned int rec_time;  /* received time_t */
04563 
04564       /* split the timestamp from the hash data */
04565       rec_hash = strchr((char *) ies->calltokendata, '?');
04566       if (rec_hash) {
04567          *rec_hash++ = '\0';
04568          rec_ts = (char *) ies->calltokendata;
04569       }
04570 
04571       /* check that we have valid data before we do any comparisons */
04572       if (!rec_hash || !rec_ts) {
04573          goto reject;
04574       } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04575          goto reject;
04576       }
04577 
04578       /* create a hash with their address and the _TOKEN'S_ timestamp */
04579       ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04580       ast_sha1_hash(hash, ast_str_buffer(buf));
04581 
04582       /* compare hashes and then check timestamp delay */
04583       if (strcmp(hash, rec_hash)) {
04584          ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04585          goto reject; /* received hash does not match ours, reject */
04586       } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04587          ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04588          goto reject; /* too much delay, reject */
04589       }
04590 
04591       /* at this point the call token is valid, returning 0 
04592        * will allow socket_process to continue as usual */
04593       requirecalltoken_mark_auto(ies->username, subclass);
04594       return 0;
04595 
04596    /* ----- Case 3 ----- */
04597    } else { /* calltokens are not supported for this client, how do we respond? */
04598       if (calltoken_required(sin, ies->username, subclass)) {
04599          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"));
04600          goto reject;
04601       }
04602       return 0; /* calltoken is not required for this addr, so permit it. */
04603    }
04604 
04605 reject:
04606    /* received frame has failed calltoken inspection, send apathetic reject messages */
04607    if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04608       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04609    } else {
04610       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04611    }
04612 
04613    return 1;
04614 }

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

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

11235 {
11236    int force = 0;
11237    int res;
11238 
11239    switch (cmd) {
11240    case CLI_INIT:
11241       e->command = "iax2 provision";
11242       e->usage = 
11243          "Usage: iax2 provision <host> <template> [forced]\n"
11244          "       Provisions the given peer or IP address using a template\n"
11245          "       matching either 'template' or '*' if the template is not\n"
11246          "       found.  If 'forced' is specified, even empty provisioning\n"
11247          "       fields will be provisioned as empty fields.\n";
11248       return NULL;
11249    case CLI_GENERATE:
11250       if (a->pos == 3)
11251          return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11252       return NULL;
11253    }
11254 
11255    if (a->argc < 4)
11256       return CLI_SHOWUSAGE;
11257    if (a->argc > 4) {
11258       if (!strcasecmp(a->argv[4], "forced"))
11259          force = 1;
11260       else
11261          return CLI_SHOWUSAGE;
11262    }
11263    res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11264    if (res < 0)
11265       ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11266    else if (res < 1)
11267       ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11268    else
11269       ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11270    return CLI_SUCCESS;
11271 }

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

Definition at line 3300 of file chan_iax2.c.

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

03301 {
03302    struct iax2_peer *peer = NULL;
03303    struct iax2_user *user = NULL;
03304 
03305    switch (cmd) {
03306    case CLI_INIT:
03307       e->command = "iax2 prune realtime";
03308       e->usage =
03309          "Usage: iax2 prune realtime [<peername>|all]\n"
03310          "       Prunes object(s) from the cache\n";
03311       return NULL;
03312    case CLI_GENERATE:
03313       if (a->pos == 3)
03314          return complete_iax2_peers(a->line, a->word, a->pos, a->n);
03315       return NULL;
03316    }
03317    if (a->argc != 4)
03318         return CLI_SHOWUSAGE;
03319    if (!strcmp(a->argv[3], "all")) {
03320       prune_users();
03321       prune_peers();
03322       ast_cli(a->fd, "Cache flushed successfully.\n");
03323       return CLI_SUCCESS;
03324    }
03325    peer = find_peer(a->argv[3], 0);
03326    user = find_user(a->argv[3]);
03327    if (peer || user) {
03328       if (peer) {
03329          if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
03330             ast_set_flag(peer, IAX_RTAUTOCLEAR);
03331             expire_registry(peer_ref(peer));
03332             ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03333          } else {
03334             ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03335          }
03336          peer_unref(peer);
03337       }
03338       if (user) {
03339          if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
03340             ast_set_flag(user, IAX_RTAUTOCLEAR);
03341             ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03342          } else {
03343             ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03344          }
03345          ao2_unlink(users,user);
03346          user_unref(user);
03347       }
03348    } else {
03349       ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03350    }
03351 
03352    return CLI_SUCCESS;
03353 }

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

Definition at line 12790 of file chan_iax2.c.

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

12791 {
12792    switch (cmd) {
12793    case CLI_INIT:
12794       e->command = "iax2 reload";
12795       e->usage =
12796          "Usage: iax2 reload\n"
12797          "       Reloads IAX configuration from iax.conf\n";
12798       return NULL;
12799    case CLI_GENERATE:
12800       return NULL;
12801    }
12802 
12803    reload_config();
12804 
12805    return CLI_SUCCESS;
12806 }

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

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

06839 {
06840    switch (cmd) {
06841    case CLI_INIT:
06842       e->command = "iax2 set debug {on|off|peer}";
06843       e->usage =
06844          "Usage: iax2 set debug {on|off|peer peername}\n"
06845          "       Enables/Disables dumping of IAX packets for debugging purposes.\n";
06846       return NULL;
06847    case CLI_GENERATE:
06848       if (a->pos == 4)
06849          return complete_iax2_peers(a->line, a->word, a->pos, a->n);
06850       return NULL;
06851    }
06852 
06853    if (a->argc < e->args  || a->argc > e->args + 1)
06854       return CLI_SHOWUSAGE;
06855 
06856    if (!strcasecmp(a->argv[3], "peer")) {
06857       struct iax2_peer *peer;
06858 
06859       if (a->argc != e->args + 1)
06860          return CLI_SHOWUSAGE;
06861 
06862       peer = find_peer(a->argv[4], 1);
06863 
06864       if (!peer) {
06865          ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
06866          return CLI_FAILURE;
06867       }
06868 
06869       debugaddr.sin_addr = peer->addr.sin_addr;
06870       debugaddr.sin_port = peer->addr.sin_port;
06871 
06872       ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
06873          ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
06874 
06875       ao2_ref(peer, -1);
06876    } else if (!strncasecmp(a->argv[3], "on", 2)) {
06877       iaxdebug = 1;
06878       ast_cli(a->fd, "IAX2 Debugging Enabled\n");
06879    } else {
06880       iaxdebug = 0;
06881       memset(&debugaddr, 0, sizeof(debugaddr));
06882       ast_cli(a->fd, "IAX2 Debugging Disabled\n");
06883    }
06884    return CLI_SUCCESS;
06885 }

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

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

06914 {
06915    switch (cmd) {
06916    case CLI_INIT:
06917       e->command = "iax2 set debug jb {on|off}";
06918       e->usage =
06919          "Usage: iax2 set debug jb {on|off}\n"
06920          "       Enables/Disables jitterbuffer debugging information\n";
06921       return NULL;
06922    case CLI_GENERATE:
06923       return NULL;
06924    }
06925 
06926    if (a->argc != e->args)
06927       return CLI_SHOWUSAGE;
06928    
06929    if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
06930       jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
06931       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
06932    } else {
06933       jb_setoutput(jb_error_output, jb_warning_output, NULL);
06934       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
06935    }
06936    return CLI_SUCCESS;
06937 }

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

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

06888 {
06889    switch (cmd) {
06890    case CLI_INIT:
06891       e->command = "iax2 set debug trunk {on|off}";
06892       e->usage =
06893          "Usage: iax2 set debug trunk {on|off}\n"
06894          "       Enables/Disables debugging of IAX trunking\n";
06895       return NULL;
06896    case CLI_GENERATE:
06897       return NULL;
06898    }
06899 
06900    if (a->argc != e->args)
06901       return CLI_SHOWUSAGE;
06902 
06903    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
06904       iaxtrunkdebug = 1;
06905       ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
06906    } else {
06907       iaxtrunkdebug = 0;
06908       ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
06909    }
06910    return CLI_SUCCESS;
06911 }

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

03612 {
03613    int mtuv;
03614 
03615    switch (cmd) {
03616    case CLI_INIT:
03617       e->command = "iax2 set mtu";
03618       e->usage =
03619          "Usage: iax2 set mtu <value>\n"
03620          "       Set the system-wide IAX IP mtu to <value> bytes net or\n"
03621          "       zero to disable. Disabling means that the operating system\n"
03622          "       must handle fragmentation of UDP packets when the IAX2 trunk\n"
03623          "       packet exceeds the UDP payload size. This is substantially\n"
03624          "       below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03625          "       greater for G.711 samples.\n";
03626       return NULL;
03627    case CLI_GENERATE:
03628       return NULL;
03629    }
03630 
03631    if (a->argc != 4)
03632       return CLI_SHOWUSAGE; 
03633    if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03634       mtuv = MAX_TRUNK_MTU;
03635    else
03636       mtuv = atoi(a->argv[3]);
03637 
03638    if (mtuv == 0) {
03639       ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 
03640       global_max_trunk_mtu = 0; 
03641       return CLI_SUCCESS; 
03642    }
03643    if (mtuv < 172 || mtuv > 4000) {
03644       ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 
03645       return CLI_SHOWUSAGE; 
03646    }
03647    ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 
03648    global_max_trunk_mtu = mtuv; 
03649    return CLI_SUCCESS;
03650 }

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

Definition at line 3652 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, s, ast_cli_entry::usage, and iax2_dpcache::waiters.

03653 {
03654    struct iax2_dpcache *dp = NULL;
03655    char tmp[1024], *pc = NULL;
03656    int s, x, y;
03657    struct timeval now = ast_tvnow();
03658 
03659    switch (cmd) {
03660    case CLI_INIT:
03661       e->command = "iax2 show cache";
03662       e->usage =
03663          "Usage: iax2 show cache\n"
03664          "       Display currently cached IAX Dialplan results.\n";
03665       return NULL;
03666    case CLI_GENERATE:
03667       return NULL;
03668    }
03669 
03670    AST_LIST_LOCK(&dpcache);
03671 
03672    ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03673 
03674    AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03675       s = dp->expiry.tv_sec - now.tv_sec;
03676       tmp[0] = '\0';
03677       if (dp->flags & CACHE_FLAG_EXISTS)
03678          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03679       if (dp->flags & CACHE_FLAG_NONEXISTENT)
03680          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03681       if (dp->flags & CACHE_FLAG_CANEXIST)
03682          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03683       if (dp->flags & CACHE_FLAG_PENDING)
03684          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03685       if (dp->flags & CACHE_FLAG_TIMEOUT)
03686          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03687       if (dp->flags & CACHE_FLAG_TRANSMITTED)
03688          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03689       if (dp->flags & CACHE_FLAG_MATCHMORE)
03690          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03691       if (dp->flags & CACHE_FLAG_UNKNOWN)
03692          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03693       /* Trim trailing pipe */
03694       if (!ast_strlen_zero(tmp)) {
03695          tmp[strlen(tmp) - 1] = '\0';
03696       } else {
03697          ast_copy_string(tmp, "(none)", sizeof(tmp));
03698       }
03699       y = 0;
03700       pc = strchr(dp->peercontext, '@');
03701       if (!pc) {
03702          pc = dp->peercontext;
03703       } else {
03704          pc++;
03705       }
03706       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
03707          if (dp->waiters[x] > -1)
03708             y++;
03709       }
03710       if (s > 0) {
03711          ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03712       } else {
03713          ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03714       }
03715    }
03716 
03717    AST_LIST_UNLOCK(&dpcache);
03718 
03719    return CLI_SUCCESS;
03720 }

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

Definition at line 2279 of file chan_iax2.c.

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

02280 {
02281    struct ao2_iterator i;
02282    struct peercnt *peercnt;
02283    struct sockaddr_in sin;
02284    int found = 0;
02285 
02286    switch (cmd) {
02287    case CLI_INIT:
02288       e->command = "iax2 show callnumber usage";
02289       e->usage =
02290          "Usage: iax2 show callnumber usage <ip address (optional)>\n"
02291          "       Shows current ip addresses which are consuming iax2 call numbers\n";
02292       return NULL;
02293    case CLI_GENERATE:
02294       return NULL;
02295    case CLI_HANDLER:
02296       if (a->argc < 4 || a->argc > 5)
02297          return CLI_SHOWUSAGE;
02298 
02299       ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02300       i = ao2_iterator_init(peercnts, 0);
02301       while ((peercnt = ao2_iterator_next(&i))) {
02302          sin.sin_addr.s_addr = peercnt->addr;
02303          if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02304                ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02305                found = 1;
02306                break;
02307          } else {
02308             ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02309          }
02310          ao2_ref(peercnt, -1);
02311       }
02312       ao2_iterator_destroy(&i);
02313 
02314       if (a->argc == 4) {
02315          ast_cli(a->fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used);
02316       } else if (a->argc == 5 && !found) {
02317          ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02318       }
02319 
02320       return CLI_SUCCESS;
02321    default:
02322       return NULL;
02323    }
02324 }

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

Definition at line 6665 of file chan_iax2.c.

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

06666 {
06667 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s  %s  %9s\n"
06668 #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"
06669 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
06670    int x;
06671    int numchans = 0;
06672    char first_message[10] = { 0, };
06673    char last_message[10] = { 0, };
06674 
06675    switch (cmd) {
06676    case CLI_INIT:
06677       e->command = "iax2 show channels";
06678       e->usage =
06679          "Usage: iax2 show channels\n"
06680          "       Lists all currently active IAX channels.\n";
06681       return NULL;
06682    case CLI_GENERATE:
06683       return NULL;
06684    }
06685 
06686    if (a->argc != 3)
06687       return CLI_SHOWUSAGE;
06688    ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
06689    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06690       ast_mutex_lock(&iaxsl[x]);
06691       if (iaxs[x]) {
06692          int lag, jitter, localdelay;
06693          jb_info jbinfo;
06694          if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06695             jb_getinfo(iaxs[x]->jb, &jbinfo);
06696             jitter = jbinfo.jitter;
06697             localdelay = jbinfo.current - jbinfo.min;
06698          } else {
06699             jitter = -1;
06700             localdelay = 0;
06701          }
06702 
06703          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06704          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06705          lag = iaxs[x]->remote_rr.delay;
06706          ast_cli(a->fd, FORMAT,
06707             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06708             ast_inet_ntoa(iaxs[x]->addr.sin_addr),
06709             S_OR(iaxs[x]->username, "(None)"),
06710             iaxs[x]->callno, iaxs[x]->peercallno,
06711             iaxs[x]->oseqno, iaxs[x]->iseqno,
06712             lag,
06713             jitter,
06714             localdelay,
06715             ast_getformatname(iaxs[x]->voiceformat),
06716             (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06717             first_message,
06718             (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06719             last_message);
06720          numchans++;
06721       }
06722       ast_mutex_unlock(&iaxsl[x]);
06723    }
06724    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06725    return CLI_SUCCESS;
06726 #undef FORMAT
06727 #undef FORMAT2
06728 #undef FORMATB
06729 }

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

Definition at line 6515 of file chan_iax2.c.

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

06516 {
06517    struct iax_firmware *cur = NULL;
06518 
06519    switch (cmd) {
06520    case CLI_INIT:
06521       e->command = "iax2 show firmware";
06522       e->usage =
06523          "Usage: iax2 show firmware\n"
06524          "       Lists all known IAX firmware images.\n";
06525       return NULL;
06526    case CLI_GENERATE:
06527       return NULL;
06528    }
06529 
06530    if (a->argc != 3 && a->argc != 4)
06531       return CLI_SHOWUSAGE;
06532 
06533    ast_cli(a->fd, "%-15.15s  %-15.15s %-15.15s\n", "Device", "Version", "Size");
06534    AST_LIST_LOCK(&firmwares);
06535    AST_LIST_TRAVERSE(&firmwares, cur, list) {
06536       if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname)))  {
06537          ast_cli(a->fd, "%-15.15s  %-15d %-15d\n", cur->fwh->devname, 
06538             ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06539       }
06540    }
06541    AST_LIST_UNLOCK(&firmwares);
06542 
06543    return CLI_SUCCESS;
06544 }

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

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

06816 {
06817    int numchans = 0;
06818 
06819    switch (cmd) {
06820    case CLI_INIT:
06821       e->command = "iax2 show netstats";
06822       e->usage =
06823          "Usage: iax2 show netstats\n"
06824          "       Lists network status for all currently active IAX channels.\n";
06825       return NULL;
06826    case CLI_GENERATE:
06827       return NULL;
06828    }
06829    if (a->argc != 3)
06830       return CLI_SHOWUSAGE;
06831    ast_cli(a->fd, "                           -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
06832    ast_cli(a->fd, "Channel               RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts FirstMsg    LastMsg\n");
06833    numchans = ast_cli_netstats(NULL, a->fd, 1);
06834    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06835    return CLI_SUCCESS;
06836 }

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

References iax2_peer::addr, ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, 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::expire, ast_cli_args::fd, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TRUNK, ast_cli_args::line, iax2_peer::mailbox, iax2_peer::maxcallno, ast_cli_args::n, iax2_peer::name, iax2_peer::parkinglot, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, ast_cli_args::pos, iax2_peer::prefs, iax2_peer::secret, iax2_peer::smoothing, status, ast_cli_entry::usage, iax2_peer::username, and ast_cli_args::word.

03470 {
03471    char status[30];
03472    char cbuf[256];
03473    struct iax2_peer *peer;
03474    char codec_buf[512];
03475    int x = 0, codec = 0, load_realtime = 0;
03476 
03477    switch (cmd) {
03478    case CLI_INIT:
03479       e->command = "iax2 show peer";
03480       e->usage =
03481          "Usage: iax2 show peer <name>\n"
03482          "       Display details on specific IAX peer\n";
03483       return NULL;
03484    case CLI_GENERATE:
03485       if (a->pos == 3)
03486          return complete_iax2_peers(a->line, a->word, a->pos, a->n);
03487       return NULL;
03488    }
03489 
03490    if (a->argc < 4)
03491       return CLI_SHOWUSAGE;
03492 
03493    load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03494 
03495    peer = find_peer(a->argv[3], load_realtime);
03496    if (peer) {
03497       ast_cli(a->fd, "\n\n");
03498       ast_cli(a->fd, "  * Name       : %s\n", peer->name);
03499       ast_cli(a->fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03500       ast_cli(a->fd, "  Context      : %s\n", peer->context);
03501       ast_cli(a->fd, "  Parking lot  : %s\n", peer->parkinglot);
03502       ast_cli(a->fd, "  Mailbox      : %s\n", peer->mailbox);
03503       ast_cli(a->fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
03504       ast_cli(a->fd, "  Callnum limit: %d\n", peer->maxcallno);
03505       ast_cli(a->fd, "  Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03506       ast_cli(a->fd, "  Trunk        : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
03507       ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03508       ast_cli(a->fd, "  Expire       : %d\n", peer->expire);
03509       ast_cli(a->fd, "  ACL          : %s\n", (peer->ha ? "Yes" : "No"));
03510       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));
03511       ast_cli(a->fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03512       ast_cli(a->fd, "  Username     : %s\n", peer->username);
03513       ast_cli(a->fd, "  Codecs       : ");
03514       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03515       ast_cli(a->fd, "%s\n", codec_buf);
03516 
03517       ast_cli(a->fd, "  Codec Order  : (");
03518       for(x = 0; x < 32 ; x++) {
03519          codec = ast_codec_pref_index(&peer->prefs,x);
03520          if(!codec)
03521             break;
03522          ast_cli(a->fd, "%s", ast_getformatname(codec));
03523          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03524             ast_cli(a->fd, "|");
03525       }
03526 
03527       if (!x)
03528          ast_cli(a->fd, "none");
03529       ast_cli(a->fd, ")\n");
03530 
03531       ast_cli(a->fd, "  Status       : ");
03532       peer_status(peer, status, sizeof(status));   
03533       ast_cli(a->fd, "%s\n",status);
03534       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");
03535       ast_cli(a->fd, "\n");
03536       peer_unref(peer);
03537    } else {
03538       ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03539       ast_cli(a->fd, "\n");
03540    }
03541 
03542    return CLI_SUCCESS;
03543 }

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

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

06484 {
06485    switch (cmd) {
06486    case CLI_INIT:
06487       e->command = "iax2 show peers";
06488       e->usage =
06489          "Usage: iax2 show peers [registered] [like <pattern>]\n"
06490          "       Lists all known IAX2 peers.\n"
06491          "       Optional 'registered' argument lists only peers with known addresses.\n"
06492          "       Optional regular expression pattern is used to filter the peer list.\n";
06493       return NULL;
06494    case CLI_GENERATE:
06495       return NULL;
06496    }
06497 
06498    switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) {
06499    case RESULT_SHOWUSAGE:
06500       return CLI_SHOWUSAGE;
06501    case RESULT_FAILURE:
06502       return CLI_FAILURE;
06503    default:
06504       return CLI_SUCCESS;
06505    }
06506 }

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

Definition at line 6624 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, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_registry::dnsmgr, iax2_registry::entry, ast_cli_args::fd, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), iax2_registry::us, ast_cli_entry::usage, and iax2_registry::username.

06625 {
06626 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
06627 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
06628    struct iax2_registry *reg = NULL;
06629    char host[80];
06630    char perceived[80];
06631    int counter = 0;
06632 
06633    switch (cmd) {
06634    case CLI_INIT:
06635       e->command = "iax2 show registry";
06636       e->usage =
06637          "Usage: iax2 show registry\n"
06638          "       Lists all registration requests and status.\n";
06639       return NULL;
06640    case CLI_GENERATE:
06641       return NULL;
06642    }
06643    if (a->argc != 3)
06644       return CLI_SHOWUSAGE;
06645    ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
06646    AST_LIST_LOCK(&registrations);
06647    AST_LIST_TRAVERSE(&registrations, reg, entry) {
06648       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
06649       if (reg->us.sin_addr.s_addr) 
06650          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06651       else
06652          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
06653       ast_cli(a->fd, FORMAT, host, 
06654                (reg->dnsmgr) ? "Y" : "N", 
06655                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
06656       counter++;
06657    }
06658    AST_LIST_UNLOCK(&registrations);
06659    ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
06660    return CLI_SUCCESS;
06661 #undef FORMAT
06662 #undef FORMAT2
06663 }

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

Definition at line 3567 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, iax_frame::final, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iax2_trunk_peer::list, iax_frame::retries, and ast_cli_entry::usage.

03568 {
03569    struct iax_frame *cur;
03570    int cnt = 0, dead = 0, final = 0;
03571 
03572    switch (cmd) {
03573    case CLI_INIT:
03574       e->command = "iax2 show stats";
03575       e->usage =
03576          "Usage: iax2 show stats\n"
03577          "       Display statistics on IAX channel driver.\n";
03578       return NULL;
03579    case CLI_GENERATE:
03580       return NULL;
03581    }
03582 
03583    if (a->argc != 3)
03584       return CLI_SHOWUSAGE;
03585 
03586    AST_LIST_LOCK(&frame_queue);
03587    AST_LIST_TRAVERSE(&frame_queue, cur, list) {
03588       if (cur->retries < 0)
03589          dead++;
03590       if (cur->final)
03591          final++;
03592       cnt++;
03593    }
03594    AST_LIST_UNLOCK(&frame_queue);
03595 
03596    ast_cli(a->fd, "    IAX Statistics\n");
03597    ast_cli(a->fd, "---------------------\n");
03598    ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03599    ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03600       trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03601    ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03602 
03603    trunk_timed = trunk_untimed = 0;
03604    if (trunk_maxmtu > trunk_nmaxmtu)
03605       trunk_nmaxmtu = trunk_maxmtu;
03606 
03607    return CLI_SUCCESS;
03608 }

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

Definition at line 6346 of file chan_iax2.c.

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

06347 {
06348    struct iax2_thread *thread = NULL;
06349    time_t t;
06350    int threadcount = 0, dynamiccount = 0;
06351    char type;
06352 
06353    switch (cmd) {
06354    case CLI_INIT:
06355       e->command = "iax2 show threads";
06356       e->usage =
06357          "Usage: iax2 show threads\n"
06358          "       Lists status of IAX helper threads\n";
06359       return NULL;
06360    case CLI_GENERATE:
06361       return NULL;
06362    }
06363    if (a->argc != 3)
06364       return CLI_SHOWUSAGE;
06365       
06366    ast_cli(a->fd, "IAX2 Thread Information\n");
06367    time(&t);
06368    ast_cli(a->fd, "Idle Threads:\n");
06369    AST_LIST_LOCK(&idle_list);
06370    AST_LIST_TRAVERSE(&idle_list, thread, list) {
06371 #ifdef DEBUG_SCHED_MULTITHREAD
06372       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 
06373          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06374 #else
06375       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
06376          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06377 #endif
06378       threadcount++;
06379    }
06380    AST_LIST_UNLOCK(&idle_list);
06381    ast_cli(a->fd, "Active Threads:\n");
06382    AST_LIST_LOCK(&active_list);
06383    AST_LIST_TRAVERSE(&active_list, thread, list) {
06384       if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06385          type = 'D';
06386       else
06387          type = 'P';
06388 #ifdef DEBUG_SCHED_MULTITHREAD
06389       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 
06390          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06391 #else
06392       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
06393          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06394 #endif
06395       threadcount++;
06396    }
06397    AST_LIST_UNLOCK(&active_list);
06398    ast_cli(a->fd, "Dynamic Threads:\n");
06399    AST_LIST_LOCK(&dynamic_list);
06400    AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06401 #ifdef DEBUG_SCHED_MULTITHREAD
06402       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06403          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06404 #else
06405       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06406          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06407 #endif
06408       dynamiccount++;
06409    }
06410    AST_LIST_UNLOCK(&dynamic_list);
06411    ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06412    return CLI_SUCCESS;
06413 }

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

Definition at line 6143 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_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, DEFAULT_CONTEXT, ast_cli_args::fd, FORMAT, FORMAT2, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, ast_cli_entry::usage, user, user_unref(), and users.

06144 {
06145    regex_t regexbuf;
06146    int havepattern = 0;
06147 
06148 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
06149 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
06150 
06151    struct iax2_user *user = NULL;
06152    char auth[90];
06153    char *pstr = "";
06154    struct ao2_iterator i;
06155 
06156    switch (cmd) {
06157    case CLI_INIT:
06158       e->command = "iax2 show users [like]";
06159       e->usage =
06160          "Usage: iax2 show users [like <pattern>]\n"
06161          "       Lists all known IAX2 users.\n"
06162          "       Optional regular expression pattern is used to filter the user list.\n";
06163       return NULL;
06164    case CLI_GENERATE:
06165       return NULL;
06166    }
06167 
06168    switch (a->argc) {
06169    case 5:
06170       if (!strcasecmp(a->argv[3], "like")) {
06171          if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06172             return CLI_SHOWUSAGE;
06173          havepattern = 1;
06174       } else
06175          return CLI_SHOWUSAGE;
06176    case 3:
06177       break;
06178    default:
06179       return CLI_SHOWUSAGE;
06180    }
06181 
06182    ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06183    i = ao2_iterator_init(users, 0);
06184    for (user = ao2_iterator_next(&i); user; 
06185       user_unref(user), user = ao2_iterator_next(&i)) {
06186       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
06187          continue;
06188       
06189       if (!ast_strlen_zero(user->secret)) {
06190          ast_copy_string(auth,user->secret, sizeof(auth));
06191       } else if (!ast_strlen_zero(user->inkeys)) {
06192          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06193       } else
06194          ast_copy_string(auth, "-no secret-", sizeof(auth));
06195       
06196       if(ast_test_flag(user,IAX_CODEC_NOCAP))
06197          pstr = "REQ Only";
06198       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
06199          pstr = "Disabled";
06200       else
06201          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06202       
06203       ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 
06204          user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06205          user->ha ? "Yes" : "No", pstr);
06206    }
06207    ao2_iterator_destroy(&i);
06208 
06209    if (havepattern)
06210       regfree(&regexbuf);
06211 
06212    return CLI_SUCCESS;
06213 #undef FORMAT
06214 #undef FORMAT2
06215 }

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

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

03356 {
03357    switch (cmd) {
03358    case CLI_INIT:
03359       e->command = "iax2 test losspct";
03360       e->usage =
03361          "Usage: iax2 test losspct <percentage>\n"
03362          "       For testing, throws away <percentage> percent of incoming packets\n";
03363       return NULL;
03364    case CLI_GENERATE:
03365       return NULL;
03366    }
03367    if (a->argc != 4)
03368       return CLI_SHOWUSAGE;
03369 
03370    test_losspct = atoi(a->argv[3]);
03371 
03372    return CLI_SUCCESS;
03373 }

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

Definition at line 6415 of file chan_iax2.c.

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

06416 {
06417    struct iax2_peer *p;
06418 
06419    switch (cmd) {
06420    case CLI_INIT:
06421       e->command = "iax2 unregister";
06422       e->usage =
06423          "Usage: iax2 unregister <peername>\n"
06424          "       Unregister (force expiration) an IAX2 peer from the registry.\n";
06425       return NULL;
06426    case CLI_GENERATE:
06427       return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06428    }
06429 
06430    if (a->argc != 3)
06431       return CLI_SHOWUSAGE;
06432 
06433    p = find_peer(a->argv[2], 1);
06434    if (p) {
06435       if (p->expire > 0) {
06436          struct iax2_peer tmp_peer = {
06437             .name = a->argv[2],
06438          };
06439          struct iax2_peer *peer;
06440 
06441          peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06442          if (peer) {
06443             expire_registry(peer_ref(peer)); /* will release its own reference when done */
06444             peer_unref(peer); /* ref from ao2_find() */
06445             ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06446          } else {
06447             ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06448          }
06449       } else {
06450          ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06451       }
06452    } else {
06453       ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06454    }
06455    return CLI_SUCCESS;
06456 }

static void handle_deferred_full_frames ( struct iax2_thread thread  )  [static]

Handle any deferred full frames for this thread.

Definition at line 8958 of file chan_iax2.c.

References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), iax2_pkt_buf::buf, iax2_pkt_buf::entry, iax2_pkt_buf::len, socket_process(), and thread.

08959 {
08960    struct iax2_pkt_buf *pkt_buf;
08961 
08962    ast_mutex_lock(&thread->lock);
08963 
08964    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
08965       ast_mutex_unlock(&thread->lock);
08966 
08967       thread->buf = pkt_buf->buf;
08968       thread->buf_len = pkt_buf->len;
08969       thread->buf_size = pkt_buf->len + 1;
08970       
08971       socket_process(thread);
08972 
08973       thread->buf = NULL;
08974       ast_free(pkt_buf);
08975 
08976       ast_mutex_lock(&thread->lock);
08977    }
08978 
08979    ast_mutex_unlock(&thread->lock);
08980 }

static int handle_error ( void   )  [static]

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

03024 {
03025    /* XXX Ideally we should figure out why an error occurred and then abort those
03026       rather than continuing to try.  Unfortunately, the published interface does
03027       not seem to work XXX */
03028 #if 0
03029    struct sockaddr_in *sin;
03030    int res;
03031    struct msghdr m;
03032    struct sock_extended_err e;
03033    m.msg_name = NULL;
03034    m.msg_namelen = 0;
03035    m.msg_iov = NULL;
03036    m.msg_control = &e;
03037    m.msg_controllen = sizeof(e);
03038    m.msg_flags = 0;
03039    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03040    if (res < 0)
03041       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03042    else {
03043       if (m.msg_controllen) {
03044          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03045          if (sin) 
03046             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03047          else
03048             ast_log(LOG_WARNING, "No address detected??\n");
03049       } else {
03050          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03051       }
03052    }
03053 #endif
03054    return 0;
03055 }

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

Acknowledgment received for OUR registration.

Definition at line 7925 of file chan_iax2.c.

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

Referenced by socket_process().

07926 {
07927    struct iax2_registry *reg;
07928    /* Start pessimistic */
07929    char peer[256] = "";
07930    char msgstatus[60];
07931    int refresh = 60;
07932    char ourip[256] = "<Unspecified>";
07933    struct sockaddr_in oldus;
07934    struct sockaddr_in us;
07935    int oldmsgs;
07936 
07937    memset(&us, 0, sizeof(us));
07938    if (ies->apparent_addr)
07939       memmove(&us, ies->apparent_addr, sizeof(us));
07940    if (ies->username)
07941       ast_copy_string(peer, ies->username, sizeof(peer));
07942    if (ies->refresh)
07943       refresh = ies->refresh;
07944    if (ies->calling_number) {
07945       /* We don't do anything with it really, but maybe we should */
07946    }
07947    reg = iaxs[callno]->reg;
07948    if (!reg) {
07949       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
07950       return -1;
07951    }
07952    memcpy(&oldus, &reg->us, sizeof(oldus));
07953    oldmsgs = reg->messages;
07954    if (inaddrcmp(&reg->addr, sin)) {
07955       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07956       return -1;
07957    }
07958    memcpy(&reg->us, &us, sizeof(reg->us));
07959    if (ies->msgcount >= 0)
07960       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
07961    /* always refresh the registration at the interval requested by the server
07962       we are registering to
07963    */
07964    reg->refresh = refresh;
07965    reg->expire = iax2_sched_replace(reg->expire, sched, 
07966       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07967    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
07968          if (reg->messages > 255)
07969             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
07970          else if (reg->messages > 1)
07971             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
07972          else if (reg->messages > 0)
07973             ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
07974          else
07975             ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
07976          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07977       ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
07978       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
07979    }
07980    reg->regstate = REG_STATE_REGISTERED;
07981    return 0;
07982 }

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

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

02463 {
02464    if (frametype != AST_FRAME_IAX) {
02465       return 0;
02466    }
02467    switch (subclass) {
02468    case IAX_COMMAND_NEW:
02469    case IAX_COMMAND_REGREQ:
02470    case IAX_COMMAND_FWDOWNL:
02471    case IAX_COMMAND_REGREL:
02472       return 1;
02473    case IAX_COMMAND_POKE:
02474       if (!inbound) {
02475          return 1;
02476       }
02477       break;
02478    }
02479    return 0;
02480 }

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

References chan_iax2_pvt::callno, EVENT_FLAG_SYSTEM, manager_event, ast_channel::name, chan_iax2_pvt::owner, chan_iax2_pvt::peer, and chan_iax2_pvt::peercallno.

Referenced by ast_iax2_new(), and iax2_answer().

01110 {
01111    manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01112       "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01113       pvt->owner ? pvt->owner->name : "",
01114       pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01115 }

static int iax2_answer ( struct ast_channel c  )  [static]

Definition at line 5218 of file chan_iax2.c.

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

05219 {
05220    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05221    ast_debug(1, "Answering IAX2 call\n");
05222    ast_mutex_lock(&iaxsl[callno]);
05223    if (iaxs[callno])
05224       iax2_ami_channelupdate(iaxs[callno]);
05225    ast_mutex_unlock(&iaxsl[callno]);
05226    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05227 }

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

Definition at line 7984 of file chan_iax2.c.

References ast_calloc, ast_copy_string(), ast_dnsmgr_lookup(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, iax2_registry::entry, IAX_DEFAULT_PORTNO, and IAX_DEFAULT_REG_EXPIRE.

Referenced by iax2_register().

07986 {
07987    struct iax2_registry *reg;
07988 
07989    if (!(reg = ast_calloc(1, sizeof(*reg))))
07990       return -1;
07991 
07992    if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
07993       ast_free(reg);
07994       return -1;
07995    }
07996 
07997    ast_copy_string(reg->username, username, sizeof(reg->username));
07998 
07999    if (secret)
08000       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08001 
08002    reg->expire = -1;
08003    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08004    reg->addr.sin_family = AF_INET;
08005    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
08006 
08007    AST_LIST_LOCK(&registrations);
08008    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
08009    AST_LIST_UNLOCK(&registrations);
08010    
08011    return 0;
08012 }

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

References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, ast_mutex_lock(), ast_mutex_unlock(), ast_verb, chan_iax2_pvt::bridgecallno, f, iax2_tech, iaxs, lock_both(), PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, and unlock_both().

05064 {
05065    struct ast_channel *cs[3];
05066    struct ast_channel *who, *other;
05067    int to = -1;
05068    int res = -1;
05069    int transferstarted=0;
05070    struct ast_frame *f;
05071    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05072    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05073    struct timeval waittimer = {0, 0};
05074 
05075    /* We currently do not support native bridging if a timeoutms value has been provided */
05076    if (timeoutms > 0) {
05077       return AST_BRIDGE_FAILED;
05078    }
05079 
05080    timeoutms = -1;
05081 
05082    lock_both(callno0, callno1);
05083    if (!iaxs[callno0] || !iaxs[callno1]) {
05084       unlock_both(callno0, callno1);
05085       return AST_BRIDGE_FAILED;
05086    }
05087    /* Put them in native bridge mode */
05088    if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05089       iaxs[callno0]->bridgecallno = callno1;
05090       iaxs[callno1]->bridgecallno = callno0;
05091    }
05092    unlock_both(callno0, callno1);
05093 
05094    /* If not, try to bridge until we can execute a transfer, if we can */
05095    cs[0] = c0;
05096    cs[1] = c1;
05097    for (/* ever */;;) {
05098       /* Check in case we got masqueraded into */
05099       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05100          ast_verb(3, "Can't masquerade, we're different...\n");
05101          /* Remove from native mode */
05102          if (c0->tech == &iax2_tech) {
05103             ast_mutex_lock(&iaxsl[callno0]);
05104             iaxs[callno0]->bridgecallno = 0;
05105             ast_mutex_unlock(&iaxsl[callno0]);
05106          }
05107          if (c1->tech == &iax2_tech) {
05108             ast_mutex_lock(&iaxsl[callno1]);
05109             iaxs[callno1]->bridgecallno = 0;
05110             ast_mutex_unlock(&iaxsl[callno1]);
05111          }
05112          return AST_BRIDGE_FAILED_NOWARN;
05113       }
05114       if (c0->nativeformats != c1->nativeformats) {
05115             char buf0[255];
05116             char buf1[255];
05117             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
05118             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
05119          ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
05120          /* Remove from native mode */
05121          lock_both(callno0, callno1);
05122          if (iaxs[callno0])
05123             iaxs[callno0]->bridgecallno = 0;
05124          if (iaxs[callno1])
05125             iaxs[callno1]->bridgecallno = 0;
05126          unlock_both(callno0, callno1);
05127          return AST_BRIDGE_FAILED_NOWARN;
05128       }
05129       /* check if transfered and if we really want native bridging */
05130       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
05131          /* Try the transfer */
05132          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05133                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
05134             ast_log(LOG_WARNING, "Unable to start the transfer\n");
05135          transferstarted = 1;
05136       }
05137       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05138          /* Call has been transferred.  We're no longer involved */
05139          struct timeval now = ast_tvnow();
05140          if (ast_tvzero(waittimer)) {
05141             waittimer = now;
05142          } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05143             c0->_softhangup |= AST_SOFTHANGUP_DEV;
05144             c1->_softhangup |= AST_SOFTHANGUP_DEV;
05145             *fo = NULL;
05146             *rc = c0;
05147             res = AST_BRIDGE_COMPLETE;
05148             break;
05149          }
05150       }
05151       to = 1000;
05152       who = ast_waitfor_n(cs, 2, &to);
05153       if (timeoutms > -1) {
05154          timeoutms -= (1000 - to);
05155          if (timeoutms < 0)
05156             timeoutms = 0;
05157       }
05158       if (!who) {
05159          if (!timeoutms) {
05160             res = AST_BRIDGE_RETRY;
05161             break;
05162          }
05163          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05164             res = AST_BRIDGE_FAILED;
05165             break;
05166          }
05167          continue;
05168       }
05169       f = ast_read(who);
05170       if (!f) {
05171          *fo = NULL;
05172          *rc = who;
05173          res = AST_BRIDGE_COMPLETE;
05174          break;
05175       }
05176       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
05177          *fo = f;
05178          *rc = who;
05179          res =  AST_BRIDGE_COMPLETE;
05180          break;
05181       }
05182       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
05183       if ((f->frametype == AST_FRAME_VOICE) ||
05184          (f->frametype == AST_FRAME_TEXT) ||
05185          (f->frametype == AST_FRAME_VIDEO) || 
05186          (f->frametype == AST_FRAME_IMAGE) ||
05187          (f->frametype == AST_FRAME_DTMF) ||
05188          (f->frametype == AST_FRAME_CONTROL)) {
05189          /* monitored dtmf take out of the bridge.
05190           * check if we monitor the specific source.
05191           */
05192          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05193          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05194             *rc = who;
05195             *fo = f;
05196             res = AST_BRIDGE_COMPLETE;
05197             /* Remove from native mode */
05198             break;
05199          }
05200          /* everything else goes to the other side */
05201          ast_write(other, f);
05202       }
05203       ast_frfree(f);
05204       /* Swap who gets priority */
05205       cs[2] = cs[0];
05206       cs[0] = cs[1];
05207       cs[1] = cs[2];
05208    }
05209    lock_both(callno0, callno1);
05210    if(iaxs[callno0])
05211       iaxs[callno0]->bridgecallno = 0;
05212    if(iaxs[callno1])
05213       iaxs[callno1]->bridgecallno = 0;
05214    unlock_both(callno0, callno1);
05215    return res;
05216 }

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

Definition at line 4674 of file chan_iax2.c.

References ast_channel::_state, add_empty_calltoken_ie(), chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel_datastore_find(), ast_copy_string(), ast_debug, AST_FRAME_IAX, AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_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_flag, ast_var_name(), ast_var_value(), auto_congest(), CALLNO_TO_PTR, capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, context, ast_channel::context, create_addr(), ast_datastore::data, chan_iax2_pvt::encmethods, iax2_datetime(), iax2_sched_add(), iax2_variable_datastore_info, IAX_COMMAND_NEW, 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_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_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_LANGUAGE, IAX_IE_OSPTOKEN, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VARIABLE, IAX_IE_VERSION, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPTOKEN_SIZE, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, chan_iax2_pvt::initid, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, chan_iax2_pvt::mohinterpret, chan_iax2_pvt::mohsuggest, ast_channel::name, ast_channel::nativeformats, parse_dial_string(), pbx_builtin_getvar_helper(), chan_iax2_pvt::pingtime, PTR_TO_CALLNO, sched, secret, send_command(), chan_iax2_pvt::sockfd, ast_channel::tech_pvt, chan_iax2_pvt::username, and var.

04675 {
04676    struct sockaddr_in sin;
04677    char *l=NULL, *n=NULL, *tmpstr;
04678    struct iax_ie_data ied;
04679    char *defaultrdest = "s";
04680    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04681    struct parsed_dial_string pds;
04682    struct create_addr_info cai;
04683    struct ast_var_t *var;
04684    struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
04685    const char* osp_token_ptr;
04686    unsigned int osp_token_length;
04687    unsigned char osp_block_index;
04688    unsigned int osp_block_length;
04689    unsigned char osp_buffer[256];
04690 
04691    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
04692       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
04693       return -1;
04694    }
04695 
04696    memset(&cai, 0, sizeof(cai));
04697    cai.encmethods = iax2_encryption;
04698 
04699    memset(&pds, 0, sizeof(pds));
04700    tmpstr = ast_strdupa(dest);
04701    parse_dial_string(tmpstr, &pds);
04702 
04703    if (ast_strlen_zero(pds.peer)) {
04704       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
04705       return -1;
04706    }
04707 
04708    if (!pds.exten) {
04709       pds.exten = defaultrdest;
04710    }
04711 
04712    if (create_addr(pds.peer, c, &sin, &cai)) {
04713       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
04714       return -1;
04715    }
04716 
04717    if (!pds.username && !ast_strlen_zero(cai.username))
04718       pds.username = cai.username;
04719    if (!pds.password && !ast_strlen_zero(cai.secret))
04720       pds.password = cai.secret;
04721    if (!pds.key && !ast_strlen_zero(cai.outkey))
04722       pds.key = cai.outkey;
04723    if (!pds.context && !ast_strlen_zero(cai.peercontext))
04724       pds.context = cai.peercontext;
04725 
04726    /* Keep track of the context for outgoing calls too */
04727    ast_copy_string(c->context, cai.context, sizeof(c->context));
04728 
04729    if (pds.port)
04730       sin.sin_port = htons(atoi(pds.port));
04731 
04732    l = c->cid.cid_num;
04733    n = c->cid.cid_name;
04734 
04735    /* Now build request */ 
04736    memset(&ied, 0, sizeof(ied));
04737 
04738    /* On new call, first IE MUST be IAX version of caller */
04739    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
04740    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
04741    if (pds.options && strchr(pds.options, 'a')) {
04742       /* Request auto answer */
04743       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
04744    }
04745 
04746    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
04747 
04748    if (l) {
04749       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
04750       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04751    } else {
04752       if (n)
04753          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04754       else
04755          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
04756    }
04757 
04758    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
04759    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
04760 
04761    if (n)
04762       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
04763    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
04764       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
04765 
04766    if (!ast_strlen_zero(c->language))
04767       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
04768    if (!ast_strlen_zero(c->cid.cid_dnid))
04769       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
04770    if (!ast_strlen_zero(c->cid.cid_rdnis))
04771       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
04772 
04773    if (pds.context)
04774       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
04775 
04776    if (pds.username)
04777       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
04778 
04779    if (cai.encmethods)
04780       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
04781 
04782    ast_mutex_lock(&iaxsl[callno]);
04783 
04784    if (!ast_strlen_zero(c->context))
04785       ast_string_field_set(iaxs[callno], context, c->context);
04786 
04787    if (pds.username)
04788       ast_string_field_set(iaxs[callno], username, pds.username);
04789 
04790    iaxs[callno]->encmethods = cai.encmethods;
04791 
04792    iaxs[callno]->adsi = cai.adsi;
04793    
04794    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
04795    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
04796 
04797    if (pds.key)
04798       ast_string_field_set(iaxs[callno], outkey, pds.key);
04799    if (pds.password)
04800       ast_string_field_set(iaxs[callno], secret, pds.password);
04801 
04802    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
04803    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
04804    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
04805    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
04806 
04807    if (iaxs[callno]->maxtime) {
04808       /* Initialize pingtime and auto-congest time */
04809       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
04810       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
04811    } else if (autokill) {
04812       iaxs[callno]->pingtime = autokill / 2;
04813       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
04814    }
04815 
04816    /* Check if there is an OSP token */
04817    osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
04818    if (!ast_strlen_zero(osp_token_ptr)) {
04819       if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
04820          osp_block_index = 0;
04821          while (osp_token_length > 0) {
04822             osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
04823             osp_buffer[0] = osp_block_index;
04824             memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
04825             iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
04826             osp_block_index++;
04827             osp_token_ptr += osp_block_length;
04828             osp_token_length -= osp_block_length;
04829          } 
04830       } else
04831          ast_log(LOG_WARNING, "OSP token is too long\n");
04832    } else if (iaxdebug)
04833       ast_debug(1, "OSP token is undefined\n");
04834 
04835    /* send the command using the appropriate socket for this peer */
04836    iaxs[callno]->sockfd = cai.sockfd;
04837 
04838    /* Add remote vars */
04839    if (variablestore) {
04840       AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
04841       ast_debug(1, "Found an IAX variable store on this channel\n");
04842       AST_LIST_LOCK(variablelist);
04843       AST_LIST_TRAVERSE(variablelist, var, entries) {
04844          char tmp[256];
04845          int i;
04846          ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
04847          /* Automatically divide the value up into sized chunks */
04848          for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
04849             snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
04850             iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
04851          }
04852       }
04853       AST_LIST_UNLOCK(variablelist);
04854    }
04855 
04856    /* Transmit the string in a "NEW" request */
04857    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
04858    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
04859 
04860    ast_mutex_unlock(&iaxsl[callno]);
04861    ast_setstate(c, AST_STATE_RINGING);
04862 
04863    return 0;
04864 }

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

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

13040 {
13041    int res = 0;
13042    struct iax2_dpcache *dp = NULL;
13043 #if 0
13044    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13045 #endif
13046    if ((priority != 1) && (priority != 2))
13047       return 0;
13048 
13049    AST_LIST_LOCK(&dpcache);
13050    if ((dp = find_cache(chan, data, context, exten, priority))) {
13051       if (dp->flags & CACHE_FLAG_CANEXIST)
13052          res = 1;
13053    } else {
13054       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13055    }
13056    AST_LIST_UNLOCK(&dpcache);
13057 
13058    return res;
13059 }

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

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

04346 {
04347    struct timeval t = ast_tvnow();
04348    struct ast_tm tm;
04349    unsigned int tmp;
04350    ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04351    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
04352    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
04353    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
04354    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
04355    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
04356    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
04357    return tmp;
04358 }

static void iax2_destroy ( int  callno  )  [static]

Definition at line 3129 of file chan_iax2.c.

References ao2_ref, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_queue_hangup(), DEADLOCK_AVOIDANCE, iax2_destroy_helper(), iaxs, 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().

03130 {
03131    struct chan_iax2_pvt *pvt = NULL;
03132    struct ast_channel *owner = NULL;
03133 
03134 retry:
03135    if ((pvt = iaxs[callno])) {
03136       iax2_destroy_helper(pvt);
03137    }
03138 
03139    owner = pvt ? pvt->owner : NULL;
03140 
03141    if (owner) {
03142       if (ast_channel_trylock(owner)) {
03143          ast_debug(3, "Avoiding IAX destroy deadlock\n");
03144          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03145          goto retry;
03146       }
03147    }
03148 
03149    if (!owner) {
03150       iaxs[callno] = NULL;
03151    }
03152 
03153    if (pvt) {
03154       if (!owner) {
03155          pvt->owner = NULL;
03156       } else {
03157          /* If there's an owner, prod it to give up */
03158          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
03159           * because we already hold the owner channel lock. */
03160          ast_queue_hangup(owner);
03161       }
03162 
03163       if (pvt->peercallno) {
03164          remove_by_peercallno(pvt);
03165       }
03166 
03167       if (pvt->transfercallno) {
03168          remove_by_transfercallno(pvt);
03169       }
03170 
03171       if (!owner) {
03172          ao2_ref(pvt, -1);
03173          pvt = NULL;
03174       }
03175    }
03176 
03177    if (owner) {
03178       ast_channel_unlock(owner);
03179    }
03180 
03181    if (callno & 0x4000) {
03182       update_max_trunk();
03183    }
03184 }

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

References ao2_find, ast_atomic_fetchadd_int(), ast_clear_flag, AST_SCHED_DEL, AST_SCHED_DEL_SPINLOCK, ast_test_flag, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::callno, IAX_MAXAUTHREQ, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, iax2_user::name, OBJ_POINTER, chan_iax2_pvt::pingid, sched, user, user_unref(), chan_iax2_pvt::username, and users.

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

01529 {
01530    /* Decrement AUTHREQ count if needed */
01531    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01532       struct iax2_user *user;
01533       struct iax2_user tmp_user = {
01534          .name = pvt->username,
01535       };
01536 
01537       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01538       if (user) {
01539          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01540          user_unref(user); 
01541       }
01542 
01543       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01544    }
01545    /* No more pings or lagrq's */
01546    AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]);
01547    AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]);
01548    AST_SCHED_DEL(sched, pvt->autoid);
01549    AST_SCHED_DEL(sched, pvt->authid);
01550    AST_SCHED_DEL(sched, pvt->initid);
01551    AST_SCHED_DEL(sched, pvt->jbid);
01552    AST_SCHED_DEL(sched, pvt->keyrotateid);
01553 }

static int iax2_devicestate ( void *  data  )  [static]

Part of the device state notification system ---.

Definition at line 13258 of file chan_iax2.c.

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

13259 {
13260    struct parsed_dial_string pds;
13261    char *tmp = ast_strdupa(data);
13262    struct iax2_peer *p;
13263    int res = AST_DEVICE_INVALID;
13264 
13265    memset(&pds, 0, sizeof(pds));
13266    parse_dial_string(tmp, &pds);
13267 
13268    if (ast_strlen_zero(pds.peer)) {
13269       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13270       return res;
13271    }
13272    
13273    ast_debug(3, "Checking device state for device %s\n", pds.peer);
13274 
13275    /* SLD: FIXME: second call to find_peer during registration */
13276    if (!(p = find_peer(pds.peer, 1)))
13277       return res;
13278 
13279    res = AST_DEVICE_UNAVAILABLE;
13280    ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13281       pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13282    
13283    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
13284        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13285       /* Peer is registered, or have default IP address
13286          and a valid registration */
13287       if (p->historicms == 0 || p->historicms <= p->maxms)
13288          /* let the core figure out whether it is in use or not */
13289          res = AST_DEVICE_UNKNOWN;  
13290    }
13291 
13292    peer_unref(p);
13293 
13294    return res;
13295 }

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

Definition at line 3969 of file chan_iax2.c.

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

03970 {
03971    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
03972 }

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

Definition at line 3974 of file chan_iax2.c.

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

03975 {
03976    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
03977 }

static int iax2_do_register ( struct iax2_registry reg  )  [static]

Definition at line 11092 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(), iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno_locked(), iax2_destroy(), iax2_do_register_s(), iax2_sched_replace(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, LOG_WARNING, NEW_FORCE, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), and iax2_registry::username.

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

11093 {
11094    struct iax_ie_data ied;
11095    if (iaxdebug)
11096       ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11097 
11098    if (reg->dnsmgr && 
11099        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
11100       /* Maybe the IP has changed, force DNS refresh */
11101       ast_dnsmgr_refresh(reg->dnsmgr);
11102    }
11103    
11104    /*
11105     * if IP has Changed, free allocated call to create a new one with new IP
11106     * call has the pointer to IP and must be updated to the new one
11107     */
11108    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11109       int callno = reg->callno;
11110       ast_mutex_lock(&iaxsl[callno]);
11111       iax2_destroy(callno);
11112       ast_mutex_unlock(&iaxsl[callno]);
11113       reg->callno = 0;
11114    }
11115    if (!reg->addr.sin_addr.s_addr) {
11116       if (iaxdebug)
11117          ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11118       /* Setup the next registration attempt */
11119       reg->expire = iax2_sched_replace(reg->expire, sched, 
11120          (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11121       return -1;
11122    }
11123 
11124    if (!reg->callno) {
11125       ast_debug(3, "Allocate call number\n");
11126       reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
11127       if (reg->callno < 1) {
11128          ast_log(LOG_WARNING, "Unable to create call for registration\n");
11129          return -1;
11130       } else
11131          ast_debug(3, "Registration created on call %d\n", reg->callno);
11132       iaxs[reg->callno]->reg = reg;
11133       ast_mutex_unlock(&iaxsl[reg->callno]);
11134    }
11135    /* Setup the next registration a little early */
11136    reg->expire = iax2_sched_replace(reg->expire, sched, 
11137       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11138    /* Send the request */
11139    memset(&ied, 0, sizeof(ied));
11140    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11141    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11142    add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */
11143    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11144    reg->regstate = REG_STATE_REGSENT;
11145    return 0;
11146 }

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

Definition at line 7769 of file chan_iax2.c.

References __iax2_do_register_s(), and schedule_action.

Referenced by iax2_ack_registry(), and iax2_do_register().

07770 {
07771 #ifdef SCHED_MULTITHREADED
07772    if (schedule_action(__iax2_do_register_s, data))
07773 #endif      
07774       __iax2_do_register_s(data);
07775    return 0;
07776 }

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

Definition at line 8519 of file chan_iax2.c.

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

Referenced by find_cache(), and socket_process().

08520 {
08521    struct iax_ie_data ied;
08522    /* Auto-hangup with 30 seconds of inactivity */
08523    iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
08524       sched, 30000, auto_hangup, (void *)(long)callno);
08525    memset(&ied, 0, sizeof(ied));
08526    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
08527    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
08528    dp->flags |= CACHE_FLAG_TRANSMITTED;
08529 }

static void * iax2_dup_variable_datastore ( void *   )  [static]

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

01125 {
01126    AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01127    struct ast_var_t *oldvar, *newvar;
01128 
01129    newlist = ast_calloc(sizeof(*newlist), 1);
01130    if (!newlist) {
01131       ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01132       return NULL;
01133    }
01134 
01135    AST_LIST_HEAD_INIT(newlist);
01136    AST_LIST_LOCK(oldlist);
01137    AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01138       newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01139       if (newvar)
01140          AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01141       else
01142          ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01143    }
01144    AST_LIST_UNLOCK(oldlist);
01145    return newlist;
01146 }

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

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

13086 {
13087    char odata[256];
13088    char req[256];
13089    char *ncontext;
13090    struct iax2_dpcache *dp = NULL;
13091    struct ast_app *dial = NULL;
13092 #if 0
13093    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);
13094 #endif
13095    if (priority == 2) {
13096       /* Indicate status, can be overridden in dialplan */
13097       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13098       if (dialstatus) {
13099          dial = pbx_findapp(dialstatus);
13100          if (dial) 
13101             pbx_exec(chan, dial, "");
13102       }
13103       return -1;
13104    } else if (priority != 1)
13105       return -1;
13106 
13107    AST_LIST_LOCK(&dpcache);
13108    if ((dp = find_cache(chan, data, context, exten, priority))) {
13109       if (dp->flags & CACHE_FLAG_EXISTS) {
13110          ast_copy_string(odata, data, sizeof(odata));
13111          ncontext = strchr(odata, '/');
13112          if (ncontext) {
13113             *ncontext = '\0';
13114             ncontext++;
13115             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13116          } else {
13117             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13118          }
13119          ast_verb(3, "Executing Dial('%s')\n", req);
13120       } else {
13121          AST_LIST_UNLOCK(&dpcache);
13122          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13123          return -1;
13124       }
13125    }
13126    AST_LIST_UNLOCK(&dpcache);
13127 
13128    if ((dial = pbx_findapp("Dial")))
13129       return pbx_exec(chan, dial, req);
13130    else
13131       ast_log(LOG_WARNING, "No dial application registered\n");
13132 
13133    return -1;
13134 }

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

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

13017 {
13018    int res = 0;
13019    struct iax2_dpcache *dp = NULL;
13020 #if 0
13021    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13022 #endif
13023    if ((priority != 1) && (priority != 2))
13024       return 0;
13025 
13026    AST_LIST_LOCK(&dpcache);
13027    if ((dp = find_cache(chan, data, context, exten, priority))) {
13028       if (dp->flags & CACHE_FLAG_EXISTS)
13029          res = 1;
13030    } else {
13031       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13032    }
13033    AST_LIST_UNLOCK(&dpcache);
13034 
13035    return res;
13036 }

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

Definition at line 3996 of file chan_iax2.c.

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

03997 {
03998    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
03999    ast_mutex_lock(&iaxsl[callno]);
04000    if (iaxs[callno])
04001       iaxs[callno]->owner = newchan;
04002    else
04003       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04004    ast_mutex_unlock(&iaxsl[callno]);
04005    return 0;
04006 }

static void iax2_frame_free ( struct iax_frame fr  )  [static]

Definition at line 1555 of file chan_iax2.c.

References AST_SCHED_DEL, iax_frame_free(), iax_frame::retrans, and sched.

Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), resend_with_token(), and schedule_delivery().

01556 {
01557    AST_SCHED_DEL(sched, fr->retrans);
01558    iax_frame_free(fr);
01559 }

static void iax2_free_variable_datastore ( void *   )  [static]

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

01149 {
01150    AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01151    struct ast_var_t *oldvar;
01152 
01153    AST_LIST_LOCK(oldlist);
01154    while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01155       ast_free(oldvar);
01156    }
01157    AST_LIST_UNLOCK(oldlist);
01158    AST_LIST_HEAD_DESTROY(oldlist);
01159    ast_free(oldlist);
01160 }

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

Definition at line 1495 of file chan_iax2.c.

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

Referenced by __find_callno().

01496 {
01497    struct iax2_peer *peer = NULL;
01498    int res = 0;
01499    struct ao2_iterator i;
01500 
01501    i = ao2_iterator_init(peers, 0);
01502    while ((peer = ao2_iterator_next(&i))) {
01503       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01504           (peer->addr.sin_port == sin.sin_port)) {
01505          ast_copy_string(host, peer->name, len);
01506          peer_unref(peer);
01507          res = 1;
01508          break;
01509       }
01510       peer_unref(peer);
01511    }
01512    ao2_iterator_destroy(&i);
01513 
01514    if (!peer) {
01515       peer = realtime_peer(NULL, &sin);
01516       if (peer) {
01517          ast_copy_string(host, peer->name, len);
01518          peer_unref(peer);
01519          res = 1;
01520       }
01521    }
01522 
01523    return res;
01524 }

static int iax2_getpeertrunk ( struct sockaddr_in  sin  )  [static]

Definition at line 5286 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_test_flag, IAX_TRUNK, peer_unref(), and peers.

Referenced by check_access().

05287 {
05288    struct iax2_peer *peer;
05289    int res = 0;
05290    struct ao2_iterator i;
05291 
05292    i = ao2_iterator_init(peers, 0);
05293    while ((peer = ao2_iterator_next(&i))) {
05294       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05295           (peer->addr.sin_port == sin.sin_port)) {
05296          res = ast_test_flag(peer, IAX_TRUNK);
05297          peer_unref(peer);
05298          break;
05299       }
05300       peer_unref(peer);
05301    }
05302    ao2_iterator_destroy(&i);
05303 
05304    return res;
05305 }

static int iax2_hangup ( struct ast_channel c  )  [static]

Definition at line 4866 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_test_flag, ast_verb, CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, LOG_ERROR, LOG_WARNING, ast_channel::name, PTR_TO_CALLNO, sched, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.

04867 {
04868    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04869    struct iax_ie_data ied;
04870    int alreadygone;
04871    memset(&ied, 0, sizeof(ied));
04872    ast_mutex_lock(&iaxsl[callno]);
04873    if (callno && iaxs[callno]) {
04874       ast_debug(1, "We're hanging up %s now...\n", c->name);
04875       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
04876       /* Send the hangup unless we have had a transmission error or are already gone */
04877       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
04878       if (!iaxs[callno]->error && !alreadygone) {
04879          if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
04880             ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
04881          }
04882          if (!iaxs[callno]) {
04883             ast_mutex_unlock(&iaxsl[callno]);
04884             return 0;
04885          }
04886       }
04887       /* Explicitly predestroy it */
04888       iax2_predestroy(callno);
04889       /* If we were already gone to begin with, destroy us now */
04890       if (iaxs[callno] && alreadygone) {
04891          ast_debug(1, "Really destroying %s now...\n", c->name);
04892          iax2_destroy(callno);
04893       } else if (iaxs[callno]) {
04894          if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
04895             ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!!  Destroying immediately.\n", callno);
04896             iax2_destroy(callno);
04897          }
04898       }
04899    } else if (c->tech_pvt) {
04900       /* If this call no longer exists, but the channel still
04901        * references it we need to set the channel's tech_pvt to null
04902        * to avoid ast_channel_free() trying to free it.
04903        */
04904       c->tech_pvt = NULL;
04905    }
04906    ast_mutex_unlock(&iaxsl[callno]);
04907    ast_verb(3, "Hungup '%s'\n", c->name);
04908    return 0;
04909 }

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

Definition at line 5229 of file chan_iax2.c.

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

05230 {
05231    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05232    struct chan_iax2_pvt *pvt;
05233    int res = 0;
05234 
05235    if (iaxdebug)
05236       ast_debug(1, "Indicating condition %d\n", condition);
05237 
05238    ast_mutex_lock(&iaxsl[callno]);
05239    pvt = iaxs[callno];
05240 
05241    if (wait_for_peercallno(pvt)) {
05242       res = -1;
05243       goto done;
05244    }
05245 
05246    switch (condition) {
05247    case AST_CONTROL_HOLD:
05248       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05249          ast_moh_start(c, data, pvt->mohinterpret);
05250          goto done;
05251       }
05252       break;
05253    case AST_CONTROL_UNHOLD:
05254       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05255          ast_moh_stop(c);
05256          goto done;
05257       }
05258    }
05259 
05260    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05261 
05262 done:
05263    ast_mutex_unlock(&iaxsl[callno]);
05264 
05265    return res;
05266 }

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

Definition at line 4981 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, md5(), MD5Final(), MD5Init(), MD5Update(), iax_ie_data::pos, sched, and send_command().

Referenced by iax2_send().

04982 {
04983    int res = 0;
04984    struct chan_iax2_pvt *pvt = (void *) vpvt;
04985    struct MD5Context md5;
04986    char key[17] = "";
04987    struct iax_ie_data ied = {
04988       .pos = 0,   
04989    };
04990    
04991    ast_mutex_lock(&iaxsl[pvt->callno]);
04992    pvt->keyrotateid = 
04993       ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
04994 
04995    snprintf(key, sizeof(key), "%lX", ast_random());
04996 
04997    MD5Init(&md5);
04998    MD5Update(&md5, (unsigned char *) key, strlen(key));
04999    MD5Final((unsigned char *) key, &md5);
05000 
05001    IAX_DEBUGDIGEST("Sending", key);
05002 
05003    iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05004 
05005    res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05006 
05007    build_ecx_key((unsigned char *) key, pvt);
05008 
05009    ast_mutex_unlock(&iaxsl[pvt->callno]);
05010 
05011    return res;
05012 }

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

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

13063 {
13064    int res = 0;
13065    struct iax2_dpcache *dp = NULL;
13066 #if 0
13067    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13068 #endif
13069    if ((priority != 1) && (priority != 2))
13070       return 0;
13071 
13072    AST_LIST_LOCK(&dpcache);
13073    if ((dp = find_cache(chan, data, context, exten, priority))) {
13074       if (dp->flags & CACHE_FLAG_MATCHMORE)
13075          res = 1;
13076    } else {
13077       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13078    }
13079    AST_LIST_UNLOCK(&dpcache);
13080 
13081    return res;
13082 }

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

Definition at line 11296 of file chan_iax2.c.

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

Referenced by iax2_poke_peer().

11297 {
11298    struct iax2_peer *peer = (struct iax2_peer *)data;
11299    peer->pokeexpire = -1;
11300 #ifdef SCHED_MULTITHREADED
11301    if (schedule_action(__iax2_poke_noanswer, data))
11302 #endif      
11303       __iax2_poke_noanswer(data);
11304    peer_unref(peer);
11305    return 0;
11306 }

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

Definition at line 11317 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(), iax_ie_data::buf, iax2_peer::callno, DEFAULT_MAXMS, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iaxs, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax_ie_data::pos, sched, send_command(), and iax2_peer::sockfd.

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

11318 {
11319    int callno;
11320    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
11321       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
11322         immediately after clearing things out */
11323       peer->lastms = 0;
11324       peer->historicms = 0;
11325       peer->pokeexpire = -1;
11326       peer->callno = 0;
11327       return 0;
11328    }
11329 
11330    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
11331    if ((callno = peer->callno) > 0) {
11332       ast_log(LOG_NOTICE, "Still have a callno...\n");
11333       ast_mutex_lock(&iaxsl[callno]);
11334       iax2_destroy(callno);
11335       ast_mutex_unlock(&iaxsl[callno]);
11336    }
11337    if (heldcall)
11338       ast_mutex_unlock(&iaxsl[heldcall]);
11339    callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
11340    if (heldcall)
11341       ast_mutex_lock(&iaxsl[heldcall]);
11342    if (peer->callno < 1) {
11343       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
11344       return -1;
11345    }
11346 
11347    /* Speed up retransmission times for this qualify call */
11348    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
11349    iaxs[peer->callno]->peerpoke = peer;
11350 
11351    if (peer->pokeexpire > -1) {
11352       if (!ast_sched_del(sched, peer->pokeexpire)) {
11353          peer->pokeexpire = -1;
11354          peer_unref(peer);
11355       }
11356    }
11357  
11358    /* Queue up a new task to handle no reply */
11359    /* If the host is already unreachable then use the unreachable interval instead */
11360    if (peer->lastms < 0)
11361       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
11362    else
11363       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
11364 
11365    if (peer->pokeexpire == -1)
11366       peer_unref(peer);
11367 
11368    /* And send the poke */
11369    ast_mutex_lock(&iaxsl[callno]);
11370    if (iaxs[callno]) {
11371       struct iax_ie_data ied = {
11372          .buf = { 0 },
11373          .pos = 0,
11374       };
11375       add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
11376       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
11377    }
11378    ast_mutex_unlock(&iaxsl[callno]);
11379 
11380    return 0;
11381 }

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

Definition at line 11308 of file chan_iax2.c.

References iax2_poke_peer().

Referenced by load_module().

11309 {
11310    struct iax2_peer *peer = obj;
11311 
11312    iax2_poke_peer(peer, 0);
11313 
11314    return 0;
11315 }

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

Definition at line 8559 of file chan_iax2.c.

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

Referenced by __iax2_poke_noanswer(), and socket_process().

08560 {
08561    struct iax2_peer *peer = (struct iax2_peer *)data;
08562    peer->pokeexpire = -1;
08563 #ifdef SCHED_MULTITHREADED
08564    if (schedule_action(__iax2_poke_peer_s, data))
08565 #endif      
08566       __iax2_poke_peer_s(data);
08567    return 0;
08568 }

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

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

Referenced by iax2_hangup(), and send_command_final().

03107 {
03108    struct ast_channel *c = NULL;
03109    struct chan_iax2_pvt *pvt = iaxs[callno];
03110 
03111    if (!pvt)
03112       return -1;
03113 
03114    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
03115       iax2_destroy_helper(pvt);
03116       ast_set_flag(pvt, IAX_ALREADYGONE); 
03117    }
03118 
03119    if ((c = pvt->owner)) {
03120       c->tech_pvt = NULL;
03121       iax2_queue_hangup(callno);
03122       pvt->owner = NULL;
03123       ast_module_unref(ast_module_info->self);
03124    }
03125 
03126    return 0;
03127 }

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

Definition at line 10963 of file chan_iax2.c.

References ast_atomic_fetchadd_int(), ast_cond_timedwait(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_tvadd(), ast_tvnow(), iax2_process_thread_cleanup(), IAX_THREAD_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), signal_condition(), and thread.

Referenced by find_idle_thread(), and start_network_thread().

10964 {
10965    struct iax2_thread *thread = data;
10966    struct timeval wait;
10967    struct timespec ts;
10968    int put_into_idle = 0;
10969    int first_time = 1;
10970 
10971    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
10972    pthread_cleanup_push(iax2_process_thread_cleanup, data);
10973    for(;;) {
10974       /* Wait for something to signal us to be awake */
10975       ast_mutex_lock(&thread->lock);
10976 
10977       /* Flag that we're ready to accept signals */
10978       if (first_time) {
10979          signal_condition(&thread->init_lock, &thread->init_cond);
10980          first_time = 0;
10981       }
10982 
10983       /* Put into idle list if applicable */
10984       if (put_into_idle)
10985          insert_idle_thread(thread);
10986 
10987       if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
10988          struct iax2_thread *t = NULL;
10989          /* Wait to be signalled or time out */
10990          wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
10991          ts.tv_sec = wait.tv_sec;
10992          ts.tv_nsec = wait.tv_usec * 1000;
10993          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
10994             /* This thread was never put back into the available dynamic
10995              * thread list, so just go away. */
10996             if (!put_into_idle) {
10997                ast_mutex_unlock(&thread->lock);
10998                break;
10999             }
11000             AST_LIST_LOCK(&dynamic_list);
11001             /* Account for the case where this thread is acquired *right* after a timeout */
11002             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11003                ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11004             AST_LIST_UNLOCK(&dynamic_list);
11005             if (t) {
11006                /* This dynamic thread timed out waiting for a task and was
11007                 * not acquired immediately after the timeout, 
11008                 * so it's time to go away. */
11009                ast_mutex_unlock(&thread->lock);
11010                break;
11011             }
11012             /* Someone grabbed our thread *right* after we timed out.
11013              * Wait for them to set us up with something to do and signal
11014              * us to continue. */
11015             wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11016             ts.tv_sec = wait.tv_sec;
11017             ts.tv_nsec = wait.tv_usec * 1000;
11018             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
11019             {
11020                ast_mutex_unlock(&thread->lock);
11021                break;
11022             }
11023          }
11024       } else {
11025          ast_cond_wait(&thread->cond, &thread->lock);
11026       }
11027 
11028       /* Go back into our respective list */
11029       put_into_idle = 1;
11030 
11031       ast_mutex_unlock(&thread->lock);
11032 
11033       if (thread->iostate == IAX_IOSTATE_IDLE)
11034          continue;
11035 
11036       /* Add ourselves to the active list now */
11037       AST_LIST_LOCK(&active_list);
11038       AST_LIST_INSERT_HEAD(&active_list, thread, list);
11039       AST_LIST_UNLOCK(&active_list);
11040 
11041       /* See what we need to do */
11042       switch(thread->iostate) {
11043       case IAX_IOSTATE_READY:
11044          thread->actions++;
11045          thread->iostate = IAX_IOSTATE_PROCESSING;
11046          socket_process(thread);
11047          handle_deferred_full_frames(thread);
11048          break;
11049       case IAX_IOSTATE_SCHEDREADY:
11050          thread->actions++;
11051          thread->iostate = IAX_IOSTATE_PROCESSING;
11052 #ifdef SCHED_MULTITHREADED
11053          thread->schedfunc(thread->scheddata);
11054 #endif      
11055       default:
11056          break;
11057       }
11058       time(&thread->checktime);
11059       thread->iostate = IAX_IOSTATE_IDLE;
11060 #ifdef DEBUG_SCHED_MULTITHREAD
11061       thread->curfunc[0]='\0';
11062 #endif      
11063 
11064       /* Now... remove ourselves from the active list, and return to the idle list */
11065       AST_LIST_LOCK(&active_list);
11066       AST_LIST_REMOVE(&active_list, thread, list);
11067       AST_LIST_UNLOCK(&active_list);
11068 
11069       /* Make sure another frame didn't sneak in there after we thought we were done. */
11070       handle_deferred_full_frames(thread);
11071    }
11072 
11073    /*!\note For some reason, idle threads are exiting without being removed
11074     * from an idle list, which is causing memory corruption.  Forcibly remove
11075     * it from the list, if it's there.
11076     */
11077    AST_LIST_LOCK(&idle_list);
11078    AST_LIST_REMOVE(&idle_list, thread, list);
11079    AST_LIST_UNLOCK(&idle_list);
11080 
11081    AST_LIST_LOCK(&dynamic_list);
11082    AST_LIST_REMOVE(&dynamic_list, thread, list);
11083    AST_LIST_UNLOCK(&dynamic_list);
11084 
11085    /* I am exiting here on my own volition, I need to clean up my own data structures
11086    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
11087    */
11088    pthread_cleanup_pop(1);
11089    return NULL;
11090 }

static void iax2_process_thread_cleanup ( void *  data  )  [static]

Definition at line 10952 of file chan_iax2.c.

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

Referenced by iax2_process_thread().

10953 {
10954    struct iax2_thread *thread = data;
10955    ast_mutex_destroy(&thread->lock);
10956    ast_cond_destroy(&thread->cond);
10957    ast_mutex_destroy(&thread->init_lock);
10958    ast_cond_destroy(&thread->init_cond);
10959    ast_free(thread);
10960    ast_atomic_dec_and_test(&iaxactivethreadcount);
10961 }

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

Definition at line 11148 of file chan_iax2.c.

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

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

11149 {
11150    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
11151       is found for template */
11152    struct iax_ie_data provdata;
11153    struct iax_ie_data ied;
11154    unsigned int sig;
11155    struct sockaddr_in sin;
11156    int callno;
11157    struct create_addr_info cai;
11158 
11159    memset(&cai, 0, sizeof(cai));
11160 
11161    ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11162 
11163    if (iax_provision_build(&provdata, &sig, template, force)) {
11164       ast_debug(1, "No provisioning found for template '%s'\n", template);
11165       return 0;
11166    }
11167 
11168    if (end) {
11169       memcpy(&sin, end, sizeof(sin));
11170       cai.sockfd = sockfd;
11171    } else if (create_addr(dest, NULL, &sin, &cai))
11172       return -1;
11173 
11174    /* Build the rest of the message */
11175    memset(&ied, 0, sizeof(ied));
11176    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11177 
11178    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11179    if (!callno)
11180       return -1;
11181 
11182    if (iaxs[callno]) {
11183       /* Schedule autodestruct in case they don't ever give us anything back */
11184       iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
11185          sched, 15000, auto_hangup, (void *)(long)callno);
11186       ast_set_flag(iaxs[callno], IAX_PROVISION);
11187       /* Got a call number now, so go ahead and send the provisioning information */
11188       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11189    }
11190    ast_mutex_unlock(&iaxsl[callno]);
11191 
11192    return 1;
11193 }

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

References ast_channel_trylock, ast_channel_unlock, ast_queue_control_data(), DEADLOCK_AVOIDANCE, iaxs, and chan_iax2_pvt::owner.

Referenced by socket_process().

02733 {
02734    for (;;) {
02735       if (iaxs[callno] && iaxs[callno]->owner) {
02736          if (ast_channel_trylock(iaxs[callno]->owner)) {
02737             /* Avoid deadlock by pausing and trying again */
02738             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02739          } else {
02740             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02741             ast_channel_unlock(iaxs[callno]->owner);
02742             break;
02743          }
02744       } else
02745          break;
02746    }
02747    return 0;
02748 }

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

References ast_channel_trylock, ast_channel_unlock, ast_queue_frame(), DEADLOCK_AVOIDANCE, f, iaxs, and chan_iax2_pvt::owner.

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

02670 {
02671    for (;;) {
02672       if (iaxs[callno] && iaxs[callno]->owner) {
02673          if (ast_channel_trylock(iaxs[callno]->owner)) {
02674             /* Avoid deadlock by pausing and trying again */
02675             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02676          } else {
02677             ast_queue_frame(iaxs[callno]->owner, f);
02678             ast_channel_unlock(iaxs[callno]->owner);
02679             break;
02680          }
02681       } else
02682          break;
02683    }
02684    return 0;
02685 }

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

References ast_channel_trylock, ast_channel_unlock, ast_queue_hangup(), DEADLOCK_AVOIDANCE, iaxs, and chan_iax2_pvt::owner.

Referenced by iax2_predestroy().

02701 {
02702    for (;;) {
02703       if (iaxs[callno] && iaxs[callno]->owner) {
02704          if (ast_channel_trylock(iaxs[callno]->owner)) {
02705             /* Avoid deadlock by pausing and trying again */
02706             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02707          } else {
02708             ast_queue_hangup(iaxs[callno]->owner);
02709             ast_channel_unlock(iaxs[callno]->owner);
02710             break;
02711          }
02712       } else
02713          break;
02714    }
02715    return 0;
02716 }

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

Definition at line 4975 of file chan_iax2.c.

References ast_log(), ast_null_frame, and LOG_NOTICE.

04976 {
04977    ast_log(LOG_NOTICE, "I should never be called!\n");
04978    return &ast_null_frame;
04979 }

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

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

08015 {
08016    char copy[256];
08017    char *username, *hostname, *secret;
08018    char *porta;
08019    char *stringp=NULL;
08020    
08021    if (!value)
08022       return -1;
08023 
08024    ast_copy_string(copy, value, sizeof(copy));
08025    stringp = copy;
08026    username = strsep(&stringp, "@");
08027    hostname = strsep(&stringp, "@");
08028 
08029    if (!hostname) {
08030       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08031       return -1;
08032    }
08033 
08034    stringp = username;
08035    username = strsep(&stringp, ":");
08036    secret = strsep(&stringp, ":");
08037    stringp = hostname;
08038    hostname = strsep(&stringp, ":");
08039    porta = strsep(&stringp, ":");
08040    
08041    if (porta && !atoi(porta)) {
08042       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08043       return -1;
08044    }
08045 
08046    return iax2_append_register(hostname, username, secret, porta);
08047 }

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

Definition at line 11393 of file chan_iax2.c.

References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_unlock(), AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_translator_best_choice(), create_addr(), find_callno_locked(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), chan_iax2_pvt::peer, ast_channel::readformat, and ast_channel::writeformat.

11394 {
11395    int callno;
11396    int res;
11397    int fmt, native;
11398    struct sockaddr_in sin;
11399    struct ast_channel *c;
11400    struct parsed_dial_string pds;
11401    struct create_addr_info cai;
11402    char *tmpstr;
11403 
11404    memset(&pds, 0, sizeof(pds));
11405    tmpstr = ast_strdupa(data);
11406    parse_dial_string(tmpstr, &pds);
11407 
11408    if (ast_strlen_zero(pds.peer)) {
11409       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
11410       return NULL;
11411    }
11412           
11413    memset(&cai, 0, sizeof(cai));
11414    cai.capability = iax2_capability;
11415 
11416    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11417    
11418    /* Populate our address from the given */
11419    if (create_addr(pds.peer, NULL, &sin, &cai)) {
11420       *cause = AST_CAUSE_UNREGISTERED;
11421       return NULL;
11422    }
11423 
11424    if (pds.port)
11425       sin.sin_port = htons(atoi(pds.port));
11426 
11427    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11428    if (callno < 1) {
11429       ast_log(LOG_WARNING, "Unable to create call\n");
11430       *cause = AST_CAUSE_CONGESTION;
11431       return NULL;
11432    }
11433 
11434    /* If this is a trunk, update it now */
11435    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11436    if (ast_test_flag(&cai, IAX_TRUNK)) {
11437       int new_callno;
11438       if ((new_callno = make_trunk(callno, 1)) != -1)
11439          callno = new_callno;
11440    }
11441    iaxs[callno]->maxtime = cai.maxtime;
11442    if (cai.found)
11443       ast_string_field_set(iaxs[callno], host, pds.peer);
11444 
11445    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
11446 
11447    ast_mutex_unlock(&iaxsl[callno]);
11448 
11449    if (c) {
11450       /* Choose a format we can live with */
11451       if (c->nativeformats & format) 
11452          c->nativeformats &= format;
11453       else {
11454          native = c->nativeformats;
11455          fmt = format;
11456          res = ast_translator_best_choice(&fmt, &native);
11457          if (res < 0) {
11458             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
11459                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
11460             ast_hangup(c);
11461             return NULL;
11462          }
11463          c->nativeformats = native;
11464       }
11465       c->readformat = ast_best_codec(c->nativeformats);
11466       c->writeformat = c->readformat;
11467    }
11468 
11469    return c;
11470 }

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

Definition at line 1281 of file chan_iax2.c.

References ast_sched_add(), sched_lock, and signal_condition().

Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), iax2_call(), iax2_poke_peer(), make_trunk(), network_thread(), reg_source_db(), sched_delay_remove(), socket_process(), and update_registry().

01282 {
01283    int res;
01284 
01285    res = ast_sched_add(con, when, callback, data);
01286    signal_condition(&sched_lock, &sched_cond);
01287 
01288    return res;
01289 }

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

Definition at line 1273 of file chan_iax2.c.

References AST_SCHED_REPLACE, sched_lock, and signal_condition().

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

01274 {
01275    AST_SCHED_REPLACE(id, con, when, callback, data);
01276    signal_condition(&sched_lock, &sched_cond);
01277 
01278    return id;
01279 }

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

References iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag, 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, ast_frame::datalen, iax_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, iax_frame::encmethods, encrypt_frame(), f, iax_frame::final, chan_iax2_pvt::first_iax_message, ast_frame::frametype, iax2_key_rotate(), iax2_transmit(), iax2_trunk_queue(), IAX_CALLENCRYPTED, IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_outputframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::last_iax_message, chan_iax2_pvt::lastsent, chan_iax2_pvt::lastvsent, LOG_NOTICE, LOG_WARNING, MARK_IAX_SUBCLASS_TX, MAX_RETRY_TIME, MIN_RETRY_TIME, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, ast_frame::ptr, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.

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

05939 {
05940    /* Queue a packet for delivery on a given private structure.  Use "ts" for
05941       timestamp, or calculate if ts is 0.  Send immediately without retransmission
05942       or delayed, with retransmission */
05943    struct ast_iax2_full_hdr *fh;
05944    struct ast_iax2_mini_hdr *mh;
05945    struct ast_iax2_video_hdr *vh;
05946    struct {
05947       struct iax_frame fr2;
05948       unsigned char buffer[4096];
05949    } frb;
05950    struct iax_frame *fr;
05951    int res;
05952    int sendmini=0;
05953    unsigned int lastsent;
05954    unsigned int fts;
05955 
05956    frb.fr2.afdatalen = sizeof(frb.buffer);
05957 
05958    if (!pvt) {
05959       ast_log(LOG_WARNING, "No private structure for packet?\n");
05960       return -1;
05961    }
05962    
05963    lastsent = pvt->lastsent;
05964 
05965    /* Calculate actual timestamp */
05966    fts = calc_timestamp(pvt, ts, f);
05967 
05968    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
05969     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
05970     * increment the "predicted timestamps" for voice, if we're predicting */
05971    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
05972       return 0;
05973 #if 0
05974    ast_log(LOG_NOTICE, 
05975       "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
05976       *("=!" + (f->frametype == AST_FRAME_VOICE)),
05977       IAX_CALLENCRYPTED(pvt) ? "" : "not ",
05978       pvt->keyrotateid != -1 ? "" : "no "
05979    );
05980 #endif
05981    if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
05982       iax2_key_rotate(pvt);
05983    }
05984 
05985    if ((ast_test_flag(pvt, IAX_TRUNK) || 
05986          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
05987          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
05988       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
05989        (f->frametype == AST_FRAME_VOICE) 
05990       /* is a voice frame */ &&
05991       (f->subclass == pvt->svoiceformat) 
05992       /* is the same type */ ) {
05993          /* Force immediate rather than delayed transmission */
05994          now = 1;
05995          /* Mark that mini-style frame is appropriate */
05996          sendmini = 1;
05997    }
05998    if ( f->frametype == AST_FRAME_VIDEO ) {
05999       /*
06000        * If the lower 15 bits of the timestamp roll over, or if
06001        * the video format changed then send a full frame.
06002        * Otherwise send a mini video frame
06003        */
06004       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06005           ((f->subclass & ~0x1) == pvt->svideoformat)
06006          ) {
06007          now = 1;
06008          sendmini = 1;
06009       } else {
06010          now = 0;
06011          sendmini = 0;
06012       }
06013       pvt->lastvsent = fts;
06014    }
06015    if (f->frametype == AST_FRAME_IAX) {
06016       /* 0x8000 marks this message as TX:, this bit will be stripped later */
06017       pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
06018       if (!pvt->first_iax_message) {
06019          pvt->first_iax_message = pvt->last_iax_message;
06020       }
06021    }
06022    /* Allocate an iax_frame */
06023    if (now) {
06024       fr = &frb.fr2;
06025    } else
06026       fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO));
06027    if (!fr) {
06028       ast_log(LOG_WARNING, "Out of memory\n");
06029       return -1;
06030    }
06031    /* Copy our prospective frame into our immediate or retransmitted wrapper */
06032    iax_frame_wrap(fr, f);
06033 
06034    fr->ts = fts;
06035    fr->callno = pvt->callno;
06036    fr->transfer = transfer;
06037    fr->final = final;
06038    fr->encmethods = 0;
06039    if (!sendmini) {
06040       /* We need a full frame */
06041       if (seqno > -1)
06042          fr->oseqno = seqno;
06043       else
06044          fr->oseqno = pvt->oseqno++;
06045       fr->iseqno = pvt->iseqno;
06046       fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06047       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06048       fh->ts = htonl(fr->ts);
06049       fh->oseqno = fr->oseqno;
06050       if (transfer) {
06051          fh->iseqno = 0;
06052       } else
06053          fh->iseqno = fr->iseqno;
06054       /* Keep track of the last thing we've acknowledged */
06055       if (!transfer)
06056          pvt->aseqno = fr->iseqno;
06057       fh->type = fr->af.frametype & 0xFF;
06058       if (fr->af.frametype == AST_FRAME_VIDEO)
06059          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
06060       else
06061          fh->csub = compress_subclass(fr->af.subclass);
06062       if (transfer) {
06063          fr->dcallno = pvt->transfercallno;
06064       } else
06065          fr->dcallno = pvt->peercallno;
06066       fh->dcallno = htons(fr->dcallno);
06067       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06068       fr->data = fh;
06069       fr->retries = 0;
06070       /* Retry after 2x the ping time has passed */
06071       fr->retrytime = pvt->pingtime * 2;
06072       if (fr->retrytime < MIN_RETRY_TIME)
06073          fr->retrytime = MIN_RETRY_TIME;
06074       if (fr->retrytime > MAX_RETRY_TIME)
06075          fr->retrytime = MAX_RETRY_TIME;
06076       /* Acks' don't get retried */
06077       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
06078          fr->retries = -1;
06079       else if (f->frametype == AST_FRAME_VOICE)
06080          pvt->svoiceformat = f->subclass;
06081       else if (f->frametype == AST_FRAME_VIDEO)
06082          pvt->svideoformat = f->subclass & ~0x1;
06083       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06084          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06085             if (fr->transfer)
06086                iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06087             else
06088                iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06089             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06090             fr->encmethods = pvt->encmethods;
06091             fr->ecx = pvt->ecx;
06092             fr->mydcx = pvt->mydcx;
06093             memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06094          } else
06095             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06096       }
06097 
06098       if (now) {
06099          res = send_packet(fr);
06100       } else
06101          res = iax2_transmit(fr);
06102    } else {
06103       if (ast_test_flag(pvt, IAX_TRUNK)) {
06104          iax2_trunk_queue(pvt, fr);
06105          res = 0;
06106       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06107          /* Video frame have no sequence number */
06108          fr->oseqno = -1;
06109          fr->iseqno = -1;
06110          vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06111          vh->zeros = 0;
06112          vh->callno = htons(0x8000 | fr->callno);
06113          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
06114          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06115          fr->data = vh;
06116          fr->retries = -1;
06117          res = send_packet(fr);        
06118       } else {
06119          /* Mini-frames have no sequence number */
06120          fr->oseqno = -1;
06121          fr->iseqno = -1;
06122          /* Mini frame will do */
06123          mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06124          mh->callno = htons(fr->callno);
06125          mh->ts = htons(fr->ts & 0xFFFF);
06126          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06127          fr->data = mh;
06128          fr->retries = -1;
06129          if (pvt->transferring == TRANSFER_MEDIAPASS)
06130             fr->transfer = 1;
06131          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06132             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06133                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06134             } else
06135                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06136          }
06137          res = send_packet(fr);
06138       }
06139    }
06140    return res;
06141 }

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

Definition at line 3991 of file chan_iax2.c.

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

03992 {
03993    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
03994 }

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

Definition at line 3986 of file chan_iax2.c.

References AST_FRAME_IMAGE, ast_frame::data, ast_frame::datalen, ast_frame::ptr, PTR_TO_CALLNO, send_command_locked(), ast_frame::subclass, and ast_channel::tech_pvt.

03987 {
03988    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data.ptr, img->datalen, -1);
03989 }

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

Definition at line 3979 of file chan_iax2.c.

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

03980 {
03981    
03982    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
03983       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
03984 }

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

Definition at line 4933 of file chan_iax2.c.

References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_free, ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, errno, iaxs, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().

04934 {
04935    struct ast_option_header *h;
04936    int res;
04937 
04938    switch (option) {
04939    case AST_OPTION_TXGAIN:
04940    case AST_OPTION_RXGAIN:
04941       /* these two cannot be sent, because they require a result */
04942       errno = ENOSYS;
04943       return -1;
04944    default:
04945    {
04946       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04947       struct chan_iax2_pvt *pvt;
04948 
04949       ast_mutex_lock(&iaxsl[callno]);
04950       pvt = iaxs[callno];
04951 
04952       if (wait_for_peercallno(pvt)) {
04953          ast_mutex_unlock(&iaxsl[callno]);
04954          return -1;
04955       }
04956 
04957       ast_mutex_unlock(&iaxsl[callno]);
04958 
04959       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
04960          return -1;
04961       }
04962 
04963       h->flag = AST_OPTION_FLAG_REQUEST;
04964       h->option = htons(option);
04965       memcpy(h->data, data, datalen);
04966       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
04967                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
04968                  datalen + sizeof(*h), -1);
04969       ast_free(h);
04970       return res;
04971    }
04972    }
04973 }

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

Definition at line 5014 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_random(), ast_set_flag, IAX_CALLENCRYPTED, IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, IAX_NOTRANSFER, iaxs, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.

05015 {
05016    int res;
05017    struct iax_ie_data ied0;
05018    struct iax_ie_data ied1;
05019    unsigned int transferid = (unsigned int)ast_random();
05020 
05021    if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05022       ast_debug(1, "transfers are not supported for encrypted calls at this time");
05023       ast_set_flag(iaxs[callno0], IAX_NOTRANSFER);
05024       ast_set_flag(iaxs[callno1], IAX_NOTRANSFER);
05025       return 0;
05026    }
05027 
05028    memset(&ied0, 0, sizeof(ied0));
05029    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05030    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05031    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05032 
05033    memset(&ied1, 0, sizeof(ied1));
05034    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05035    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05036    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05037    
05038    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05039    if (res)
05040       return -1;
05041    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05042    if (res)
05043       return -1;
05044    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05045    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05046    return 0;
05047 }

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

Definition at line 5268 of file chan_iax2.c.

References ast_copy_string(), ast_debug, AST_FRAME_IAX, chan_iax2_pvt::callno, context, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, ast_channel::name, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

05269 {
05270    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05271    struct iax_ie_data ied = { "", };
05272    char tmp[256], *context;
05273    ast_copy_string(tmp, dest, sizeof(tmp));
05274    context = strchr(tmp, '@');
05275    if (context) {
05276       *context = '\0';
05277       context++;
05278    }
05279    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05280    if (context)
05281       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05282    ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05283    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05284 }

static int iax2_transmit ( struct iax_frame fr  )  [static]

Definition at line 3951 of file chan_iax2.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, iax2_trunk_peer::list, sched_lock, iax_frame::sentyet, and signal_condition().

Referenced by iax2_send().

03952 {
03953    /* Lock the queue and place this packet at the end */
03954    /* By setting this to 0, the network thread will send it for us, and
03955       queue retransmission if necessary */
03956    fr->sentyet = 0;
03957    AST_LIST_LOCK(&frame_queue);
03958    AST_LIST_INSERT_TAIL(&frame_queue, fr, list);
03959    AST_LIST_UNLOCK(&frame_queue);
03960    /* Wake up the network and scheduler thread */
03961    if (netthreadid != AST_PTHREADT_NULL)
03962       pthread_kill(netthreadid, SIGURG);
03963    signal_condition(&sched_lock, &sched_cond);
03964    return 0;
03965 }

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

Definition at line 8613 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

08614 {
08615    /* Drop when trunk is about 5 seconds idle */
08616    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
08617       return 1;
08618    return 0;
08619 }

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

Definition at line 5677 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_flag, ast_tvnow(), ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, DEFAULT_TRUNKDATA, f, find_tpeer(), globalflags, IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, send_trunk(), chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.

Referenced by iax2_send().

05678 {
05679    struct ast_frame *f;
05680    struct iax2_trunk_peer *tpeer;
05681    void *tmp, *ptr;
05682    struct timeval now;
05683    int res; 
05684    struct ast_iax2_meta_trunk_entry *met;
05685    struct ast_iax2_meta_trunk_mini *mtm;
05686 
05687    f = &fr->af;
05688    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
05689    if (tpeer) {
05690       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
05691          /* Need to reallocate space */
05692          if (tpeer->trunkdataalloc < trunkmaxsize) {
05693             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
05694                ast_mutex_unlock(&tpeer->lock);
05695                return -1;
05696             }
05697             
05698             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
05699             tpeer->trunkdata = tmp;
05700             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);
05701          } else {
05702             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));
05703             ast_mutex_unlock(&tpeer->lock);
05704             return -1;
05705          }
05706       }
05707 
05708       /* Append to meta frame */
05709       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
05710       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
05711          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
05712          mtm->len = htons(f->datalen);
05713          mtm->mini.callno = htons(pvt->callno);
05714          mtm->mini.ts = htons(0xffff & fr->ts);
05715          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
05716          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
05717       } else {
05718          met = (struct ast_iax2_meta_trunk_entry *)ptr;
05719          /* Store call number and length in meta header */
05720          met->callno = htons(pvt->callno);
05721          met->len = htons(f->datalen);
05722          /* Advance pointers/decrease length past trunk entry header */
05723          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
05724          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
05725       }
05726       /* Copy actual trunk data */
05727       memcpy(ptr, f->data.ptr, f->datalen);
05728       tpeer->trunkdatalen += f->datalen;
05729 
05730       tpeer->calls++;
05731 
05732       /* track the largest mtu we actually have sent */
05733       if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 
05734          trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 
05735 
05736       /* if we have enough for a full MTU, ship it now without waiting */
05737       if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
05738          now = ast_tvnow();
05739          res = send_trunk(tpeer, &now); 
05740          trunk_untimed ++; 
05741       }
05742 
05743       ast_mutex_unlock(&tpeer->lock);
05744    }
05745    return 0;
05746 }

static int iax2_vnak ( int  callno  )  [static]

Definition at line 8531 of file chan_iax2.c.

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

Referenced by socket_process(), and socket_process_meta().

08532 {
08533    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
08534 }

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

Definition at line 6939 of file chan_iax2.c.

References ast_debug, AST_FRAME_NULL, AST_FRAME_VOICE, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_peer::callno, errno, f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, PTR_TO_CALLNO, and ast_channel::tech_pvt.

06940 {
06941    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
06942    int res = -1;
06943    ast_mutex_lock(&iaxsl[callno]);
06944    if (iaxs[callno]) {
06945    /* If there's an outstanding error, return failure now */
06946       if (!iaxs[callno]->error) {
06947          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
06948             res = 0;
06949             /* Don't waste bandwidth sending null frames */
06950          else if (f->frametype == AST_FRAME_NULL)
06951             res = 0;
06952          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
06953             res = 0;
06954          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
06955             res = 0;
06956          else
06957          /* Simple, just queue for transmission */
06958             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
06959       } else {
06960          ast_debug(1, "Write error: %s\n", strerror(errno));
06961       }
06962    }
06963    /* If it's already gone, just return */
06964    ast_mutex_unlock(&iaxsl[callno]);
06965    return res;
06966 }

static int iax_check_version ( char *  dev  )  [static]

Definition at line 2898 of file chan_iax2.c.

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

Referenced by update_registry().

02899 {
02900    int res = 0;
02901    struct iax_firmware *cur = NULL;
02902 
02903    if (ast_strlen_zero(dev))
02904       return 0;
02905 
02906    AST_LIST_LOCK(&firmwares);
02907    AST_LIST_TRAVERSE(&firmwares, cur, list) {
02908       if (!strcmp(dev, (char *)cur->fwh->devname)) {
02909          res = ntohs(cur->fwh->version);
02910          break;
02911       }
02912    }
02913    AST_LIST_UNLOCK(&firmwares);
02914 
02915    return res;
02916 }

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

Definition at line 979 of file chan_iax2.c.

References ast_verbose.

Referenced by load_module().

00980 {
00981    if (iaxdebug)
00982       ast_verbose("%s", data);
00983 }

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

Definition at line 985 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

00986 {
00987    ast_log(LOG_WARNING, "%s", data);
00988 }

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

Definition at line 2918 of file chan_iax2.c.

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

Referenced by socket_process().

02919 {
02920    int res = -1;
02921    unsigned int bs = desc & 0xff;
02922    unsigned int start = (desc >> 8) & 0xffffff;
02923    unsigned int bytes;
02924    struct iax_firmware *cur;
02925 
02926    if (ast_strlen_zero((char *)dev) || !bs)
02927       return -1;
02928 
02929    start *= bs;
02930    
02931    AST_LIST_LOCK(&firmwares);
02932    AST_LIST_TRAVERSE(&firmwares, cur, list) {
02933       if (strcmp((char *)dev, (char *)cur->fwh->devname))
02934          continue;
02935       iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
02936       if (start < ntohl(cur->fwh->datalen)) {
02937          bytes = ntohl(cur->fwh->datalen) - start;
02938          if (bytes > bs)
02939             bytes = bs;
02940          iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02941       } else {
02942          bytes = 0;
02943          iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02944       }
02945       if (bytes == bs)
02946          res = 0;
02947       else
02948          res = 1;
02949       break;
02950    }
02951    AST_LIST_UNLOCK(&firmwares);
02952 
02953    return res;
02954 }

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

References debugaddr, f, and iax_showframe().

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

00963 {
00964    if (iaxdebug ||
00965        (sin && debugaddr.sin_addr.s_addr && 
00966         (!ntohs(debugaddr.sin_port) ||
00967          debugaddr.sin_port == sin->sin_port) &&
00968         debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
00969       if (iaxdebug) {
00970          iax_showframe(f, fhi, rx, sin, datalen);
00971       } else {
00972          iaxdebug = 1;
00973          iax_showframe(f, fhi, rx, sin, datalen);
00974          iaxdebug = 0;
00975       }
00976    }
00977 }

static int iax_park ( struct ast_channel chan1,
struct ast_channel chan2 
) [static]

Definition at line 8775 of file chan_iax2.c.

References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, ast_channel_alloc, ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_channel::context, ast_channel::exten, iax_park_thread(), LOG_WARNING, ast_channel::name, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.

Referenced by socket_process().

08776 {
08777    struct iax_dual *d;
08778    struct ast_channel *chan1m, *chan2m;
08779    pthread_t th;
08780    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
08781    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
08782    if (chan2m && chan1m) {
08783       /* Make formats okay */
08784       chan1m->readformat = chan1->readformat;
08785       chan1m->writeformat = chan1->writeformat;
08786       ast_channel_masquerade(chan1m, chan1);
08787       /* Setup the extensions and such */
08788       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
08789       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
08790       chan1m->priority = chan1->priority;
08791       
08792       /* We make a clone of the peer channel too, so we can play
08793          back the announcement */
08794       /* Make formats okay */
08795       chan2m->readformat = chan2->readformat;
08796       chan2m->writeformat = chan2->writeformat;
08797       ast_channel_masquerade(chan2m, chan2);
08798       /* Setup the extensions and such */
08799       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
08800       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
08801       chan2m->priority = chan2->priority;
08802       if (ast_do_masquerade(chan2m)) {
08803          ast_log(LOG_WARNING, "Masquerade failed :(\n");
08804          ast_hangup(chan2m);
08805          return -1;
08806       }
08807    } else {
08808       if (chan1m)
08809          ast_hangup(chan1m);
08810       if (chan2m)
08811          ast_hangup(chan2m);
08812       return -1;
08813    }
08814    if ((d = ast_calloc(1, sizeof(*d)))) {
08815       d->chan1 = chan1m;
08816       d->chan2 = chan2m;
08817       if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
08818          return 0;
08819       }
08820       ast_free(d);
08821    }
08822    return -1;
08823 }

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

Definition at line 8755 of file chan_iax2.c.

References ast_free, ast_frfree, ast_hangup(), ast_log(), ast_park_call(), ast_read(), iax_dual::chan1, iax_dual::chan2, ext, f, and LOG_NOTICE.

Referenced by iax_park().

08756 {
08757    struct ast_channel *chan1, *chan2;
08758    struct iax_dual *d;
08759    struct ast_frame *f;
08760    int ext;
08761    int res;
08762    d = stuff;
08763    chan1 = d->chan1;
08764    chan2 = d->chan2;
08765    ast_free(d);
08766    f = ast_read(chan1);
08767    if (f)
08768       ast_frfree(f);
08769    res = ast_park_call(chan1, chan2, 0, &ext);
08770    ast_hangup(chan2);
08771    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
08772    return NULL;
08773 }

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

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

01711 {
01712    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01713    if (new) {
01714       size_t afdatalen = new->afdatalen;
01715       memcpy(new, fr, sizeof(*new));
01716       iax_frame_wrap(new, &fr->af);
01717       new->afdatalen = afdatalen;
01718       new->data = NULL;
01719       new->datalen = 0;
01720       new->direction = DIRECTION_INGRESS;
01721       new->retrans = -1;
01722    }
01723    return new;
01724 }

static void insert_idle_thread ( struct iax2_thread thread  )  [static]

Definition at line 1166 of file chan_iax2.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_THREAD_TYPE_DYNAMIC, iax2_trunk_peer::list, and thread.

Referenced by iax2_process_thread().

01167 {
01168    if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01169       AST_LIST_LOCK(&dynamic_list);
01170       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01171       AST_LIST_UNLOCK(&dynamic_list);
01172    } else {
01173       AST_LIST_LOCK(&idle_list);
01174       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01175       AST_LIST_UNLOCK(&idle_list);
01176    }
01177 
01178    return;
01179 }

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

Definition at line 1014 of file chan_iax2.c.

References ast_verbose.

Referenced by handle_cli_iax2_set_debug_jb().

01015 {
01016    va_list args;
01017    char buf[1024];
01018 
01019    va_start(args, fmt);
01020    vsnprintf(buf, sizeof(buf), fmt, args);
01021    va_end(args);
01022 
01023    ast_verbose("%s", buf);
01024 }

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

Definition at line 990 of file chan_iax2.c.

References ast_log(), and LOG_ERROR.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

00991 {
00992    va_list args;
00993    char buf[1024];
00994 
00995    va_start(args, fmt);
00996    vsnprintf(buf, sizeof(buf), fmt, args);
00997    va_end(args);
00998 
00999    ast_log(LOG_ERROR, "%s", buf);
01000 }

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

Definition at line 1002 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

01003 {
01004    va_list args;
01005    char buf[1024];
01006 
01007    va_start(args, fmt);
01008    vsnprintf(buf, sizeof(buf), fmt, args);
01009    va_end(args);
01010 
01011    ast_log(LOG_WARNING, "%s", buf);
01012 }

static int load_module ( void   )  [static]

Load IAX2 module, load configuraiton ---.

Definition at line 13641 of file chan_iax2.c.

References __unload_module(), ao2_callback, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_cond_init(), ast_custom_function_register, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register, 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, ast_register_switch(), ast_timer_close(), ast_timer_open(), ast_timer_set_rate(), ast_verb, cli_iax2, config, iax2_registry::entry, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxs, iaxvar_function, io, io_context_create(), io_context_destroy(), jb_error_output(), jb_setoutput(), jb_warning_output(), load_objects(), LOG_ERROR, manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), netsock, outsock, papp, pdescrip, peer_set_sock_cb(), peers, psyn, reload_firmware(), RQ_CHAR, RQ_UINTEGER2, sched, sched_context_create(), sched_context_destroy(), SENTINEL, set_config(), start_network_thread(), and timer.

13642 {
13643 
13644    static const char config[] = "iax.conf";
13645    int x = 0;
13646    struct iax2_registry *reg = NULL;
13647 
13648    if (load_objects()) {
13649       return AST_MODULE_LOAD_FAILURE;
13650    }
13651 
13652    randomcalltokendata = ast_random();
13653    ast_custom_function_register(&iaxpeer_function);
13654    ast_custom_function_register(&iaxvar_function);
13655 
13656    iax_set_output(iax_debug_output);
13657    iax_set_error(iax_error_output);
13658    jb_setoutput(jb_error_output, jb_warning_output, NULL);
13659 
13660    memset(iaxs, 0, sizeof(iaxs));
13661 
13662    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13663       ast_mutex_init(&iaxsl[x]);
13664    }
13665 
13666    ast_cond_init(&sched_cond, NULL);
13667 
13668    if (!(sched = sched_context_create())) {
13669       ast_log(LOG_ERROR, "Failed to create scheduler context\n");
13670       return AST_MODULE_LOAD_FAILURE;
13671    }
13672 
13673    if (!(io = io_context_create())) {
13674       ast_log(LOG_ERROR, "Failed to create I/O context\n");
13675       sched_context_destroy(sched);
13676       return AST_MODULE_LOAD_FAILURE;
13677    }
13678 
13679    if (!(netsock = ast_netsock_list_alloc())) {
13680       ast_log(LOG_ERROR, "Failed to create netsock list\n");
13681       io_context_destroy(io);
13682       sched_context_destroy(sched);
13683       return AST_MODULE_LOAD_FAILURE;
13684    }
13685    ast_netsock_init(netsock);
13686    
13687    outsock = ast_netsock_list_alloc();
13688    if (!outsock) {
13689       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13690       io_context_destroy(io);
13691       sched_context_destroy(sched);
13692       return AST_MODULE_LOAD_FAILURE;
13693    }
13694    ast_netsock_init(outsock);
13695 
13696    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
13697 
13698    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
13699    
13700    ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" );
13701    ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" );
13702    ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" );
13703 
13704    if ((timer = ast_timer_open())) {
13705       ast_timer_set_rate(timer, trunkfreq);
13706    }
13707 
13708    if (set_config(config, 0) == -1) {
13709       if (timer) {
13710          ast_timer_close(timer);
13711       }
13712       return AST_MODULE_LOAD_DECLINE;
13713    }
13714 
13715    if (ast_channel_register(&iax2_tech)) {
13716       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
13717       __unload_module();
13718       return AST_MODULE_LOAD_FAILURE;
13719    }
13720 
13721    if (ast_register_switch(&iax2_switch)) 
13722       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
13723 
13724    if (start_network_thread()) {
13725       ast_log(LOG_ERROR, "Unable to start network thread\n");
13726       __unload_module();
13727       return AST_MODULE_LOAD_FAILURE;
13728    } else
13729       ast_verb(2, "IAX Ready and Listening\n");
13730 
13731    AST_LIST_LOCK(&registrations);
13732    AST_LIST_TRAVERSE(&registrations, reg, entry)
13733       iax2_do_register(reg);
13734    AST_LIST_UNLOCK(&registrations); 
13735    
13736    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
13737    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
13738 
13739 
13740    reload_firmware(0);
13741    iax_provision_reload(0);
13742 
13743    ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
13744 
13745    return AST_MODULE_LOAD_SUCCESS;
13746 }

static int load_objects ( void   )  [static]

Definition at line 13582 of file chan_iax2.c.

References addr_range_cmp_cb(), addr_range_hash_cb(), ao2_container_alloc, ao2_ref, AST_MODULE_LOAD_FAILURE, callno_limits, calltoken_ignores, create_callno_pools(), IAX_MAX_CALLS, iax_peercallno_pvts, iax_transfercallno_pvts, MAX_PEER_BUCKETS, MAX_USER_BUCKETS, peer_cmp_cb(), peer_hash_cb(), peercnt_cmp_cb(), peercnt_hash_cb(), peercnts, peers, pvt_cmp_cb(), pvt_hash_cb(), transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), user_hash_cb(), and users.

Referenced by load_module().

13583 {
13584    peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
13585    peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
13586 
13587    if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
13588       goto container_fail;
13589    } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
13590       goto container_fail;
13591    } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
13592       goto container_fail;
13593    } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
13594       goto container_fail;
13595    } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
13596       goto container_fail;
13597    } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13598       goto container_fail;
13599    } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13600       goto container_fail;
13601    } else if (create_callno_pools()) {
13602       goto container_fail;
13603    }
13604 
13605    return 0;
13606 
13607 container_fail:
13608    if (peers) {
13609       ao2_ref(peers, -1);
13610    }
13611    if (users) {
13612       ao2_ref(users, -1);
13613    }
13614    if (iax_peercallno_pvts) {
13615       ao2_ref(iax_peercallno_pvts, -1);
13616    }
13617    if (iax_transfercallno_pvts) {
13618       ao2_ref(iax_transfercallno_pvts, -1);
13619    }
13620    if (peercnts) {
13621       ao2_ref(peercnts, -1);
13622    }
13623    if (callno_limits) {
13624       ao2_ref(callno_limits, -1);
13625    }
13626    if (calltoken_ignores) {
13627       ao2_ref(calltoken_ignores, -1);
13628    }
13629    if (callno_pool) {
13630       ao2_ref(callno_pool, -1);
13631    }
13632    if (callno_pool_trunk) {
13633       ao2_ref(callno_pool_trunk, -1);
13634    }
13635    return AST_MODULE_LOAD_FAILURE;
13636 }

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

Definition at line 5049 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_trylock(), and DEADLOCK_AVOIDANCE.

Referenced by iax2_bridge().

05050 {
05051    ast_mutex_lock(&iaxsl[callno0]);
05052    while (ast_mutex_trylock(&iaxsl[callno1])) {
05053       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05054    }
05055 }

static void log_jitterstats ( unsigned short  callno  )  [static]

Definition at line 8898 of file chan_iax2.c.

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

Referenced by socket_process().

08899 {
08900    int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
08901    jb_info jbinfo;
08902 
08903    ast_mutex_lock(&iaxsl[callno]);
08904    if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
08905       if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) {
08906          jb_getinfo(iaxs[callno]->jb, &jbinfo);
08907          localjitter = jbinfo.jitter;
08908          localdelay = jbinfo.current - jbinfo.min;
08909          locallost = jbinfo.frames_lost;
08910          locallosspct = jbinfo.losspct/1000;
08911          localdropped = jbinfo.frames_dropped;
08912          localooo = jbinfo.frames_ooo;
08913          localpackets = jbinfo.frames_in;
08914       }
08915       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",
08916          iaxs[callno]->owner->name,
08917          iaxs[callno]->pingtime,
08918          localjitter,
08919          localdelay,
08920          locallost,
08921          locallosspct,
08922          localdropped,
08923          localooo,
08924          localpackets,
08925          iaxs[callno]->remote_rr.jitter,
08926          iaxs[callno]->remote_rr.delay,
08927          iaxs[callno]->remote_rr.losscnt,
08928          iaxs[callno]->remote_rr.losspct/1000,
08929          iaxs[callno]->remote_rr.dropped,
08930          iaxs[callno]->remote_rr.ooo,
08931          iaxs[callno]->remote_rr.packets);
08932       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",
08933          iaxs[callno]->owner->name,
08934          iaxs[callno]->pingtime,
08935          localjitter,
08936          localdelay,
08937          locallost,
08938          locallosspct,
08939          localdropped,
08940          localooo,
08941          localpackets,
08942          iaxs[callno]->remote_rr.jitter,
08943          iaxs[callno]->remote_rr.delay,
08944          iaxs[callno]->remote_rr.losscnt,
08945          iaxs[callno]->remote_rr.losspct/1000,
08946          iaxs[callno]->remote_rr.dropped,
08947          iaxs[callno]->remote_rr.ooo,
08948          iaxs[callno]->remote_rr.packets);
08949    }
08950    ast_mutex_unlock(&iaxsl[callno]);
08951 }

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

Definition at line 1790 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(), iaxs, chan_iax2_pvt::lagid, LOG_WARNING, MIN_REUSE_TIME, chan_iax2_pvt::pingid, replace_callno(), sched, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), update_max_trunk(), and callno_entry::validated.

Referenced by iax2_request(), and socket_process().

01791 {
01792    int x;
01793    int res= 0;
01794    struct callno_entry *callno_entry;
01795    if (iaxs[callno]->oseqno) {
01796       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01797       return -1;
01798    }
01799    if (callno & TRUNK_CALL_START) {
01800       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01801       return -1;
01802    }
01803 
01804    if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
01805       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01806       return -1;
01807    }
01808 
01809    x = callno_entry->callno;
01810    ast_mutex_lock(&iaxsl[x]);
01811 
01812    /*!
01813     * \note We delete these before switching the slot, because if
01814     * they fire in the meantime, they will generate a warning.
01815     */
01816    AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01817    AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01818    iaxs[x] = iaxs[callno];
01819    iaxs[x]->callno = x;
01820 
01821    /* since we copied over the pvt from a different callno, make sure the old entry is replaced
01822     * before assigning the new one */
01823    if (iaxs[x]->callno_entry) {
01824       iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
01825    }
01826    iaxs[x]->callno_entry = callno_entry;
01827 
01828    iaxs[callno] = NULL;
01829    /* Update the two timers that should have been started */
01830    iaxs[x]->pingid = iax2_sched_add(sched, 
01831       ping_time * 1000, send_ping, (void *)(long)x);
01832    iaxs[x]->lagid = iax2_sched_add(sched, 
01833       lagrq_time * 1000, send_lagrq, (void *)(long)x);
01834 
01835    if (locked)
01836       ast_mutex_unlock(&iaxsl[callno]);
01837    res = x;
01838    if (!locked)
01839       ast_mutex_unlock(&iaxsl[x]);
01840 
01841    ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
01842    /* We move this call from a non-trunked to a trunked call */
01843    update_max_trunk();
01844    update_max_nontrunk();
01845    return res;
01846 }

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

Definition at line 6508 of file chan_iax2.c.

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

Referenced by load_module().

06509 {
06510    ast_cli_netstats(s, -1, 0);
06511    astman_append(s, "\r\n");
06512    return RESULT_SUCCESS;
06513 }

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 6560 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_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), IAX_DYNAMIC, iax2_peer::mask, iax2_peer::name, peer_status(), peer_unref(), peers, RESULT_SUCCESS, s, status, and iax2_peer::username.

Referenced by load_module().

06561 {
06562    struct iax2_peer *peer = NULL;
06563    int peer_count = 0;
06564    char nm[20];
06565    char status[20];
06566    const char *id = astman_get_header(m,"ActionID");
06567    char idtext[256] = "";
06568    struct ao2_iterator i;
06569 
06570    if (!ast_strlen_zero(id))
06571       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06572 
06573    astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06574 
06575 
06576    i = ao2_iterator_init(peers, 0);
06577    for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
06578 
06579       astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06580       if (!ast_strlen_zero(peer->username)) {
06581          astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
06582       } else {
06583          astman_append(s, "ObjectName: %s\r\n", peer->name);
06584       }
06585       astman_append(s, "ChanObjectType: peer\r\n");
06586       astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-");
06587       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06588       astman_append(s, "Mask: %s\r\n", nm);
06589       astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port));
06590       astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
06591       peer_status(peer, status, sizeof(status));
06592       astman_append(s, "Status: %s\r\n\r\n", status);
06593       peer_count++;
06594    }
06595    ao2_iterator_destroy(&i);
06596 
06597    astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
06598    return RESULT_SUCCESS;
06599 }

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

callback to display iax peers in manager

Definition at line 6547 of file chan_iax2.c.

References __iax2_show_peers(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), and s.

Referenced by load_module().

06548 {
06549    char *a[] = { "iax2", "show", "users" };
06550    const char *id = astman_get_header(m,"ActionID");
06551    char idtext[256] = "";
06552 
06553    if (!ast_strlen_zero(id))
06554       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06555    astman_send_ack(s, m, "Peer status list will follow");
06556    return __iax2_show_peers(1, -1, s, 3, a );
06557 } 

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

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

Referenced by __ao2_callback(), __find_callno(), ast_parse_device_state(), check_blacklist(), find_command(), handle_updates(), lua_find_extension(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), and transfercallno_pvt_cmp_cb().

01740 {
01741    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01742       (cur->addr.sin_port == sin->sin_port)) {
01743       /* This is the main host */
01744       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01745           (check_dcallno ? dcallno == cur->callno : 1) ) {
01746          /* That's us.  Be sure we keep track of the peer call number */
01747          return 1;
01748       }
01749    }
01750    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01751        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01752       /* We're transferring */
01753       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01754          return 1;
01755    }
01756    return 0;
01757 }

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

Definition at line 5776 of file chan_iax2.c.

References ast_aes_decrypt, ast_log(), and LOG_WARNING.

Referenced by decode_frame().

05777 {
05778 #if 0
05779    /* Debug with "fake encryption" */
05780    int x;
05781    if (len % 16)
05782       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05783    for (x=0;x<len;x++)
05784       dst[x] = src[x] ^ 0xff;
05785 #else 
05786    unsigned char lastblock[16] = { 0 };
05787    int x;
05788    while(len > 0) {
05789       ast_aes_decrypt(src, dst, dcx);
05790       for (x=0;x<16;x++)
05791          dst[x] ^= lastblock[x];
05792       memcpy(lastblock, src, sizeof(lastblock));
05793       dst += 16;
05794       src += 16;
05795       len -= 16;
05796    }
05797 #endif
05798 }

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

Definition at line 5800 of file chan_iax2.c.

References ast_aes_encrypt, ast_log(), and LOG_WARNING.

Referenced by encrypt_frame().

05801 {
05802 #if 0
05803    /* Debug with "fake encryption" */
05804    int x;
05805    if (len % 16)
05806       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05807    for (x=0;x<len;x++)
05808       dst[x] = src[x] ^ 0xff;
05809 #else
05810    unsigned char curblock[16] = { 0 };
05811    int x;
05812    while(len > 0) {
05813       for (x=0;x<16;x++)
05814          curblock[x] ^= src[x];
05815       ast_aes_encrypt(curblock, dst, ecx);
05816       memcpy(curblock, dst, sizeof(curblock)); 
05817       dst += 16;
05818       src += 16;
05819       len -= 16;
05820    }
05821 #endif
05822 }

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

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

07284 {
07285    /* Select exactly one common encryption if there are any */
07286    p->encmethods &= enc;
07287    if (p->encmethods) {
07288       if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */
07289          p->keyrotateid = -2;
07290       }
07291       if (p->encmethods & IAX_ENCRYPT_AES128)
07292          p->encmethods = IAX_ENCRYPT_AES128;
07293       else
07294          p->encmethods = 0;
07295    }
07296 }

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

Definition at line 1100 of file chan_iax2.c.

01101 {
01102    /* The MWI subscriptions exist just so the core knows we care about those
01103     * mailboxes.  However, we just grab the events out of the cache when it
01104     * is time to send MWI, since it is only sent with a REGACK. */
01105 }

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

Definition at line 11500 of file chan_iax2.c.

References ast_debug, ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_mutex_trylock(), ast_mutex_unlock(), ast_timer_fd(), attempt_transmit(), f, iax2_sched_add(), iax_frame_free(), iaxs, io, iax_frame::list, sched, send_packet(), timer, and timing_read().

Referenced by start_network_thread().

11501 {
11502    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
11503       from the network, and queue them for delivery to the channels */
11504    int res, count, wakeup;
11505    struct iax_frame *f;
11506 
11507    if (timer)
11508       ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
11509    
11510    for(;;) {
11511       pthread_testcancel();
11512 
11513       /* Go through the queue, sending messages which have not yet been
11514          sent, and scheduling retransmissions if appropriate */
11515       AST_LIST_LOCK(&frame_queue);
11516       count = 0;
11517       wakeup = -1;
11518       AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) {
11519          if (f->sentyet)
11520             continue;
11521          
11522          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
11523          if (ast_mutex_trylock(&iaxsl[f->callno])) {
11524             wakeup = 1;
11525             continue;
11526          }
11527 
11528          f->sentyet = 1;
11529 
11530          if (iaxs[f->callno]) {
11531             send_packet(f);
11532             count++;
11533          } 
11534 
11535          ast_mutex_unlock(&iaxsl[f->callno]);
11536 
11537          if (f->retries < 0) {
11538             /* This is not supposed to be retransmitted */
11539             AST_LIST_REMOVE_CURRENT(list);
11540             /* Free the iax frame */
11541             iax_frame_free(f);
11542          } else {
11543             /* We need reliable delivery.  Schedule a retransmission */
11544             f->retries++;
11545             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
11546          }
11547       }
11548       AST_LIST_TRAVERSE_SAFE_END;
11549       AST_LIST_UNLOCK(&frame_queue);
11550 
11551       pthread_testcancel();
11552       if (count >= 20)
11553          ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
11554 
11555       /* Now do the IO, and run scheduled tasks */
11556       res = ast_io_wait(io, wakeup);
11557       if (res >= 0) {
11558          if (res >= 20)
11559             ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
11560       }
11561    }
11562    return NULL;
11563 }

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

Definition at line 1668 of file chan_iax2.c.

References ao2_alloc, ao2_ref, AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_string_field_set, exten, jb_new(), jb_setconf(), jb_conf::max_contig_interp, jb_conf::max_jitterbuf, prefs, pvt_destructor(), jb_conf::resync_threshold, and jb_conf::target_extra.

Referenced by __find_callno().

01669 {
01670    struct chan_iax2_pvt *tmp;
01671    jb_conf jbconf;
01672 
01673    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01674       return NULL;
01675    }
01676 
01677    if (ast_string_field_init(tmp, 32)) {
01678       ao2_ref(tmp, -1);
01679       tmp = NULL;
01680       return NULL;
01681    }
01682       
01683    tmp->prefs = prefs;
01684    tmp->pingid = -1;
01685    tmp->lagid = -1;
01686    tmp->autoid = -1;
01687    tmp->authid = -1;
01688    tmp->initid = -1;
01689    tmp->keyrotateid = -1;
01690 
01691    ast_string_field_set(tmp,exten, "s");
01692    ast_string_field_set(tmp,host, host);
01693 
01694    tmp->jb = jb_new();
01695    tmp->jbid = -1;
01696    jbconf.max_jitterbuf = maxjitterbuffer;
01697    jbconf.resync_threshold = resyncthreshold;
01698    jbconf.max_contig_interp = maxjitterinterps;
01699    jbconf.target_extra = jittertargetextra;
01700    jb_setconf(tmp->jb,&jbconf);
01701 
01702    AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01703 
01704    tmp->hold_signaling = 1;
01705    AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
01706 
01707    return tmp;
01708 }

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

04635 {
04636    if (ast_strlen_zero(data))
04637       return;
04638 
04639    pds->peer = strsep(&data, "/");
04640    pds->exten = strsep(&data, "/");
04641    pds->options = data;
04642 
04643    if (pds->exten) {
04644       data = pds->exten;
04645       pds->exten = strsep(&data, "@");
04646       pds->context = data;
04647    }
04648 
04649    if (strchr(pds->peer, '@')) {
04650       data = pds->peer;
04651       pds->username = strsep(&data, "@");
04652       pds->peer = data;
04653    }
04654 
04655    if (pds->username) {
04656       data = pds->username;
04657       pds->username = strsep(&data, ":");
04658       pds->password = data;
04659    }
04660 
04661    data = pds->peer;
04662    pds->peer = strsep(&data, ":");
04663    pds->port = data;
04664 
04665    /* check for a key name wrapped in [] in the secret position, if found,
04666       move it to the key field instead
04667    */
04668    if (pds->password && (pds->password[0] == '[')) {
04669       pds->key = ast_strip_quoted(pds->password, "[", "]");
04670       pds->password = NULL;
04671    }
04672 }

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

References CMP_MATCH, CMP_STOP, and iax2_peer::name.

Referenced by load_module(), and load_objects().

01417 {
01418    struct iax2_peer *peer = obj, *peer2 = arg;
01419 
01420    return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01421 }

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

Definition at line 12231 of file chan_iax2.c.

References ast_set_flag, and IAX_DELME.

Referenced by delete_users().

12232 {
12233    struct iax2_peer *peer = obj;
12234 
12235    ast_set_flag(peer, IAX_DELME);
12236 
12237    return 0;
12238 }

static void peer_destructor ( void *  obj  )  [static]

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

11717 {
11718    struct iax2_peer *peer = obj;
11719    int callno = peer->callno;
11720 
11721    ast_free_ha(peer->ha);
11722 
11723    if (callno > 0) {
11724       ast_mutex_lock(&iaxsl[callno]);
11725       iax2_destroy(callno);
11726       ast_mutex_unlock(&iaxsl[callno]);
11727    }
11728 
11729    register_peer_exten(peer, 0);
11730 
11731    if (peer->dnsmgr)
11732       ast_dnsmgr_release(peer->dnsmgr);
11733 
11734    if (peer->mwi_event_sub)
11735       ast_event_unsubscribe(peer->mwi_event_sub);
11736 
11737    ast_string_field_free_memory(peer);
11738 }

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

References ast_str_hash(), and iax2_peer::name.

Referenced by load_module(), and load_objects().

01407 {
01408    const struct iax2_peer *peer = obj;
01409 
01410    return ast_str_hash(peer->name);
01411 }

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

Definition at line 1463 of file chan_iax2.c.

References ao2_ref.

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

01464 {
01465    ao2_ref(peer, +1);
01466    return peer;
01467 }

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

Definition at line 13536 of file chan_iax2.c.

References iax2_peer::sockfd.

Referenced by load_module().

13537 {
13538    struct iax2_peer *peer = obj;
13539 
13540    if (peer->sockfd < 0)
13541       peer->sockfd = defaultsockfd;
13542 
13543    return 0;
13544 }

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

References ast_debug, ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, io, LOG_WARNING, iax2_peer::name, netsock, outsock, qos, socket_read(), iax2_peer::sockfd, and strsep().

Referenced by build_peer().

11645 {
11646    struct sockaddr_in sin;
11647    int nonlocal = 1;
11648    int port = IAX_DEFAULT_PORTNO;
11649    int sockfd = defaultsockfd;
11650    char *tmp;
11651    char *addr;
11652    char *portstr;
11653 
11654    if (!(tmp = ast_strdupa(srcaddr)))
11655       return -1;
11656 
11657    addr = strsep(&tmp, ":");
11658    portstr = tmp;
11659 
11660    if (portstr) {
11661       port = atoi(portstr);
11662       if (port < 1)
11663          port = IAX_DEFAULT_PORTNO;
11664    }
11665    
11666    if (!ast_get_ip(&sin, addr)) {
11667       struct ast_netsock *sock;
11668       int res;
11669 
11670       sin.sin_port = 0;
11671       sin.sin_family = AF_INET;
11672       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
11673       if (res == 0) {
11674          /* ip address valid. */
11675          sin.sin_port = htons(port);
11676          if (!(sock = ast_netsock_find(netsock, &sin)))
11677             sock = ast_netsock_find(outsock, &sin);
11678          if (sock) {
11679             sockfd = ast_netsock_sockfd(sock);
11680             nonlocal = 0;
11681          } else {
11682             unsigned int orig_saddr = sin.sin_addr.s_addr;
11683             /* INADDR_ANY matches anyway! */
11684             sin.sin_addr.s_addr = INADDR_ANY;
11685             if (ast_netsock_find(netsock, &sin)) {
11686                sin.sin_addr.s_addr = orig_saddr;
11687                sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
11688                if (sock) {
11689                   sockfd = ast_netsock_sockfd(sock);
11690                   ast_netsock_unref(sock);
11691                   nonlocal = 0;
11692                } else {
11693                   nonlocal = 2;
11694                }
11695             }
11696          }
11697       }
11698    }
11699       
11700    peer->sockfd = sockfd;
11701 
11702    if (nonlocal == 1) {
11703       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
11704          srcaddr, peer->name);
11705       return -1;
11706         } else if (nonlocal == 2) {
11707       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
11708          srcaddr, peer->name);
11709          return -1;
11710    } else {
11711       ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
11712       return 0;
11713    }
11714 }

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

peer_status: Report Peer status in character string

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

03447 {
03448    int res = 0;
03449    if (peer->maxms) {
03450       if (peer->lastms < 0) {
03451          ast_copy_string(status, "UNREACHABLE", statuslen);
03452       } else if (peer->lastms > peer->maxms) {
03453          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03454          res = 1;
03455       } else if (peer->lastms) {
03456          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03457          res = 1;
03458       } else {
03459          ast_copy_string(status, "UNKNOWN", statuslen);
03460       }
03461    } else { 
03462       ast_copy_string(status, "Unmonitored", statuslen);
03463       res = -1;
03464    }
03465    return res;
03466 }

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

Definition at line 1469 of file chan_iax2.c.

References ao2_ref.

Referenced by __expire_registry(), __iax2_poke_noanswer(), __iax2_poke_peer_s(), __iax2_show_peers(), authenticate_reply(), build_peer(), calltoken_required(), complete_iax2_peers(), complete_iax2_unregister(), create_addr(), function_iaxpeer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_peer(), handle_cli_iax2_unregister(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), manager_iax2_show_peer_list(), poke_all_peers(), prune_peers(), reg_source_db(), registry_authrequest(), requirecalltoken_mark_auto(), set_config(), socket_process(), unlink_peer(), and update_registry().

01470 {
01471    ao2_ref(peer, -1);
01472    return NULL;
01473 }

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

Definition at line 2074 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

02075 {
02076    struct peercnt *peercnt;
02077    unsigned long addr = sin->sin_addr.s_addr;
02078    int res = 0;
02079    struct peercnt tmp = {
02080       .addr = addr,
02081    };
02082 
02083    /* Reasoning for peercnts container lock:  Two identical ip addresses
02084     * could be added by different threads at the "same time". Without the container
02085     * lock, both threads could alloc space for the same object and attempt
02086     * to link to table.  With the lock, one would create the object and link
02087     * to table while the other would find the already created peercnt object
02088     * rather than creating a new one. */
02089    ao2_lock(peercnts);
02090    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02091       ao2_lock(peercnt);
02092    } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02093       ao2_lock(peercnt);
02094       /* create and set defaults */
02095       peercnt->addr = addr;
02096       set_peercnt_limit(peercnt);
02097       /* guarantees it does not go away after unlocking table
02098        * ao2_find automatically adds this */
02099       ao2_link(peercnts, peercnt);
02100    } else {
02101       ao2_unlock(peercnts);
02102       return -1;
02103    }
02104 
02105    /* check to see if the address has hit its callno limit.  If not increment cur. */
02106    if (peercnt->limit > peercnt->cur) {
02107       peercnt->cur++;
02108       ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02109    } else { /* max num call numbers for this peer has been reached! */
02110       ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02111       res = -1;
02112    }
02113 
02114    /* clean up locks and ref count */
02115    ao2_unlock(peercnt);
02116    ao2_unlock(peercnts);
02117    ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */
02118 
02119    return res;
02120 }

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

Definition at line 1914 of file chan_iax2.c.

References peercnt::addr, CMP_MATCH, and CMP_STOP.

Referenced by load_objects().

01915 {
01916    struct peercnt *peercnt1 = obj, *peercnt2 = arg;
01917    return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
01918 }

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

Definition at line 1908 of file chan_iax2.c.

References peercnt::addr.

Referenced by load_objects().

01909 {
01910    const struct peercnt *peercnt = obj;
01911    return abs((int) peercnt->addr);
01912 }

static void peercnt_modify ( unsigned char  reg,
uint16_t  limit,
struct sockaddr_in *  sin 
) [static]

Definition at line 2046 of file chan_iax2.c.

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

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

02047 {
02048    /* this function turns off and on custom callno limits set by peer registration */
02049    struct peercnt *peercnt;
02050    struct peercnt tmp = {
02051       .addr = sin->sin_addr.s_addr,
02052    };
02053 
02054    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02055       peercnt->reg = reg;
02056       if (limit) {
02057          peercnt->limit = limit;
02058       } else {
02059          set_peercnt_limit(peercnt);
02060       }
02061       ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg);
02062       ao2_ref(peercnt, -1); /* decrement ref from find */
02063    }
02064 }

static void peercnt_remove ( struct peercnt peercnt  )  [static]

Definition at line 2126 of file chan_iax2.c.

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

Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().

02127 {
02128    struct sockaddr_in sin = {
02129       .sin_addr.s_addr = peercnt->addr,
02130    };
02131 
02132    if (peercnt) {
02133       /* Container locked here since peercnt may be unlinked from list.  If left unlocked,
02134        * peercnt_add could try and grab this entry from the table and modify it at the
02135        * "same time" this thread attemps to unlink it.*/
02136       ao2_lock(peercnts);
02137       peercnt->cur--;
02138       ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02139       /* if this was the last connection from the peer remove it from table */
02140       if (peercnt->cur == 0) {
02141          ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */
02142       }
02143       ao2_unlock(peercnts);
02144    }
02145 }

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

Definition at line 2165 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

02166 {
02167    struct peercnt *peercnt;
02168    struct peercnt tmp = {
02169       .addr = sin->sin_addr.s_addr,
02170    };
02171 
02172    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02173       peercnt_remove(peercnt);
02174       ao2_ref(peercnt, -1); /* decrement ref from find */
02175    }
02176    return 0;
02177 }

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

Definition at line 2151 of file chan_iax2.c.

References ao2_ref, and peercnt_remove().

Referenced by sched_delay_remove().

02152 {
02153    struct peercnt *peercnt = (struct peercnt *) obj;
02154 
02155    peercnt_remove(peercnt);
02156    ao2_ref(peercnt, -1); /* decrement ref from scheduler */
02157 
02158    return 0;
02159 }

static void poke_all_peers ( void   )  [static]

Definition at line 12747 of file chan_iax2.c.

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

Referenced by reload_config().

12748 {
12749    struct ao2_iterator i;
12750    struct iax2_peer *peer;
12751 
12752    i = ao2_iterator_init(peers, 0);
12753    while ((peer = ao2_iterator_next(&i))) {
12754       iax2_poke_peer(peer, 0);
12755       peer_unref(peer);
12756    }
12757    ao2_iterator_destroy(&i);
12758 }

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

Definition at line 2035 of file chan_iax2.c.

References CMP_MATCH, and addr_range::delme.

Referenced by reload_config().

02036 {
02037    struct addr_range *addr_range = obj;
02038 
02039    return addr_range->delme ? CMP_MATCH : 0;
02040 }

static void prune_peers ( void   )  [static]

Definition at line 12292 of file chan_iax2.c.

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

12293 {
12294    struct iax2_peer *peer;
12295    struct ao2_iterator i;
12296 
12297    i = ao2_iterator_init(peers, 0);
12298    while ((peer = ao2_iterator_next(&i))) {
12299       if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
12300          unlink_peer(peer);
12301       }
12302       peer_unref(peer);
12303    }
12304    ao2_iterator_destroy(&i);
12305 }

static void prune_users ( void   )  [static]

Definition at line 12276 of file chan_iax2.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_unlink, ast_test_flag, IAX_DELME, IAX_RTCACHEFRIENDS, user, user_unref(), and users.

Referenced by handle_cli_iax2_prune_realtime(), and reload_config().

12277 {
12278    struct iax2_user *user;
12279    struct ao2_iterator i;
12280 
12281    i = ao2_iterator_init(users, 0);
12282    while ((user = ao2_iterator_next(&i))) {
12283       if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
12284          ao2_unlink(users, user);
12285       }
12286       user_unref(user);
12287    }
12288    ao2_iterator_destroy(&i);
12289 }

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

Definition at line 13553 of file chan_iax2.c.

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

13554 {
13555    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13556 
13557    /* The frames_received field is used to hold whether we're matching
13558     * against a full frame or not ... */
13559 
13560    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
13561       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13562 }

static void pvt_destructor ( void *  obj  )  [static]

Definition at line 1620 of file chan_iax2.c.

References chan_iax2_pvt::addr, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, iax_frame::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, jb_frame::data, free_signaling_queue_entry(), iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, iax2_trunk_peer::list, iax2_trunk_peer::next, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, s, sched_delay_remove(), chan_iax2_pvt::signaling_queue, and chan_iax2_pvt::vars.

01621 {
01622    struct chan_iax2_pvt *pvt = obj;
01623    struct iax_frame *cur = NULL;
01624    struct signaling_queue_entry *s = NULL;
01625 
01626    ast_mutex_lock(&iaxsl[pvt->callno]);
01627    iax2_destroy_helper(pvt);
01628    sched_delay_remove(&pvt->addr, pvt->callno_entry);
01629    pvt->callno_entry = NULL;
01630    ast_mutex_unlock(&iaxsl[pvt->callno]);
01631 
01632    /* Already gone */
01633    ast_set_flag(pvt, IAX_ALREADYGONE); 
01634 
01635    AST_LIST_LOCK(&frame_queue);
01636    AST_LIST_TRAVERSE(&frame_queue, cur, list) {
01637       /* Cancel any pending transmissions */
01638       if (cur->callno == pvt->callno) { 
01639          cur->retries = -1;
01640       }
01641    }
01642    AST_LIST_UNLOCK(&frame_queue);
01643 
01644    while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01645       free_signaling_queue_entry(s);
01646    }
01647 
01648    if (pvt->reg) {
01649       pvt->reg->callno = 0;
01650    }
01651 
01652    if (!pvt->owner) {
01653       jb_frame frame;
01654       if (pvt->vars) {
01655           ast_variables_destroy(pvt->vars);
01656           pvt->vars = NULL;
01657       }
01658 
01659       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01660          iax2_frame_free(frame.data);
01661       }
01662 
01663       jb_destroy(pvt->jb);
01664       ast_string_field_free_memory(pvt);
01665    }
01666 }

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

Definition at line 13546 of file chan_iax2.c.

References chan_iax2_pvt::peercallno.

13547 {
13548    const struct chan_iax2_pvt *pvt = obj;
13549 
13550    return pvt->peercallno;
13551 }

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

References ast_calloc, AST_FRAME_IAX, AST_LIST_INSERT_TAIL, f, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_trunk_peer::next, and chan_iax2_pvt::signaling_queue.

Referenced by __send_command().

01597 {
01598    struct signaling_queue_entry *new;
01599 
01600    if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01601       return 1; /* do not queue this frame */
01602    } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01603       return -1;  /* out of memory */
01604    }
01605 
01606    memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */
01607 
01608    if (new->f.datalen) { /* if there is data in this frame copy it over as well */
01609       if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
01610          free_signaling_queue_entry(new);
01611          return -1;
01612       }
01613       memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
01614    }
01615    AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
01616 
01617    return 0;
01618 }

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

Definition at line 7264 of file chan_iax2.c.

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

Referenced by socket_process().

07265 {
07266    struct ast_iax2_full_hdr fh;
07267    fh.scallno = htons(src | IAX_FLAG_FULL);
07268    fh.dcallno = htons(dst);
07269    fh.ts = 0;
07270    fh.oseqno = 0;
07271    fh.iseqno = 0;
07272    fh.type = AST_FRAME_IAX;
07273    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07274    iax_outputframe(NULL, &fh, 0, sin, 0);
07275 #if 0
07276    if (option_debug)
07277 #endif   
07278       ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07279          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07280    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07281 }

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

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

References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.

04013 {
04014    struct ast_variable *var = NULL;
04015    struct ast_variable *tmp;
04016    struct iax2_peer *peer=NULL;
04017    time_t regseconds = 0, nowtime;
04018    int dynamic=0;
04019 
04020    if (peername) {
04021       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04022       if (!var && sin)
04023          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04024    } else if (sin) {
04025       char porta[25];
04026       sprintf(porta, "%d", ntohs(sin->sin_port));
04027       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04028       if (var) {
04029          /* We'll need the peer name in order to build the structure! */
04030          for (tmp = var; tmp; tmp = tmp->next) {
04031             if (!strcasecmp(tmp->name, "name"))
04032                peername = tmp->value;
04033          }
04034       }
04035    }
04036    if (!var && peername) { /* Last ditch effort */
04037       var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04038       /*!\note
04039        * If this one loaded something, then we need to ensure that the host
04040        * field matched.  The only reason why we can't have this as a criteria
04041        * is because we only have the IP address and the host field might be
04042        * set as a name (and the reverse PTR might not match).
04043        */
04044       if (var && sin) {
04045          for (tmp = var; tmp; tmp = tmp->next) {
04046             if (!strcasecmp(tmp->name, "host")) {
04047                struct ast_hostent ahp;
04048                struct hostent *hp;
04049                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04050                   /* No match */
04051                   ast_variables_destroy(var);
04052                   var = NULL;
04053                }
04054                break;
04055             }
04056          }
04057       }
04058    }
04059    if (!var)
04060       return NULL;
04061 
04062    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04063    
04064    if (!peer) {
04065       ast_variables_destroy(var);
04066       return NULL;
04067    }
04068 
04069    for (tmp = var; tmp; tmp = tmp->next) {
04070       /* Make sure it's not a user only... */
04071       if (!strcasecmp(tmp->name, "type")) {
04072          if (strcasecmp(tmp->value, "friend") &&
04073              strcasecmp(tmp->value, "peer")) {
04074             /* Whoops, we weren't supposed to exist! */
04075             peer = peer_unref(peer);
04076             break;
04077          } 
04078       } else if (!strcasecmp(tmp->name, "regseconds")) {
04079          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
04080       } else if (!strcasecmp(tmp->name, "ipaddr")) {
04081          inet_aton(tmp->value, &(peer->addr.sin_addr));
04082       } else if (!strcasecmp(tmp->name, "port")) {
04083          peer->addr.sin_port = htons(atoi(tmp->value));
04084       } else if (!strcasecmp(tmp->name, "host")) {
04085          if (!strcasecmp(tmp->value, "dynamic"))
04086             dynamic = 1;
04087       }
04088    }
04089 
04090    ast_variables_destroy(var);
04091 
04092    if (!peer)
04093       return NULL;
04094 
04095    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04096       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04097       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
04098          if (peer->expire > -1) {
04099             if (!ast_sched_del(sched, peer->expire)) {
04100                peer->expire = -1;
04101                peer_unref(peer);
04102             }
04103          }
04104          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04105          if (peer->expire == -1)
04106             peer_unref(peer);
04107       }
04108       ao2_link(peers, peer);
04109       if (ast_test_flag(peer, IAX_DYNAMIC))
04110          reg_source_db(peer);
04111    } else {
04112       ast_set_flag(peer, IAX_TEMPONLY);   
04113    }
04114 
04115    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04116       time(&nowtime);
04117       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04118          memset(&peer->addr, 0, sizeof(peer->addr));
04119          realtime_update_peer(peer->name, &peer->addr, 0);
04120          ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04121             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04122       }
04123       else {
04124          ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04125             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04126       }
04127    }
04128 
04129    return peer;
04130 }

static void realtime_update_peer ( const char *  peername,
struct sockaddr_in *  sin,
time_t  regtime 
) [static]

Definition at line 4203 of file chan_iax2.c.

References ast_inet_ntoa(), ast_update_realtime(), and SENTINEL.

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

04204 {
04205    char port[10];
04206    char regseconds[20];
04207    
04208    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04209    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
04210    ast_update_realtime("iaxpeers", "name", peername, 
04211       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
04212       "regseconds", regseconds, SENTINEL);
04213 }

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

Definition at line 4132 of file chan_iax2.c.

References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.

04133 {
04134    struct ast_variable *var;
04135    struct ast_variable *tmp;
04136    struct iax2_user *user=NULL;
04137 
04138    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04139    if (!var)
04140       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04141    if (!var && sin) {
04142       char porta[6];
04143       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04144       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04145       if (!var)
04146          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04147    }
04148    if (!var) { /* Last ditch effort */
04149       var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04150       /*!\note
04151        * If this one loaded something, then we need to ensure that the host
04152        * field matched.  The only reason why we can't have this as a criteria
04153        * is because we only have the IP address and the host field might be
04154        * set as a name (and the reverse PTR might not match).
04155        */
04156       if (var) {
04157          for (tmp = var; tmp; tmp = tmp->next) {
04158             if (!strcasecmp(tmp->name, "host")) {
04159                struct ast_hostent ahp;
04160                struct hostent *hp;
04161                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04162                   /* No match */
04163                   ast_variables_destroy(var);
04164                   var = NULL;
04165                }
04166                break;
04167             }
04168          }
04169       }
04170    }
04171    if (!var)
04172       return NULL;
04173 
04174    tmp = var;
04175    while(tmp) {
04176       /* Make sure it's not a peer only... */
04177       if (!strcasecmp(tmp->name, "type")) {
04178          if (strcasecmp(tmp->value, "friend") &&
04179              strcasecmp(tmp->value, "user")) {
04180             return NULL;
04181          } 
04182       }
04183       tmp = tmp->next;
04184    }
04185 
04186    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
04187 
04188    ast_variables_destroy(var);
04189 
04190    if (!user)
04191       return NULL;
04192 
04193    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04194       ast_set_flag(user, IAX_RTCACHEFRIENDS);
04195       ao2_link(users, user);
04196    } else {
04197       ast_set_flag(user, IAX_TEMPONLY);   
04198    }
04199 
04200    return user;
04201 }

static void reg_source_db ( struct iax2_peer p  )  [static]

Definition at line 8131 of file chan_iax2.c.

References iax2_peer::addr, ast_db_get(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_inet_ntoa(), ast_sched_del(), ast_test_flag, ast_verb, iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, inet_aton(), iax2_peer::name, peer_ref(), peer_unref(), register_peer_exten(), and sched.

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

08132 {
08133    char data[80];
08134    struct in_addr in;
08135    char *c, *d;
08136    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
08137       c = strchr(data, ':');
08138       if (c) {
08139          *c = '\0';
08140          c++;
08141          if (inet_aton(data, &in)) {
08142             d = strchr(c, ':');
08143             if (d) {
08144                *d = '\0';
08145                d++;
08146                ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name,
08147                   ast_inet_ntoa(in), atoi(c), atoi(d));
08148                iax2_poke_peer(p, 0);
08149                p->expiry = atoi(d);
08150                memset(&p->addr, 0, sizeof(p->addr));
08151                p->addr.sin_family = AF_INET;
08152                p->addr.sin_addr = in;
08153                p->addr.sin_port = htons(atoi(c));
08154                if (p->expire > -1) {
08155                   if (!ast_sched_del(sched, p->expire)) {
08156                      p->expire = -1;
08157                      peer_unref(p);
08158                   }
08159                }
08160                ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
08161                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08162                if (p->expire == -1)
08163                   peer_unref(p);
08164                if (iax2_regfunk)
08165                   iax2_regfunk(p->name, 1);
08166                register_peer_exten(p, 1);
08167             }              
08168                
08169          }
08170       }
08171    }
08172 }

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

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

08051 {
08052    char multi[256];
08053    char *stringp, *ext;
08054    if (!ast_strlen_zero(regcontext)) {
08055       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08056       stringp = multi;
08057       while((ext = strsep(&stringp, "&"))) {
08058          if (onoff) {
08059             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08060                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08061                        "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08062          } else
08063             ast_context_remove_extension(regcontext, ext, 1, NULL);
08064       }
08065    }
08066 }

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

Verify inbound registration.

Definition at line 7435 of file chan_iax2.c.

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

Referenced by handle_request_register(), and socket_process().

07436 {
07437    char requeststr[256] = "";
07438    char peer[256] = "";
07439    char md5secret[256] = "";
07440    char rsasecret[256] = "";
07441    char secret[256] = "";
07442    struct iax2_peer *p = NULL;
07443    struct ast_key *key;
07444    char *keyn;
07445    int x;
07446    int expire = 0;
07447    int res = -1;
07448 
07449    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07450    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
07451    if (ies->username)
07452       ast_copy_string(peer, ies->username, sizeof(peer));
07453    if (ies->password)
07454       ast_copy_string(secret, ies->password, sizeof(secret));
07455    if (ies->md5_result)
07456       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07457    if (ies->rsa_result)
07458       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07459    if (ies->refresh)
07460       expire = ies->refresh;
07461 
07462    if (ast_strlen_zero(peer)) {
07463       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07464       return -1;
07465    }
07466 
07467    /* SLD: first call to lookup peer during registration */
07468    ast_mutex_unlock(&iaxsl[callno]);
07469    p = find_peer(peer, 1);
07470    ast_mutex_lock(&iaxsl[callno]);
07471    if (!p || !iaxs[callno]) {
07472       if (iaxs[callno]) {
07473          int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07474          /* Anything, as long as it's non-blank */
07475          ast_string_field_set(iaxs[callno], secret, "badsecret");
07476          /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
07477           * 1. A challenge already exists indicating a AUTHREQ was already sent out.
07478           * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
07479           * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
07480           *    to be plaintext, indicating it is an authmethod used by other peers on the system. 
07481           *
07482           * If none of these cases exist, res will be returned as 0 without authentication indicating
07483           * an AUTHREQ needs to be sent out. */
07484 
07485          if (ast_strlen_zero(iaxs[callno]->challenge) &&
07486             !(!ast_strlen_zero(secret) && plaintext)) {
07487             /* by setting res to 0, an REGAUTH will be sent */
07488             res = 0;
07489          }
07490       }
07491       if (authdebug && !p)
07492          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07493       goto return_unref;
07494    }
07495 
07496    if (!ast_test_flag(p, IAX_DYNAMIC)) {
07497       if (authdebug)
07498          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07499       goto return_unref;
07500    }
07501 
07502    if (!ast_apply_ha(p->ha, sin)) {
07503       if (authdebug)
07504          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07505       goto return_unref;
07506    }
07507    ast_string_field_set(iaxs[callno], secret, p->secret);
07508    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
07509    /* Check secret against what we have on file */
07510    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07511       if (!ast_strlen_zero(p->inkeys)) {
07512          char tmpkeys[256];
07513          char *stringp=NULL;
07514          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
07515          stringp=tmpkeys;
07516          keyn = strsep(&stringp, ":");
07517          while(keyn) {
07518             key = ast_key_get(keyn, AST_KEY_PUBLIC);
07519             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
07520                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07521                break;
07522             } else if (!key)
07523                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
07524             keyn = strsep(&stringp, ":");
07525          }
07526          if (!keyn) {
07527             if (authdebug)
07528                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
07529             goto return_unref;
07530          }
07531       } else {
07532          if (authdebug)
07533             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
07534          goto return_unref;
07535       }
07536    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07537       struct MD5Context md5;
07538       unsigned char digest[16];
07539       char *tmppw, *stringp;
07540 
07541       tmppw = ast_strdupa(p->secret);
07542       stringp = tmppw;
07543       while((tmppw = strsep(&stringp, ";"))) {
07544          MD5Init(&md5);
07545          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
07546          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07547          MD5Final(digest, &md5);
07548          for (x=0;x<16;x++)
07549             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
07550          if (!strcasecmp(requeststr, md5secret))
07551             break;
07552       }
07553       if (tmppw) {
07554          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07555       } else {
07556          if (authdebug)
07557             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
07558          goto return_unref;
07559       }
07560    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
07561       /* They've provided a plain text password and we support that */
07562       if (strcmp(secret, p->secret)) {
07563          if (authdebug)
07564             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07565          goto return_unref;
07566       } else
07567          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07568    } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
07569       /* if challenge has been sent, but no challenge response if given, reject. */
07570       goto return_unref;
07571    }
07572    ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
07573 
07574    /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
07575    res = 0;
07576 
07577 return_unref:
07578    if (iaxs[callno]) {
07579       ast_string_field_set(iaxs[callno], peer, peer);
07580 
07581       /* Choose lowest expiry number */
07582       if (expire && (expire < iaxs[callno]->expiry)) {
07583          iaxs[callno]->expiry = expire;
07584       }
07585    }
07586 
07587    if (p) {
07588       peer_unref(p);
07589    }
07590    return res;
07591 }

static int registry_authrequest ( int  callno  )  [static]

Definition at line 8339 of file chan_iax2.c.

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

Referenced by socket_process().

08340 {
08341    struct iax_ie_data ied;
08342    struct iax2_peer *p;
08343    char challenge[10];
08344    const char *peer_name;
08345    int sentauthmethod;
08346 
08347    peer_name = ast_strdupa(iaxs[callno]->peer);
08348 
08349    /* SLD: third call to find_peer in registration */
08350    ast_mutex_unlock(&iaxsl[callno]);
08351    if ((p = find_peer(peer_name, 1))) {
08352       last_authmethod = p->authmethods;
08353    }
08354 
08355    ast_mutex_lock(&iaxsl[callno]);
08356    if (!iaxs[callno])
08357       goto return_unref;
08358 
08359    memset(&ied, 0, sizeof(ied));
08360    /* The selection of which delayed reject is sent may leak information,
08361     * if it sets a static response.  For example, if a host is known to only
08362     * use MD5 authentication, then an RSA response would indicate that the
08363     * peer does not exist, and vice-versa.
08364     * Therefore, we use whatever the last peer used (which may vary over the
08365     * course of a server, which should leak minimal information). */
08366    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08367    if (!p) {
08368       iaxs[callno]->authmethods = sentauthmethod;
08369    }
08370    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08371    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08372       /* Build the challenge */
08373       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08374       ast_string_field_set(iaxs[callno], challenge, challenge);
08375       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08376    }
08377    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08378 
08379 return_unref:
08380    if (p) {
08381       peer_unref(p);
08382    }
08383 
08384    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08385 }

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

Definition at line 8387 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_strlen_zero(), authenticate(), iax_ies::authmethods, iax_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.

Referenced by socket_process().

08388 {
08389    struct iax2_registry *reg;
08390    /* Start pessimistic */
08391    struct iax_ie_data ied;
08392    char peer[256] = "";
08393    char challenge[256] = "";
08394    int res;
08395    int authmethods = 0;
08396    if (ies->authmethods)
08397       authmethods = ies->authmethods;
08398    if (ies->username)
08399       ast_copy_string(peer, ies->username, sizeof(peer));
08400    if (ies->challenge)
08401       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08402    memset(&ied, 0, sizeof(ied));
08403    reg = iaxs[callno]->reg;
08404    if (reg) {
08405          if (inaddrcmp(&reg->addr, sin)) {
08406             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08407             return -1;
08408          }
08409          if (ast_strlen_zero(reg->secret)) {
08410             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08411             reg->regstate = REG_STATE_NOAUTH;
08412             return -1;
08413          }
08414          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08415          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08416          if (reg->secret[0] == '[') {
08417             char tmpkey[256];
08418             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08419             tmpkey[strlen(tmpkey) - 1] = '\0';
08420             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08421          } else
08422             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08423          if (!res) {
08424             reg->regstate = REG_STATE_AUTHSENT;
08425             add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
08426             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08427          } else
08428             return -1;
08429          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08430    } else   
08431       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08432    return -1;
08433 }

static char* regstate2str ( int  regstate  )  [static]

Definition at line 6602 of file chan_iax2.c.

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

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

06603 {
06604    switch(regstate) {
06605    case REG_STATE_UNREGISTERED:
06606       return "Unregistered";
06607    case REG_STATE_REGSENT:
06608       return "Request Sent";
06609    case REG_STATE_AUTHSENT:
06610       return "Auth. Sent";
06611    case REG_STATE_REGISTERED:
06612       return "Registered";
06613    case REG_STATE_REJECTED:
06614       return "Rejected";
06615    case REG_STATE_TIMEOUT:
06616       return "Timeout";
06617    case REG_STATE_NOAUTH:
06618       return "No Authentication";
06619    default:
06620       return "Unknown";
06621    }
06622 }

static int reload ( void   )  [static]

Definition at line 12808 of file chan_iax2.c.

References reload_config().

12809 {
12810    return reload_config();
12811 }

static int reload_config ( void   )  [static]

Definition at line 12759 of file chan_iax2.c.

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

12760 {
12761    static const char config[] = "iax.conf";
12762    struct iax2_registry *reg;
12763 
12764    if (set_config(config, 1) > 0) {
12765       prune_peers();
12766       prune_users();
12767       ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
12768       ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
12769       ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
12770       trunk_timed = trunk_untimed = 0; 
12771       trunk_nmaxmtu = trunk_maxmtu = 0;
12772       memset(&debugaddr, '\0', sizeof(debugaddr));
12773 
12774       AST_LIST_LOCK(&registrations);
12775       AST_LIST_TRAVERSE(&registrations, reg, entry)
12776          iax2_do_register(reg);
12777       AST_LIST_UNLOCK(&registrations);
12778 
12779       /* Qualify hosts, too */
12780       poke_all_peers();
12781    }
12782    
12783    reload_firmware(0);
12784    iax_provision_reload(1);
12785    ast_unload_realtime("iaxpeers");
12786 
12787    return 0;
12788 }

static void reload_firmware ( int  unload  )  [static]

Definition at line 2957 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(), dir, errno, iax2_trunk_peer::list, LOG_WARNING, and try_firmware().

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

02958 {
02959    struct iax_firmware *cur = NULL;
02960    DIR *fwd;
02961    struct dirent *de;
02962    char dir[256], fn[256];
02963 
02964    AST_LIST_LOCK(&firmwares);
02965 
02966    /* Mark all as dead */
02967    AST_LIST_TRAVERSE(&firmwares, cur, list)
02968       cur->dead = 1;
02969 
02970    /* Now that we have marked them dead... load new ones */
02971    if (!unload) {
02972       snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
02973       fwd = opendir(dir);
02974       if (fwd) {
02975          while((de = readdir(fwd))) {
02976             if (de->d_name[0] != '.') {
02977                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02978                if (!try_firmware(fn)) {
02979                   ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
02980                }
02981             }
02982          }
02983          closedir(fwd);
02984       } else 
02985          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02986    }
02987 
02988    /* Clean up leftovers */
02989    AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
02990       if (!cur->dead)
02991          continue;
02992       AST_LIST_REMOVE_CURRENT(list);
02993       destroy_firmware(cur);
02994    }
02995    AST_LIST_TRAVERSE_SAFE_END;
02996 
02997    AST_LIST_UNLOCK(&firmwares);
02998 }

static void remove_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1877 of file chan_iax2.c.

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

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

01878 {
01879    if (!pvt->peercallno) {
01880       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01881       return;
01882    }
01883 
01884    ao2_unlink(iax_peercallno_pvts, pvt);
01885 }

static void remove_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1858 of file chan_iax2.c.

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

Referenced by complete_transfer(), and iax2_destroy().

01859 {
01860    if (!pvt->transfercallno) {
01861       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01862       return;
01863    }
01864 
01865    ao2_unlink(iax_transfercallno_pvts, pvt);
01866 }

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

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

02364 {
02365    struct callno_entry *callno_entry = (struct callno_entry *) obj;
02366 
02367    /* the callno_pool container is locked here primarily to ensure thread
02368     * safety of the total_nonval_callno_used check and decrement */
02369    ao2_lock(callno_pool);
02370 
02371    if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02372       total_nonval_callno_used--;
02373    } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02374       ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02375    }
02376 
02377    if (callno_entry->callno < TRUNK_CALL_START) {
02378       ao2_link(callno_pool, callno_entry);
02379    } else {
02380       ao2_link(callno_pool_trunk, callno_entry);
02381    }
02382    ao2_ref(callno_entry, -1); /* only container ref remains */
02383 
02384    ao2_unlock(callno_pool);
02385    return 0;
02386 }

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

Definition at line 4491 of file chan_iax2.c.

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

Referenced by handle_call_token().

04492 {
04493    struct iax2_user *user = NULL;
04494    struct iax2_peer *peer = NULL;
04495 
04496    if (ast_strlen_zero(name)) {
04497       return; /* no username given */
04498    }
04499 
04500    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04501       user->calltoken_required = CALLTOKEN_YES;
04502    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04503       peer->calltoken_required = CALLTOKEN_YES;
04504    }
04505 
04506    if (peer) {
04507       peer_unref(peer);
04508    }
04509    if (user) {
04510       user_unref(user);
04511    }
04512 }

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

Definition at line 4407 of file chan_iax2.c.

References chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, iax_ie_data::buf, chan_iax2_pvt::calltoken_ie_len, f, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, remove_by_peercallno(), chan_iax2_pvt::rseqno, and send_command().

Referenced by socket_process().

04408 {
04409    struct chan_iax2_pvt *pvt = iaxs[callno];
04410    int frametype = f->af.frametype;
04411    int subclass = f->af.subclass;
04412    struct {
04413       struct ast_iax2_full_hdr fh;
04414       struct iax_ie_data ied;
04415    } data = {
04416       .ied.buf = { 0 },
04417       .ied.pos = 0,
04418    };
04419    /* total len - header len gives us the frame's IE len */
04420    int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04421 
04422    if (!pvt) {
04423       return;  /* this should not be possible if called from socket_process() */
04424    }
04425 
04426    /* 
04427     * Check to make sure last frame sent is valid for call token resend
04428     * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 
04429     * 2. Frame should _NOT_ already have a destination callno
04430     * 3. Frame must be a valid iax_frame subclass capable of starting dialog
04431     * 4. Pvt must have a calltoken_ie_len which represents the number of
04432     *    bytes at the end of the frame used for the previous calltoken ie.
04433     * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length
04434     * 6. Total length of f->data must be _LESS_ than size of our data struct
04435     *    because f->data must be able to fit within data. 
04436     */
04437    if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04438       || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04439       (f->datalen > sizeof(data))) {
04440 
04441       return;  /* ignore resend, token was not valid for the dialog */
04442    }
04443 
04444    /* token is valid
04445     * 1. Copy frame data over
04446     * 2. Redo calltoken IE, it will always be the last ie in the frame.
04447     *    NOTE: Having the ie always be last is not protocol specified,
04448     *    it is only an implementation choice.  Since we only expect the ie to
04449     *    be last for frames we have sent, this can no way be affected by
04450     *    another end point.
04451     * 3. Remove frame from queue
04452     * 4. Free old frame
04453     * 5. Clear previous seqnos
04454     * 6. Resend with CALLTOKEN ie.
04455     */
04456 
04457    /* ---1.--- */
04458    memcpy(&data, f->data, f->datalen);
04459    data.ied.pos = ie_data_pos;
04460 
04461    /* ---2.--- */
04462    /* move to the beginning of the calltoken ie so we can write over it */
04463    data.ied.pos -= pvt->calltoken_ie_len;
04464    iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04465 
04466    /* make sure to update token length incase it ever has to be stripped off again */
04467    pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */
04468 
04469    /* ---3.--- */
04470    AST_LIST_LOCK(&frame_queue);
04471    AST_LIST_REMOVE(&frame_queue, f, list);
04472    AST_LIST_UNLOCK(&frame_queue);
04473 
04474    /* ---4.--- */
04475    iax2_frame_free(f);
04476 
04477    /* ---5.--- */
04478    pvt->oseqno = 0;
04479    pvt->rseqno = 0;
04480    pvt->iseqno = 0;
04481    pvt->aseqno = 0;
04482    if (pvt->peercallno) {
04483       remove_by_peercallno(pvt);
04484       pvt->peercallno = 0;
04485    }
04486 
04487    /* ---6.--- */
04488    send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04489 }

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

Definition at line 8868 of file chan_iax2.c.

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

Referenced by socket_process().

08869 {
08870    int i;
08871    unsigned int length, offset = 0;
08872    char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
08873 
08874    for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
08875       length = ies->ospblocklength[i];
08876       if (length != 0) {
08877          if (length > IAX_MAX_OSPBLOCK_SIZE) {
08878             /* OSP token block length wrong, clear buffer */
08879             offset = 0;
08880             break;
08881          } else {
08882             memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
08883             offset += length;
08884          }
08885       } else {
08886          break;
08887       }
08888    }
08889    *(full_osptoken + offset) = '\0';
08890    if (strlen(full_osptoken) != offset) {
08891       /* OSP token length wrong, clear buffer */
08892       *full_osptoken = '\0';
08893    }
08894 
08895    ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
08896 }

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

Definition at line 8857 of file chan_iax2.c.

References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::remote_rr, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, and iax_ies::rr_pkts.

Referenced by socket_process().

08858 {
08859    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
08860    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
08861    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
08862    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
08863    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
08864    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
08865    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
08866 }

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

Definition at line 2435 of file chan_iax2.c.

References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), iax2_sched_add(), MIN_REUSE_TIME, OBJ_POINTER, peercnt_remove_cb(), peercnts, replace_callno(), and sched.

Referenced by pvt_destructor().

02436 {
02437    int i;
02438    struct peercnt *peercnt;
02439    struct peercnt tmp = {
02440       .addr = sin->sin_addr.s_addr,
02441    };
02442 
02443    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02444       /* refcount is incremented with ao2_find.  keep that ref for the scheduler */
02445       ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02446       i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02447       if (i == -1) {
02448          ao2_ref(peercnt, -1);
02449       }
02450    }
02451 
02452    iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02453 }

static void* sched_thread ( void *  ignore  )  [static]

Definition at line 11472 of file chan_iax2.c.

References ast_cond_timedwait(), ast_debug, ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), ast_tvnow(), sched, and sched_lock.

11473 {
11474    int count;
11475    int res;
11476    struct timeval wait;
11477    struct timespec ts;
11478 
11479    for (;;) {
11480       pthread_testcancel();
11481       ast_mutex_lock(&sched_lock);
11482       res = ast_sched_wait(sched);
11483       if ((res > 1000) || (res < 0))
11484          res = 1000;
11485       wait = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
11486       ts.tv_sec = wait.tv_sec;
11487       ts.tv_nsec = wait.tv_usec * 1000;
11488       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
11489       ast_mutex_unlock(&sched_lock);
11490       pthread_testcancel();
11491 
11492       count = ast_sched_runq(sched);
11493       if (count >= 20)
11494          ast_debug(1, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
11495    }
11496 
11497    return NULL;
11498 }

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

References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_samp2tv(), AST_SCHED_DEL, ast_test_flag, ast_tv(), ast_tvadd(), ast_tvzero(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, ast_channel_tech::properties, sched, ast_frame::subclass, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().

Referenced by socket_process(), and socket_process_meta().

03868 {
03869    int type, len;
03870    int ret;
03871    int needfree = 0;
03872    struct ast_channel *owner = NULL;
03873    struct ast_channel *bridge = NULL;
03874    
03875    /* Attempt to recover wrapped timestamps */
03876    unwrap_timestamp(fr);
03877 
03878    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
03879    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
03880       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
03881    else {
03882 #if 0
03883       ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
03884 #endif
03885       fr->af.delivery = ast_tv(0,0);
03886    }
03887 
03888    type = JB_TYPE_CONTROL;
03889    len = 0;
03890 
03891    if(fr->af.frametype == AST_FRAME_VOICE) {
03892       type = JB_TYPE_VOICE;
03893       len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000);
03894    } else if(fr->af.frametype == AST_FRAME_CNG) {
03895       type = JB_TYPE_SILENCE;
03896    }
03897 
03898    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
03899       if (tsout)
03900          *tsout = fr->ts;
03901       __do_deliver(fr);
03902       return -1;
03903    }
03904 
03905    if ((owner = iaxs[fr->callno]->owner))
03906       bridge = ast_bridged_channel(owner);
03907 
03908    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
03909     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
03910    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
03911       jb_frame frame;
03912 
03913       /* deliver any frames in the jb */
03914       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
03915          __do_deliver(frame.data);
03916          /* __do_deliver() can make the call disappear */
03917          if (!iaxs[fr->callno])
03918             return -1;
03919       }
03920 
03921       jb_reset(iaxs[fr->callno]->jb);
03922 
03923       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
03924 
03925       /* deliver this frame now */
03926       if (tsout)
03927          *tsout = fr->ts;
03928       __do_deliver(fr);
03929       return -1;
03930    }
03931 
03932    /* insert into jitterbuffer */
03933    /* TODO: Perhaps we could act immediately if it's not droppable and late */
03934    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
03935          calc_rxstamp(iaxs[fr->callno],fr->ts));
03936    if (ret == JB_DROP) {
03937       needfree++;
03938    } else if (ret == JB_SCHED) {
03939       update_jbsched(iaxs[fr->callno]);
03940    }
03941    if (tsout)
03942       *tsout = fr->ts;
03943    if (needfree) {
03944       /* Free our iax frame */
03945       iax2_frame_free(fr);
03946       return -1;
03947    }
03948    return 0;
03949 }

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

Definition at line 1561 of file chan_iax2.c.

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

Referenced by iax2_hangup().

01562 {
01563    unsigned short callno = PTR_TO_CALLNO(vid);
01564    ast_mutex_lock(&iaxsl[callno]);
01565    if (iaxs[callno]) {
01566       if (option_debug) {
01567          ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01568       }
01569       iax2_destroy(callno);
01570    }
01571    ast_mutex_unlock(&iaxsl[callno]);
01572    return 0;
01573 }

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

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

Referenced by handle_call_token(), and socket_process().

04374 {
04375    struct {
04376       struct ast_iax2_full_hdr f;
04377       struct iax_ie_data ied;
04378    } data;
04379    size_t size = sizeof(struct ast_iax2_full_hdr);
04380 
04381    if (ied) {
04382       size += ied->pos;
04383       memcpy(&data.ied, ied->buf, ied->pos);
04384    }
04385 
04386    data.f.scallno = htons(0x8000 | callno);
04387    data.f.dcallno = htons(dcallno);
04388    data.f.ts = htonl(ts);
04389    data.f.iseqno = seqno;
04390    data.f.oseqno = 0;
04391    data.f.type = AST_FRAME_IAX;
04392    data.f.csub = compress_subclass(command);
04393 
04394    return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04395 }

static int send_command ( struct chan_iax2_pvt ,
char  ,
int  ,
unsigned  int,
const unsigned char *  ,
int  ,
int   
) [static]

Definition at line 6987 of file chan_iax2.c.

References __send_command().

Referenced by __attempt_transmit(), __send_lagrq(), __send_ping(), authenticate_reply(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_indicate(), iax2_key_rotate(), iax2_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), resend_with_token(), send_command_locked(), and socket_process().

06988 {
06989    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
06990 }

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

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

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

07007 {
07008    int call_num = i->callno;
07009    /* It is assumed that the callno has already been locked */
07010    iax2_predestroy(i->callno);
07011    if (!iaxs[call_num])
07012       return -1;
07013    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07014 }

static int send_command_immediate ( struct chan_iax2_pvt ,
char  ,
int  ,
unsigned  int,
const unsigned char *  ,
int  ,
int   
) [static]

Definition at line 7016 of file chan_iax2.c.

References __send_command().

Referenced by iax2_vnak(), and socket_process().

07017 {
07018    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07019 }

static int send_command_locked ( unsigned short  callno,
char  ,
int  ,
unsigned  int,
const unsigned char *  ,
int  ,
int   
) [static]

Definition at line 6992 of file chan_iax2.c.

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

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

06993 {
06994    int res;
06995    ast_mutex_lock(&iaxsl[callno]);
06996    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
06997    ast_mutex_unlock(&iaxsl[callno]);
06998    return res;
06999 }

static int send_command_transfer ( struct chan_iax2_pvt ,
char  ,
int  ,
unsigned  int,
const unsigned char *  ,
int   
) [static]

Definition at line 7021 of file chan_iax2.c.

References __send_command().

Referenced by socket_process(), and try_transfer().

07022 {
07023    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07024 }

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

Definition at line 1359 of file chan_iax2.c.

References __send_lagrq(), and schedule_action.

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

01360 {
01361 #ifdef SCHED_MULTITHREADED
01362    if (schedule_action(__send_lagrq, data))
01363 #endif      
01364       __send_lagrq(data);
01365    
01366    return 0;
01367 }

static int send_packet ( struct iax_frame f  )  [static]

Definition at line 3070 of file chan_iax2.c.

References chan_iax2_pvt::addr, ast_debug, ast_inet_ntoa(), errno, f, handle_error(), iax_showframe(), iaxs, chan_iax2_pvt::peercallno, iax2_trunk_peer::sockfd, and chan_iax2_pvt::transfer.

Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().

03071 {
03072    int res;
03073    int callno = f->callno;
03074 
03075    /* Don't send if there was an error, but return error instead */
03076    if (!callno || !iaxs[callno] || iaxs[callno]->error)
03077        return -1;
03078    
03079    /* Called with iaxsl held */
03080    if (iaxdebug)
03081       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));
03082    
03083    if (f->transfer) {
03084       if (iaxdebug)
03085          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03086       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03087    } else {
03088       if (iaxdebug)
03089          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03090       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03091    }
03092    if (res < 0) {
03093       if (iaxdebug)
03094          ast_debug(1, "Received error: %s\n", strerror(errno));
03095       handle_error();
03096    } else
03097       res = 0;
03098 
03099    return res;
03100 }

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

Definition at line 1314 of file chan_iax2.c.

References __send_ping(), and schedule_action.

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

01315 {
01316 #ifdef SCHED_MULTITHREADED
01317    if (schedule_action(__send_ping, data))
01318 #endif      
01319       __send_ping(data);
01320 
01321    return 0;
01322 }

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

References AST_LIST_REMOVE_HEAD, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_send(), iax2_trunk_peer::next, s, and chan_iax2_pvt::signaling_queue.

Referenced by socket_process().

01584 {
01585    struct signaling_queue_entry *s = NULL;
01586 
01587    while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01588       iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01589       free_signaling_queue_entry(s);
01590    }
01591    pvt->hold_signaling = 0;
01592 }

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

Definition at line 8570 of file chan_iax2.c.

References iax2_trunk_peer::addr, iax_frame::afdata, ast_debug, ast_inet_ntoa(), ast_test_flag, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.

Referenced by iax2_trunk_queue(), and timing_read().

08571 {
08572    int res = 0;
08573    struct iax_frame *fr;
08574    struct ast_iax2_meta_hdr *meta;
08575    struct ast_iax2_meta_trunk_hdr *mth;
08576    int calls = 0;
08577    
08578    /* Point to frame */
08579    fr = (struct iax_frame *)tpeer->trunkdata;
08580    /* Point to meta data */
08581    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
08582    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
08583    if (tpeer->trunkdatalen) {
08584       /* We're actually sending a frame, so fill the meta trunk header and meta header */
08585       meta->zeros = 0;
08586       meta->metacmd = IAX_META_TRUNK;
08587       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
08588          meta->cmddata = IAX_META_TRUNK_MINI;
08589       else
08590          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
08591       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
08592       /* And the rest of the ast_iax2 header */
08593       fr->direction = DIRECTION_OUTGRESS;
08594       fr->retrans = -1;
08595       fr->transfer = 0;
08596       /* Any appropriate call will do */
08597       fr->data = fr->afdata;
08598       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
08599       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
08600       calls = tpeer->calls;
08601 #if 0
08602       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));
08603 #endif      
08604       /* Reset transmit trunk side data */
08605       tpeer->trunkdatalen = 0;
08606       tpeer->calls = 0;
08607    }
08608    if (res < 0)
08609       return res;
08610    return calls;
08611 }

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

Load configuration.

Definition at line 12326 of file chan_iax2.c.

References add_calltoken_ignore(), ao2_link, ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_context_find_or_create(), ast_copy_string(), ast_false(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, build_callno_limits(), build_peer(), build_user(), capability, CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), globalflags, iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_ENCRYPT_KEYROTATE, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, io, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_TRUNK_MTU, MAX_TRUNKDATA, ast_variable::name, netsock, ast_variable::next, outsock, peer_unref(), peers, prefs, qos, reg_source_db(), secret, set_config_destroy(), socket_read(), user, user_unref(), users, and ast_variable::value.

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

12327 {
12328    struct ast_config *cfg, *ucfg;
12329    int capability=iax2_capability;
12330    struct ast_variable *v;
12331    char *cat;
12332    const char *utype;
12333    const char *tosval;
12334    int format;
12335    int portno = IAX_DEFAULT_PORTNO;
12336    int  x;
12337    int mtuv; 
12338    struct iax2_user *user;
12339    struct iax2_peer *peer;
12340    struct ast_netsock *ns;
12341    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
12342 #if 0
12343    static unsigned short int last_port=0;
12344 #endif
12345 
12346    cfg = ast_config_load(config_file, config_flags);
12347 
12348    if (!cfg) {
12349       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
12350       return -1;
12351    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
12352       ucfg = ast_config_load("users.conf", config_flags);
12353       if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
12354          return 0;
12355       /* Otherwise we need to reread both files */
12356       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12357       cfg = ast_config_load(config_file, config_flags);
12358    } else { /* iax.conf changed, gotta reread users.conf, too */
12359       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12360       ucfg = ast_config_load("users.conf", config_flags);
12361    }
12362 
12363    if (reload) {
12364       set_config_destroy();
12365    }
12366 
12367    /* Reset global codec prefs */   
12368    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
12369 
12370    /* Reset Global Flags */
12371    memset(&globalflags, 0, sizeof(globalflags));
12372    ast_set_flag(&globalflags, IAX_RTUPDATE);
12373    ast_set_flag(&globalflags, IAX_SHRINKCALLERID);
12374 
12375    /* Turns on support for key rotation during encryption. */
12376    iax2_encryption |= IAX_ENCRYPT_KEYROTATE;
12377 #ifdef SO_NO_CHECK
12378    nochecksums = 0;
12379 #endif
12380    /* Reset default parking lot */
12381    default_parkinglot[0] = '\0';
12382 
12383    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12384    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12385    global_max_trunk_mtu = MAX_TRUNK_MTU;
12386    global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
12387    global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
12388 
12389    maxauthreq = 3;
12390 
12391    srvlookup = 0;
12392 
12393    v = ast_variable_browse(cfg, "general");
12394 
12395    /* Seed initial tos value */
12396    tosval = ast_variable_retrieve(cfg, "general", "tos");
12397    if (tosval) {
12398       if (ast_str2tos(tosval, &qos.tos))
12399          ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
12400    }
12401    /* Seed initial cos value */
12402    tosval = ast_variable_retrieve(cfg, "general", "cos");
12403    if (tosval) {
12404       if (ast_str2cos(tosval, &qos.cos))
12405          ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
12406    }
12407    while(v) {
12408       if (!strcasecmp(v->name, "bindport")){ 
12409          if (reload)
12410             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
12411          else
12412             portno = atoi(v->value);
12413       } else if (!strcasecmp(v->name, "pingtime")) 
12414          ping_time = atoi(v->value);
12415       else if (!strcasecmp(v->name, "iaxthreadcount")) {
12416          if (reload) {
12417             if (atoi(v->value) != iaxthreadcount)
12418                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
12419          } else {
12420             iaxthreadcount = atoi(v->value);
12421             if (iaxthreadcount < 1) {
12422                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
12423                iaxthreadcount = 1;
12424             } else if (iaxthreadcount > 256) {
12425                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
12426                iaxthreadcount = 256;
12427             }
12428          }
12429       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
12430          if (reload) {
12431             AST_LIST_LOCK(&dynamic_list);
12432             iaxmaxthreadcount = atoi(v->value);
12433             AST_LIST_UNLOCK(&dynamic_list);
12434          } else {
12435             iaxmaxthreadcount = atoi(v->value);
12436             if (iaxmaxthreadcount < 0) {
12437                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
12438                iaxmaxthreadcount = 0;
12439             } else if (iaxmaxthreadcount > 256) {
12440                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
12441                iaxmaxthreadcount = 256;
12442             }
12443          }
12444       } else if (!strcasecmp(v->name, "nochecksums")) {
12445 #ifdef SO_NO_CHECK
12446          if (ast_true(v->value))
12447             nochecksums = 1;
12448          else
12449             nochecksums = 0;
12450 #else
12451          if (ast_true(v->value))
12452             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
12453 #endif
12454       }
12455       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
12456          maxjitterbuffer = atoi(v->value);
12457       else if (!strcasecmp(v->name, "resyncthreshold")) 
12458          resyncthreshold = atoi(v->value);
12459       else if (!strcasecmp(v->name, "maxjitterinterps")) 
12460          maxjitterinterps = atoi(v->value);
12461       else if (!strcasecmp(v->name, "jittertargetextra"))
12462          jittertargetextra = atoi(v->value);
12463       else if (!strcasecmp(v->name, "lagrqtime")) 
12464          lagrq_time = atoi(v->value);
12465       else if (!strcasecmp(v->name, "maxregexpire")) 
12466          max_reg_expire = atoi(v->value);
12467       else if (!strcasecmp(v->name, "minregexpire")) 
12468          min_reg_expire = atoi(v->value);
12469       else if (!strcasecmp(v->name, "bindaddr")) {
12470          if (reload) {
12471             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
12472          } else {
12473             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
12474                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
12475             } else {
12476                   if (strchr(v->value, ':'))
12477                   ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
12478                   else
12479                   ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
12480                if (defaultsockfd < 0) 
12481                   defaultsockfd = ast_netsock_sockfd(ns);
12482                ast_netsock_unref(ns);
12483             }
12484          }
12485       } else if (!strcasecmp(v->name, "authdebug"))
12486          authdebug = ast_true(v->value);
12487       else if (!strcasecmp(v->name, "encryption"))
12488          iax2_encryption |= get_encrypt_methods(v->value);
12489       else if (!strcasecmp(v->name, "transfer")) {
12490          if (!strcasecmp(v->value, "mediaonly")) {
12491             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
12492          } else if (ast_true(v->value)) {
12493             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12494          } else 
12495             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12496       } else if (!strcasecmp(v->name, "codecpriority")) {
12497          if(!strcasecmp(v->value, "caller"))
12498             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
12499          else if(!strcasecmp(v->value, "disabled"))
12500             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12501          else if(!strcasecmp(v->value, "reqonly")) {
12502             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
12503             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12504          }
12505       } else if (!strcasecmp(v->name, "jitterbuffer"))
12506          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
12507       else if (!strcasecmp(v->name, "forcejitterbuffer"))
12508          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
12509       else if (!strcasecmp(v->name, "delayreject"))
12510          delayreject = ast_true(v->value);
12511       else if (!strcasecmp(v->name, "allowfwdownload"))
12512          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
12513       else if (!strcasecmp(v->name, "rtcachefriends"))
12514          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
12515       else if (!strcasecmp(v->name, "rtignoreregexpire"))
12516          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
12517       else if (!strcasecmp(v->name, "rtupdate"))
12518          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
12519       else if (!strcasecmp(v->name, "trunktimestamps"))
12520          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
12521       else if (!strcasecmp(v->name, "rtautoclear")) {
12522          int i = atoi(v->value);
12523          if(i > 0)
12524             global_rtautoclear = i;
12525          else
12526             i = 0;
12527          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
12528       } else if (!strcasecmp(v->name, "trunkfreq")) {
12529          trunkfreq = atoi(v->value);
12530          if (trunkfreq < 10)
12531             trunkfreq = 10;
12532       } else if (!strcasecmp(v->name, "trunkmtu")) {
12533          mtuv = atoi(v->value);
12534          if (mtuv  == 0 )  
12535             global_max_trunk_mtu = 0; 
12536          else if (mtuv >= 172 && mtuv < 4000) 
12537             global_max_trunk_mtu = mtuv; 
12538          else 
12539             ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
12540                mtuv, v->lineno);
12541       } else if (!strcasecmp(v->name, "trunkmaxsize")) {
12542          trunkmaxsize = atoi(v->value);
12543          if (trunkmaxsize == 0)
12544             trunkmaxsize = MAX_TRUNKDATA;
12545       } else if (!strcasecmp(v->name, "autokill")) {
12546          if (sscanf(v->value, "%30d", &x) == 1) {
12547             if (x >= 0)
12548                autokill = x;
12549             else
12550                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
12551          } else if (ast_true(v->value)) {
12552             autokill = DEFAULT_MAXMS;
12553          } else {
12554             autokill = 0;
12555          }
12556       } else if (!strcasecmp(v->name, "bandwidth")) {
12557          if (!strcasecmp(v->value, "low")) {
12558             capability = IAX_CAPABILITY_LOWBANDWIDTH;
12559          } else if (!strcasecmp(v->value, "medium")) {
12560             capability = IAX_CAPABILITY_MEDBANDWIDTH;
12561          } else if (!strcasecmp(v->value, "high")) {
12562             capability = IAX_CAPABILITY_FULLBANDWIDTH;
12563          } else
12564             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
12565       } else if (!strcasecmp(v->name, "allow")) {
12566          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
12567       } else if (!strcasecmp(v->name, "disallow")) {
12568          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
12569       } else if (!strcasecmp(v->name, "register")) {
12570          iax2_register(v->value, v->lineno);
12571       } else if (!strcasecmp(v->name, "iaxcompat")) {
12572          iaxcompat = ast_true(v->value);
12573       } else if (!strcasecmp(v->name, "regcontext")) {
12574          ast_copy_string(regcontext, v->value, sizeof(regcontext));
12575          /* Create context if it doesn't exist already */
12576          ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
12577       } else if (!strcasecmp(v->name, "tos")) {
12578          if (ast_str2tos(v->value, &qos.tos))
12579             ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
12580       } else if (!strcasecmp(v->name, "cos")) {
12581          if (ast_str2cos(v->value, &qos.cos))
12582             ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
12583       } else if (!strcasecmp(v->name, "parkinglot")) {
12584          ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
12585       } else if (!strcasecmp(v->name, "accountcode")) {
12586          ast_copy_string(accountcode, v->value, sizeof(accountcode));
12587       } else if (!strcasecmp(v->name, "mohinterpret")) {
12588          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
12589       } else if (!strcasecmp(v->name, "mohsuggest")) {
12590          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
12591       } else if (!strcasecmp(v->name, "amaflags")) {
12592          format = ast_cdr_amaflags2int(v->value);
12593          if (format < 0) {
12594             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12595          } else {
12596             amaflags = format;
12597          }
12598       } else if (!strcasecmp(v->name, "language")) {
12599          ast_copy_string(language, v->value, sizeof(language));
12600       } else if (!strcasecmp(v->name, "maxauthreq")) {
12601          maxauthreq = atoi(v->value);
12602          if (maxauthreq < 0)
12603             maxauthreq = 0;
12604       } else if (!strcasecmp(v->name, "adsi")) {
12605          adsi = ast_true(v->value);
12606       } else if (!strcasecmp(v->name, "srvlookup")) {
12607          srvlookup = ast_true(v->value);
12608       } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12609          if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
12610             ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number.  %s is not valid at line %d\n", v->value, v->lineno);
12611          }
12612       } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
12613          if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
12614             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);
12615          }
12616       } else if (!strcasecmp(v->name, "calltokenoptional")) {
12617          if (add_calltoken_ignore(v->value)) {
12618             ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
12619          }
12620       } else if (!strcasecmp(v->name, "shrinkcallerid")) {
12621          if (ast_true(v->value)) {
12622             ast_set_flag((&globalflags), IAX_SHRINKCALLERID);
12623          } else if (ast_false(v->value)) {
12624             ast_clear_flag((&globalflags), IAX_SHRINKCALLERID);
12625          } else {
12626             ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
12627          }
12628       }/*else if (strcasecmp(v->name,"type")) */
12629       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
12630       v = v->next;
12631    }
12632    
12633    if (defaultsockfd < 0) {
12634       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
12635          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
12636       } else {
12637          ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
12638          defaultsockfd = ast_netsock_sockfd(ns);
12639          ast_netsock_unref(ns);
12640       }
12641    }
12642    if (reload) {
12643       ast_netsock_release(outsock);
12644       outsock = ast_netsock_list_alloc();
12645       if (!outsock) {
12646          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12647          return -1;
12648       }
12649       ast_netsock_init(outsock);
12650    }
12651 
12652    if (min_reg_expire > max_reg_expire) {
12653       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
12654          min_reg_expire, max_reg_expire, max_reg_expire);
12655       min_reg_expire = max_reg_expire;
12656    }
12657    iax2_capability = capability;
12658    
12659    if (ucfg) {
12660       struct ast_variable *gen;
12661       int genhasiax;
12662       int genregisteriax;
12663       const char *hasiax, *registeriax;
12664       
12665       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
12666       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
12667       gen = ast_variable_browse(ucfg, "general");
12668       cat = ast_category_browse(ucfg, NULL);
12669       while (cat) {
12670          if (strcasecmp(cat, "general")) {
12671             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
12672             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
12673             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
12674                /* Start with general parameters, then specific parameters, user and peer */
12675                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
12676                if (user) {
12677                   ao2_link(users, user);
12678                   user = user_unref(user);
12679                }
12680                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
12681                if (peer) {
12682                   if (ast_test_flag(peer, IAX_DYNAMIC))
12683                      reg_source_db(peer);
12684                   ao2_link(peers, peer);
12685                   peer = peer_unref(peer);
12686                }
12687             }
12688             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
12689                char tmp[256];
12690                const char *host = ast_variable_retrieve(ucfg, cat, "host");
12691                const char *username = ast_variable_retrieve(ucfg, cat, "username");
12692                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
12693                if (!host)
12694                   host = ast_variable_retrieve(ucfg, "general", "host");
12695                if (!username)
12696                   username = ast_variable_retrieve(ucfg, "general", "username");
12697                if (!secret)
12698                   secret = ast_variable_retrieve(ucfg, "general", "secret");
12699                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
12700                   if (!ast_strlen_zero(secret))
12701                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
12702                   else
12703                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
12704                   iax2_register(tmp, 0);
12705                }
12706             }
12707          }
12708          cat = ast_category_browse(ucfg, cat);
12709       }
12710       ast_config_destroy(ucfg);
12711    }
12712    
12713    cat = ast_category_browse(cfg, NULL);
12714    while(cat) {
12715       if (strcasecmp(cat, "general")) {
12716          utype = ast_variable_retrieve(cfg, cat, "type");
12717          if (!strcasecmp(cat, "callnumberlimits")) {
12718             build_callno_limits(ast_variable_browse(cfg, cat));
12719          } else if (utype) {
12720             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
12721                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
12722                if (user) {
12723                   ao2_link(users, user);
12724                   user = user_unref(user);
12725                }
12726             }
12727             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
12728                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
12729                if (peer) {
12730                   if (ast_test_flag(peer, IAX_DYNAMIC))
12731                      reg_source_db(peer);
12732                   ao2_link(peers, peer);
12733                   peer = peer_unref(peer);
12734                }
12735             } else if (strcasecmp(utype, "user")) {
12736                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
12737             }
12738          } else
12739             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
12740       }
12741       cat = ast_category_browse(cfg, cat);
12742    }
12743    ast_config_destroy(cfg);
12744    return 1;
12745 }

static void set_config_destroy ( void   )  [static]

Definition at line 12307 of file chan_iax2.c.

References addr_range_delme_cb(), ao2_callback, ast_clear_flag, callno_limits, calltoken_ignores, delete_users(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, MAX_TRUNKDATA, and OBJ_NODATA.

Referenced by set_config().

static void set_peercnt_limit ( struct peercnt peercnt  )  [static]

Definition at line 1995 of file chan_iax2.c.

References peercnt::addr, addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), callno_limits, addr_range::limit, peercnt::limit, and peercnt::reg.

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

01996 {
01997    uint16_t limit = global_maxcallno;
01998    struct addr_range *addr_range;
01999    struct sockaddr_in sin = {
02000       .sin_addr.s_addr = peercnt->addr,
02001    };
02002 
02003 
02004    if (peercnt->reg && peercnt->limit) {
02005       return; /* this peercnt has a custom limit set by a registration */
02006    }
02007 
02008    if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02009       limit = addr_range->limit;
02010       ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02011       ao2_ref(addr_range, -1);
02012    }
02013 
02014    peercnt->limit = limit;
02015 }

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

Definition at line 2021 of file chan_iax2.c.

References ast_debug, and set_peercnt_limit().

Referenced by reload_config().

02022 {
02023    struct peercnt *peercnt = obj;
02024 
02025    set_peercnt_limit(peercnt);
02026    ast_debug(1, "Reset limits for peercnts table\n");
02027 
02028    return 0;
02029 }

static void signal_condition ( ast_mutex_t lock,
ast_cond_t cond 
) [static]

Definition at line 911 of file chan_iax2.c.

References ast_cond_signal(), ast_mutex_lock(), and ast_mutex_unlock().

Referenced by __schedule_action(), iax2_process_thread(), iax2_sched_add(), iax2_sched_replace(), iax2_transmit(), and socket_read().

00912 {
00913    ast_mutex_lock(lock);
00914    ast_cond_signal(cond);
00915    ast_mutex_unlock(lock);
00916 }

static int socket_process ( struct iax2_thread thread  )  [static]

Definition at line 9294 of file chan_iax2.c.

References ast_aes_decrypt_key, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_channel_datastore_add(), ast_channel_trylock, ast_channel_unlock, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_free, ast_getformatname(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_del(), AST_SCHED_DEL, ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_var_assign(), ast_variables_destroy(), ast_verb, auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax_ies::called_number, iax_ies::callno, iax2_peer::callno, iax2_dpcache::callno, iax_frame::callno, chan_iax2_pvt::callno, iax_ies::calltoken, iax_ies::calltokendata, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, check_access(), check_provisioning(), cid_num, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), ast_channel::context, context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, DEADLOCK_AVOIDANCE, decrypt_frame(), iax_ies::devicetype, dp_lookup(), iax_ies::encmethods, ast_var_t::entries, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, format, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, globalflags, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_allow_new(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_variable_datastore_info, iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CALLENCRYPTED, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_RTKEY, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DEBUGDIGEST, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_IAX_UNKNOWN, iax_outputframe(), iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), iaxs, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, iax_frame::list, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event, iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, iax_ies::musiconhold, iax2_peer::name, ast_channel::name, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, iax_frame::oseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, iax_ies::provver, iax_ies::provverpres, raw_hangup(), iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rseqno, S_OR, save_osptoken(), save_rr(), sched, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), send_signaling(), iax_ies::serviceident, iax2_peer::smoothing, socket_process_meta(), spawn_dp_lookup(), stop_stuff(), store_by_peercallno(), thread, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), iax_frame::ts, uncompress_subclass(), update_registry(), iax_ies::username, var, iax_ies::vars, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.

Referenced by handle_deferred_full_frames().

09295 {
09296    struct sockaddr_in sin;
09297    int res;
09298    int updatehistory=1;
09299    int new = NEW_PREVENT;
09300    int dcallno = 0;
09301    char decrypted = 0;
09302    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09303    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09304    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09305    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09306    struct iax_frame *fr;
09307    struct iax_frame *cur;
09308    struct ast_frame f = { 0, };
09309    struct ast_channel *c = NULL;
09310    struct iax2_dpcache *dp;
09311    struct iax2_peer *peer;
09312    struct iax_ies ies;
09313    struct iax_ie_data ied0, ied1;
09314    int format;
09315    int fd;
09316    int exists;
09317    int minivid = 0;
09318    char empty[32]="";      /* Safety measure */
09319    struct iax_frame *duped_fr;
09320    char host_pref_buf[128];
09321    char caller_pref_buf[128];
09322    struct ast_codec_pref pref;
09323    char *using_prefs = "mine";
09324 
09325    /* allocate an iax_frame with 4096 bytes of data buffer */
09326    fr = alloca(sizeof(*fr) + 4096);
09327    memset(fr, 0, sizeof(*fr));
09328    fr->afdatalen = 4096; /* From alloca() above */
09329 
09330    /* Copy frequently used parameters to the stack */
09331    res = thread->buf_len;
09332    fd = thread->iofd;
09333    memcpy(&sin, &thread->iosin, sizeof(sin));
09334 
09335    if (res < sizeof(*mh)) {
09336       ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09337       return 1;
09338    }
09339    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09340       if (res < sizeof(*vh)) {
09341          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));
09342          return 1;
09343       }
09344 
09345       /* This is a video frame, get call number */
09346       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09347       minivid = 1;
09348    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09349       return socket_process_meta(res, meta, &sin, fd, fr);
09350 
09351 #ifdef DEBUG_SUPPORT
09352    if (res >= sizeof(*fh))
09353       iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09354 #endif
09355    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09356       if (res < sizeof(*fh)) {
09357          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));
09358          return 1;
09359       }
09360 
09361       /* Get the destination call number */
09362       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09363 
09364 
09365       /* check to make sure this full frame isn't encrypted before we attempt
09366        * to look inside of it. If it is encrypted, decrypt it first. Its ok if the
09367        * callno is not found here, that just means one hasn't been allocated for
09368        * this connection yet. */
09369       if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09370          ast_mutex_lock(&iaxsl[fr->callno]);
09371          if (iaxs[fr->callno] && ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
09372             if (decrypt_frame(fr->callno, fh, &f, &res)) {
09373                ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09374                ast_mutex_unlock(&iaxsl[fr->callno]);
09375                return 1;
09376             }
09377             decrypted = 1;
09378          }
09379          ast_mutex_unlock(&iaxsl[fr->callno]);
09380       }
09381 
09382       /* Retrieve the type and subclass */
09383       f.frametype = fh->type;
09384       if (f.frametype == AST_FRAME_VIDEO) {
09385          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09386       } else {
09387          f.subclass = uncompress_subclass(fh->csub);
09388       }
09389 
09390       /* Deal with POKE/PONG without allocating a callno */
09391       if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
09392          /* Reply back with a PONG, but don't care about the result. */
09393          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09394          return 1;
09395       } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
09396          /* Ignore */
09397          return 1;
09398       }
09399 
09400       f.datalen = res - sizeof(*fh);
09401       if (f.datalen) {
09402          if (f.frametype == AST_FRAME_IAX) {
09403             if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09404                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09405                return 1;
09406             }
09407             f.data.ptr = NULL;
09408             f.datalen = 0;
09409          } else {
09410             f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09411             memset(&ies, 0, sizeof(ies));
09412          }
09413       } else {
09414          if (f.frametype == AST_FRAME_IAX)
09415             f.data.ptr = NULL;
09416          else
09417             f.data.ptr = empty;
09418          memset(&ies, 0, sizeof(ies));
09419       }
09420 
09421       if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) {
09422          /* only set NEW_ALLOW if calltoken checks out */
09423          if (handle_call_token(fh, &ies, &sin, fd)) {
09424             return 1;
09425          }
09426 
09427          if (ies.calltoken && ies.calltokendata) {
09428             /* if we've gotten this far, and the calltoken ie data exists,
09429              * then calltoken validation _MUST_ have taken place.  If calltoken
09430              * data is provided, it is always validated reguardless of any
09431              * calltokenoptional or requirecalltoken options */
09432             new = NEW_ALLOW_CALLTOKEN_VALIDATED;
09433          } else {
09434             new = NEW_ALLOW;
09435          }
09436       }
09437    } else {
09438       /* Don't know anything about it yet */
09439       f.frametype = AST_FRAME_NULL;
09440       f.subclass = 0;
09441    }
09442 
09443    if (!fr->callno) {
09444       int check_dcallno = 0;
09445 
09446       /*
09447        * We enforce accurate destination call numbers for ACKs.  This forces the other
09448        * end to know the destination call number before call setup can complete.
09449        *
09450        * Discussed in the following thread:
09451        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
09452        */
09453 
09454       if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass == IAX_COMMAND_ACK))) {
09455          check_dcallno = 1;
09456       }
09457 
09458       if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
09459          if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) {
09460             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09461          } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) {
09462             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09463          }
09464          return 1;
09465       }
09466    }
09467 
09468    if (fr->callno > 0)
09469       ast_mutex_lock(&iaxsl[fr->callno]);
09470 
09471    if (!fr->callno || !iaxs[fr->callno]) {
09472       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
09473          frame, reply with an inval */
09474       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09475          /* We can only raw hangup control frames */
09476          if (((f.subclass != IAX_COMMAND_INVAL) &&
09477              (f.subclass != IAX_COMMAND_TXCNT) &&
09478              (f.subclass != IAX_COMMAND_TXACC) &&
09479              (f.subclass != IAX_COMMAND_FWDOWNL))||
09480              (f.frametype != AST_FRAME_IAX))
09481             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
09482             fd);
09483       }
09484       if (fr->callno > 0) 
09485          ast_mutex_unlock(&iaxsl[fr->callno]);
09486       return 1;
09487    }
09488    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
09489       if (decrypt_frame(fr->callno, fh, &f, &res)) {
09490          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09491          ast_mutex_unlock(&iaxsl[fr->callno]);
09492          return 1;
09493       }
09494       decrypted = 1;
09495    }
09496 #ifdef DEBUG_SUPPORT
09497    if (decrypted) {
09498       iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
09499    }
09500 #endif
09501 
09502    /* count this frame */
09503    iaxs[fr->callno]->frames_received++;
09504 
09505    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
09506       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
09507       f.subclass != IAX_COMMAND_TXACC) {     /* for attended transfer */
09508       unsigned short new_peercallno;
09509       
09510       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
09511       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
09512          if (iaxs[fr->callno]->peercallno) {
09513             remove_by_peercallno(iaxs[fr->callno]);
09514          }
09515          iaxs[fr->callno]->peercallno = new_peercallno;
09516          store_by_peercallno(iaxs[fr->callno]);
09517       }
09518    }
09519    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09520       if (iaxdebug)
09521          ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
09522       /* Check if it's out of order (and not an ACK or INVAL) */
09523       fr->oseqno = fh->oseqno;
09524       fr->iseqno = fh->iseqno;
09525       fr->ts = ntohl(fh->ts);
09526 #ifdef IAXTESTS
09527       if (test_resync) {
09528          ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
09529          fr->ts += test_resync;
09530       }
09531 #endif /* IAXTESTS */
09532 #if 0
09533       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
09534            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
09535                         (f.subclass == IAX_COMMAND_NEW ||
09536                          f.subclass == IAX_COMMAND_AUTHREQ ||
09537                          f.subclass == IAX_COMMAND_ACCEPT ||
09538                          f.subclass == IAX_COMMAND_REJECT))      ) )
09539 #endif
09540       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
09541          updatehistory = 0;
09542       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
09543          (iaxs[fr->callno]->iseqno ||
09544             ((f.subclass != IAX_COMMAND_TXCNT) &&
09545             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
09546             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
09547             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
09548             (f.subclass != IAX_COMMAND_TXACC)) ||
09549             (f.frametype != AST_FRAME_IAX))) {
09550          if (
09551           ((f.subclass != IAX_COMMAND_ACK) &&
09552            (f.subclass != IAX_COMMAND_INVAL) &&
09553            (f.subclass != IAX_COMMAND_TXCNT) &&
09554            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
09555            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
09556            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
09557            (f.subclass != IAX_COMMAND_TXACC) &&
09558            (f.subclass != IAX_COMMAND_VNAK)) ||
09559            (f.frametype != AST_FRAME_IAX)) {
09560             /* If it's not an ACK packet, it's out of order. */
09561             ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
09562                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
09563             /* Check to see if we need to request retransmission,
09564              * and take sequence number wraparound into account */
09565             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
09566                /* If we've already seen it, ack it XXX There's a border condition here XXX */
09567                if ((f.frametype != AST_FRAME_IAX) || 
09568                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
09569                   ast_debug(1, "Acking anyway\n");
09570                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
09571                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
09572                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09573                }
09574             } else {
09575                /* Send a VNAK requesting retransmission */
09576                iax2_vnak(fr->callno);
09577             }
09578             ast_mutex_unlock(&iaxsl[fr->callno]);
09579             return 1;
09580          }
09581       } else {
09582          /* Increment unless it's an ACK or VNAK */
09583          if (((f.subclass != IAX_COMMAND_ACK) &&
09584              (f.subclass != IAX_COMMAND_INVAL) &&
09585              (f.subclass != IAX_COMMAND_TXCNT) &&
09586              (f.subclass != IAX_COMMAND_TXACC) &&
09587             (f.subclass != IAX_COMMAND_VNAK)) ||
09588              (f.frametype != AST_FRAME_IAX))
09589             iaxs[fr->callno]->iseqno++;
09590       }
09591       /* Ensure text frames are NULL-terminated */
09592       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
09593          if (res < thread->buf_size)
09594             thread->buf[res++] = '\0';
09595          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
09596             thread->buf[res - 1] = '\0';
09597       }
09598 
09599       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
09600          from the real peer, not the transfer peer */
09601       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
09602           ((f.subclass != IAX_COMMAND_INVAL) ||
09603            (f.frametype != AST_FRAME_IAX))) {
09604          unsigned char x;
09605          int call_to_destroy;
09606          /* First we have to qualify that the ACKed value is within our window */
09607          if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
09608             x = fr->iseqno;
09609          else 
09610             x = iaxs[fr->callno]->oseqno;
09611          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
09612             /* The acknowledgement is within our window.  Time to acknowledge everything
09613                that it says to */
09614             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
09615                /* Ack the packet with the given timestamp */
09616                if (iaxdebug)
09617                   ast_debug(1, "Cancelling transmission of packet %d\n", x);
09618                call_to_destroy = 0;
09619                AST_LIST_LOCK(&frame_queue);
09620                AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09621                   /* If it's our call, and our timestamp, mark -1 retries */
09622                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
09623                      cur->retries = -1;
09624                      /* Destroy call if this is the end */
09625                      if (cur->final)
09626                         call_to_destroy = fr->callno;
09627                   }
09628                }
09629                AST_LIST_UNLOCK(&frame_queue);
09630                if (call_to_destroy) {
09631                   if (iaxdebug)
09632                      ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
09633                   ast_mutex_lock(&iaxsl[call_to_destroy]);
09634                   iax2_destroy(call_to_destroy);
09635                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
09636                }
09637             }
09638             /* Note how much we've received acknowledgement for */
09639             if (iaxs[fr->callno])
09640                iaxs[fr->callno]->rseqno = fr->iseqno;
09641             else {
09642                /* Stop processing now */
09643                ast_mutex_unlock(&iaxsl[fr->callno]);
09644                return 1;
09645             }
09646          } else {
09647             ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
09648          }
09649       }
09650       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
09651          ((f.frametype != AST_FRAME_IAX) || 
09652           ((f.subclass != IAX_COMMAND_TXACC) &&
09653            (f.subclass != IAX_COMMAND_TXCNT)))) {
09654          /* Only messages we accept from a transfer host are TXACC and TXCNT */
09655          ast_mutex_unlock(&iaxsl[fr->callno]);
09656          return 1;
09657       }
09658 
09659       /* when we receive the first full frame for a new incoming channel,
09660          it is safe to start the PBX on the channel because we have now
09661          completed a 3-way handshake with the peer */
09662       if ((f.frametype == AST_FRAME_VOICE) ||
09663           (f.frametype == AST_FRAME_VIDEO) ||
09664           (f.frametype == AST_FRAME_IAX)) {
09665          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
09666             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
09667             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
09668                ast_mutex_unlock(&iaxsl[fr->callno]);
09669                return 1;
09670             }
09671          }
09672 
09673          if (ies.vars) {
09674             struct ast_datastore *variablestore = NULL;
09675             struct ast_variable *var, *prev = NULL;
09676             AST_LIST_HEAD(, ast_var_t) *varlist;
09677             if ((c = iaxs[fr->callno]->owner)) {
09678                varlist = ast_calloc(1, sizeof(*varlist));
09679                variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09680 
09681                if (variablestore && varlist) {
09682                   variablestore->data = varlist;
09683                   variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09684                   AST_LIST_HEAD_INIT(varlist);
09685                   ast_debug(1, "I can haz IAX vars?\n");
09686                   for (var = ies.vars; var; var = var->next) {
09687                      struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09688                      if (prev) {
09689                         ast_free(prev);
09690                      }
09691                      prev = var;
09692                      if (!newvar) {
09693                         /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
09694                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09695                      } else {
09696                         AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09697                      }
09698                   }
09699                   if (prev) {
09700                      ast_free(prev);
09701                   }
09702                   ies.vars = NULL;
09703                   ast_channel_datastore_add(c, variablestore);
09704                } else {
09705                   ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09706                   if (variablestore) {
09707                      ast_datastore_free(variablestore);
09708                   }
09709                   if (varlist) {
09710                      ast_free(varlist);
09711                   }
09712                }
09713             } else {
09714                /* No channel yet, so transfer the variables directly over to the pvt,
09715                 * for later inheritance. */
09716                ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
09717                for (var = ies.vars; var && var->next; var = var->next);
09718                if (var) {
09719                   var->next = iaxs[fr->callno]->iaxvars;
09720                   iaxs[fr->callno]->iaxvars = ies.vars;
09721                   ies.vars = NULL;
09722                }
09723             }
09724          }
09725 
09726          if (ies.vars) {
09727             ast_debug(1, "I have IAX variables, but they were not processed\n");
09728          }
09729       }
09730 
09731       /* once we receive our first IAX Full Frame that is not CallToken related, send all
09732        * queued signaling frames that were being held. */
09733       if ((f.frametype == AST_FRAME_IAX) && (f.subclass != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
09734          send_signaling(iaxs[fr->callno]);
09735       }
09736 
09737       if (f.frametype == AST_FRAME_VOICE) {
09738          if (f.subclass != iaxs[fr->callno]->voiceformat) {
09739                iaxs[fr->callno]->voiceformat = f.subclass;
09740                ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass);
09741                if (iaxs[fr->callno]->owner) {
09742                   int orignative;
09743 retryowner:
09744                   if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
09745                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
09746                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
09747                   }
09748                   if (iaxs[fr->callno]) {
09749                      if (iaxs[fr->callno]->owner) {
09750                         orignative = iaxs[fr->callno]->owner->nativeformats;
09751                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
09752                         if (iaxs[fr->callno]->owner->readformat)
09753                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
09754                         iaxs[fr->callno]->owner->nativeformats = orignative;
09755                         ast_channel_unlock(iaxs[fr->callno]->owner);
09756                      }
09757                   } else {
09758                      ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
09759                      /* Free remote variables (if any) */
09760                      if (ies.vars) {
09761                         ast_variables_destroy(ies.vars);
09762                         ast_debug(1, "I can haz iaxvars, but they is no good.  :-(\n");
09763                         ies.vars = NULL;
09764                      }
09765                      ast_mutex_unlock(&iaxsl[fr->callno]);
09766                      return 1;
09767                   }
09768                }
09769          }
09770       }
09771       if (f.frametype == AST_FRAME_VIDEO) {
09772          if (f.subclass != iaxs[fr->callno]->videoformat) {
09773             ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
09774             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
09775          }
09776       }
09777       if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
09778          if (f.subclass == AST_CONTROL_BUSY) {
09779             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
09780          } else if (f.subclass == AST_CONTROL_CONGESTION) {
09781             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
09782          }
09783       }
09784       if (f.frametype == AST_FRAME_IAX) {
09785          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
09786          /* Handle the IAX pseudo frame itself */
09787          if (iaxdebug)
09788             ast_debug(1, "IAX subclass %d received\n", f.subclass);
09789 
09790                         /* Update last ts unless the frame's timestamp originated with us. */
09791          if (iaxs[fr->callno]->last < fr->ts &&
09792                             f.subclass != IAX_COMMAND_ACK &&
09793                             f.subclass != IAX_COMMAND_PONG &&
09794                             f.subclass != IAX_COMMAND_LAGRP) {
09795             iaxs[fr->callno]->last = fr->ts;
09796             if (iaxdebug)
09797                ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
09798          }
09799          iaxs[fr->callno]->last_iax_message = f.subclass;
09800          if (!iaxs[fr->callno]->first_iax_message) {
09801             iaxs[fr->callno]->first_iax_message = f.subclass;
09802          }
09803          switch(f.subclass) {
09804          case IAX_COMMAND_ACK:
09805             /* Do nothing */
09806             break;
09807          case IAX_COMMAND_QUELCH:
09808             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09809                     /* Generate Manager Hold event, if necessary*/
09810                if (iaxs[fr->callno]->owner) {
09811                   manager_event(EVENT_FLAG_CALL, "Hold",
09812                      "Status: On\r\n"
09813                      "Channel: %s\r\n"
09814                      "Uniqueid: %s\r\n",
09815                      iaxs[fr->callno]->owner->name, 
09816                      iaxs[fr->callno]->owner->uniqueid);
09817                }
09818 
09819                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
09820                if (ies.musiconhold) {
09821                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
09822                      const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
09823                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
09824                         S_OR(moh_suggest, NULL),
09825                         !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
09826                      if (!iaxs[fr->callno]) {
09827                         ast_mutex_unlock(&iaxsl[fr->callno]);
09828                         return 1;
09829                      }
09830                   }
09831                }
09832             }
09833             break;
09834          case IAX_COMMAND_UNQUELCH:
09835             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09836                     /* Generate Manager Unhold event, if necessary*/
09837                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
09838                   manager_event(EVENT_FLAG_CALL, "Hold",
09839                      "Status: Off\r\n"
09840                      "Channel: %s\r\n"
09841                      "Uniqueid: %s\r\n",
09842                      iaxs[fr->callno]->owner->name, 
09843                      iaxs[fr->callno]->owner->uniqueid);
09844                }
09845 
09846                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
09847                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
09848                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
09849                   if (!iaxs[fr->callno]) {
09850                      ast_mutex_unlock(&iaxsl[fr->callno]);
09851                      return 1;
09852                   }
09853                }
09854             }
09855             break;
09856          case IAX_COMMAND_TXACC:
09857             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
09858                /* Ack the packet with the given timestamp */
09859                AST_LIST_LOCK(&frame_queue);
09860                AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09861                   /* Cancel any outstanding txcnt's */
09862                   if ((fr->callno == cur->callno) && (cur->transfer))
09863                      cur->retries = -1;
09864                }
09865                AST_LIST_UNLOCK(&frame_queue);
09866                memset(&ied1, 0, sizeof(ied1));
09867                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
09868                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
09869                iaxs[fr->callno]->transferring = TRANSFER_READY;
09870             }
09871             break;
09872          case IAX_COMMAND_NEW:
09873             /* Ignore if it's already up */
09874             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
09875                break;
09876             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
09877                ast_mutex_unlock(&iaxsl[fr->callno]);
09878                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
09879                ast_mutex_lock(&iaxsl[fr->callno]);
09880                if (!iaxs[fr->callno]) {
09881                   ast_mutex_unlock(&iaxsl[fr->callno]);
09882                   return 1;
09883                }
09884             }
09885             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
09886             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
09887                int new_callno;
09888                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
09889                   fr->callno = new_callno;
09890             }
09891             /* For security, always ack immediately */
09892             if (delayreject)
09893                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09894             if (check_access(fr->callno, &sin, &ies)) {
09895                /* They're not allowed on */
09896                auth_fail(fr->callno, IAX_COMMAND_REJECT);
09897                if (authdebug)
09898                   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);
09899                break;
09900             }
09901             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
09902                const char *context, *exten, *cid_num;
09903 
09904                context = ast_strdupa(iaxs[fr->callno]->context);
09905                exten = ast_strdupa(iaxs[fr->callno]->exten);
09906                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
09907 
09908                /* This might re-enter the IAX code and need the lock */
09909                ast_mutex_unlock(&iaxsl[fr->callno]);
09910                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
09911                ast_mutex_lock(&iaxsl[fr->callno]);
09912 
09913                if (!iaxs[fr->callno]) {
09914                   ast_mutex_unlock(&iaxsl[fr->callno]);
09915                   return 1;
09916                }
09917             } else
09918                exists = 0;
09919             /* Get OSP token if it does exist */
09920             save_osptoken(fr, &ies);
09921             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
09922                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
09923                   memset(&ied0, 0, sizeof(ied0));
09924                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09925                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09926                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09927                   if (!iaxs[fr->callno]) {
09928                      ast_mutex_unlock(&iaxsl[fr->callno]);
09929                      return 1;
09930                   }
09931                   if (authdebug)
09932                      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);
09933                } else {
09934                   /* Select an appropriate format */
09935 
09936                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09937                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09938                         using_prefs = "reqonly";
09939                      } else {
09940                         using_prefs = "disabled";
09941                      }
09942                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
09943                      memset(&pref, 0, sizeof(pref));
09944                      strcpy(caller_pref_buf, "disabled");
09945                      strcpy(host_pref_buf, "disabled");
09946                   } else {
09947                      using_prefs = "mine";
09948                      /* If the information elements are in here... use them */
09949                      if (ies.codec_prefs)
09950                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
09951                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09952                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
09953                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09954                            pref = iaxs[fr->callno]->rprefs;
09955                            using_prefs = "caller";
09956                         } else {
09957                            pref = iaxs[fr->callno]->prefs;
09958                         }
09959                      } else
09960                         pref = iaxs[fr->callno]->prefs;
09961                      
09962                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
09963                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
09964                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
09965                   }
09966                   if (!format) {
09967                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09968                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
09969                      if (!format) {
09970                         memset(&ied0, 0, sizeof(ied0));
09971                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09972                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09973                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09974                         if (!iaxs[fr->callno]) {
09975                            ast_mutex_unlock(&iaxsl[fr->callno]);
09976                            return 1;
09977                         }
09978                         if (authdebug) {
09979                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09980                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
09981                            else 
09982                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
09983                         }
09984                      } else {
09985                         /* Pick one... */
09986                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09987                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
09988                               format = 0;
09989                         } else {
09990                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09991                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
09992                               memset(&pref, 0, sizeof(pref));
09993                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09994                               strcpy(caller_pref_buf,"disabled");
09995                               strcpy(host_pref_buf,"disabled");
09996                            } else {
09997                               using_prefs = "mine";
09998                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09999                                  /* Do the opposite of what we tried above. */
10000                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10001                                     pref = iaxs[fr->callno]->prefs;                       
10002                                  } else {
10003                                     pref = iaxs[fr->callno]->rprefs;
10004                                     using_prefs = "caller";
10005                                  }
10006                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10007                            
10008                               } else /* if no codec_prefs IE do it the old way */
10009                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
10010                            }
10011                         }
10012 
10013                         if (!format) {
10014                            memset(&ied0, 0, sizeof(ied0));
10015                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10016                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10017                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10018                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10019                            if (!iaxs[fr->callno]) {
10020                               ast_mutex_unlock(&iaxsl[fr->callno]);
10021                               return 1;
10022                            }
10023                            if (authdebug)
10024                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
10025                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
10026                            break;
10027                         }
10028                      }
10029                   }
10030                   if (format) {
10031                      /* No authentication required, let them in */
10032                      memset(&ied1, 0, sizeof(ied1));
10033                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10034                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10035                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10036                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10037                         ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10038                                     "%srequested format = %s,\n"
10039                                     "%srequested prefs = %s,\n"
10040                                     "%sactual format = %s,\n"
10041                                     "%shost prefs = %s,\n"
10042                                     "%spriority = %s\n",
10043                                     ast_inet_ntoa(sin.sin_addr), 
10044                                     VERBOSE_PREFIX_4,
10045                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
10046                                     VERBOSE_PREFIX_4,
10047                                     caller_pref_buf,
10048                                     VERBOSE_PREFIX_4,
10049                                     ast_getformatname(format), 
10050                                     VERBOSE_PREFIX_4,
10051                                     host_pref_buf, 
10052                                     VERBOSE_PREFIX_4,
10053                                     using_prefs);
10054                         
10055                         iaxs[fr->callno]->chosenformat = format;
10056                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
10057                      } else {
10058                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10059                         /* If this is a TBD call, we're ready but now what...  */
10060                         ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10061                      }
10062                   }
10063                }
10064                break;
10065             }
10066             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10067                merge_encryption(iaxs[fr->callno],ies.encmethods);
10068             else
10069                iaxs[fr->callno]->encmethods = 0;
10070             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10071                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10072             if (!iaxs[fr->callno]) {
10073                ast_mutex_unlock(&iaxsl[fr->callno]);
10074                return 1;
10075             }
10076             break;
10077          case IAX_COMMAND_DPREQ:
10078             /* Request status in the dialplan */
10079             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10080                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10081                if (iaxcompat) {
10082                   /* Spawn a thread for the lookup */
10083                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10084                } else {
10085                   /* Just look it up */
10086                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10087                }
10088             }
10089             break;
10090          case IAX_COMMAND_HANGUP:
10091             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10092             ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10093             /* Set hangup cause according to remote */
10094             if (ies.causecode && iaxs[fr->callno]->owner)
10095                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
10096             /* Send ack immediately, before we destroy */
10097             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10098             iax2_destroy(fr->callno);
10099             break;
10100          case IAX_COMMAND_REJECT:
10101             /* Set hangup cause according to remote */
10102             if (ies.causecode && iaxs[fr->callno]->owner)
10103                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
10104 
10105             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
10106                if (iaxs[fr->callno]->owner && authdebug)
10107                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10108                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10109                      ies.cause ? ies.cause : "<Unknown>");
10110                ast_debug(1, "Immediately destroying %d, having received reject\n",
10111                   fr->callno);
10112             }
10113             /* Send ack immediately, before we destroy */
10114             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10115                          fr->ts, NULL, 0, fr->iseqno);
10116             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
10117                iaxs[fr->callno]->error = EPERM;
10118             iax2_destroy(fr->callno);
10119             break;
10120          case IAX_COMMAND_TRANSFER:
10121          {
10122             struct ast_channel *bridged_chan;
10123 
10124             if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
10125                /* Set BLINDTRANSFER channel variables */
10126 
10127                ast_mutex_unlock(&iaxsl[fr->callno]);
10128                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
10129                ast_mutex_lock(&iaxsl[fr->callno]);
10130                if (!iaxs[fr->callno]) {
10131                   ast_mutex_unlock(&iaxsl[fr->callno]);
10132                   return 1;
10133                }
10134 
10135                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
10136                if (!strcmp(ies.called_number, ast_parking_ext())) {
10137                   struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
10138                   ast_mutex_unlock(&iaxsl[fr->callno]);
10139                   if (iax_park(bridged_chan, saved_channel)) {
10140                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
10141                   } else {
10142                      ast_debug(1, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
10143                   }
10144                   ast_mutex_lock(&iaxsl[fr->callno]);
10145                } else {
10146                   if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
10147                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 
10148                         ies.called_number, iaxs[fr->callno]->context);
10149                   else {
10150                      ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 
10151                         ies.called_number, iaxs[fr->callno]->context);
10152                   }
10153                }
10154             } else {
10155                ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10156             }
10157 
10158             break;
10159          }
10160          case IAX_COMMAND_ACCEPT:
10161             /* Ignore if call is already up or needs authentication or is a TBD */
10162             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10163                break;
10164             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
10165                /* Send ack immediately, before we destroy */
10166                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10167                iax2_destroy(fr->callno);
10168                break;
10169             }
10170             if (ies.format) {
10171                iaxs[fr->callno]->peerformat = ies.format;
10172             } else {
10173                if (iaxs[fr->callno]->owner)
10174                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10175                else
10176                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10177             }
10178             ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
10179             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10180                memset(&ied0, 0, sizeof(ied0));
10181                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10182                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10183                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10184                if (!iaxs[fr->callno]) {
10185                   ast_mutex_unlock(&iaxsl[fr->callno]);
10186                   return 1;
10187                }
10188                if (authdebug)
10189                   ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
10190             } else {
10191                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10192                if (iaxs[fr->callno]->owner) {
10193                   /* Switch us to use a compatible format */
10194                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10195                   ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10196 retryowner2:
10197                   if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
10198                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
10199                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
10200                   }
10201                   
10202                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10203                      /* Setup read/write formats properly. */
10204                      if (iaxs[fr->callno]->owner->writeformat)
10205                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
10206                      if (iaxs[fr->callno]->owner->readformat)
10207                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
10208                      ast_channel_unlock(iaxs[fr->callno]->owner);
10209                   }
10210                }
10211             }
10212             if (iaxs[fr->callno]) {
10213                AST_LIST_LOCK(&dpcache);
10214                AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10215                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10216                      iax2_dprequest(dp, fr->callno);
10217                AST_LIST_UNLOCK(&dpcache);
10218             }
10219             break;
10220          case IAX_COMMAND_POKE:
10221             /* Send back a pong packet with the original timestamp */
10222             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10223             if (!iaxs[fr->callno]) {
10224                ast_mutex_unlock(&iaxsl[fr->callno]);
10225                return 1;
10226             }
10227             break;
10228          case IAX_COMMAND_PING:
10229          {
10230             struct iax_ie_data pingied;
10231             construct_rr(iaxs[fr->callno], &pingied);
10232             /* Send back a pong packet with the original timestamp */
10233             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10234          }
10235             break;
10236          case IAX_COMMAND_PONG:
10237             /* Calculate ping time */
10238             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10239             /* save RR info */
10240             save_rr(fr, &ies);
10241 
10242             /* Good time to write jb stats for this call */
10243             log_jitterstats(fr->callno);
10244 
10245             if (iaxs[fr->callno]->peerpoke) {
10246                peer = iaxs[fr->callno]->peerpoke;
10247                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
10248                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10249                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10250                      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); 
10251                      ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */
10252                   }
10253                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10254                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
10255                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10256                      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); 
10257                      ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
10258                   }
10259                }
10260                peer->lastms = iaxs[fr->callno]->pingtime;
10261                if (peer->smoothing && (peer->lastms > -1))
10262                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10263                else if (peer->smoothing && peer->lastms < 0)
10264                   peer->historicms = (0 + peer->historicms) / 2;
10265                else              
10266                   peer->historicms = iaxs[fr->callno]->pingtime;
10267 
10268                /* Remove scheduled iax2_poke_noanswer */
10269                if (peer->pokeexpire > -1) {
10270                   if (!ast_sched_del(sched, peer->pokeexpire)) {
10271                      peer_unref(peer);
10272                      peer->pokeexpire = -1;
10273                   }
10274                }
10275                /* Schedule the next cycle */
10276                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
10277                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10278                else
10279                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10280                if (peer->pokeexpire == -1)
10281                   peer_unref(peer);
10282                /* and finally send the ack */
10283                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10284                /* And wrap up the qualify call */
10285                iax2_destroy(fr->callno);
10286                peer->callno = 0;
10287                ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10288             }
10289             break;
10290          case IAX_COMMAND_LAGRQ:
10291          case IAX_COMMAND_LAGRP:
10292             f.src = "LAGRQ";
10293             f.mallocd = 0;
10294             f.offset = 0;
10295             f.samples = 0;
10296             iax_frame_wrap(fr, &f);
10297             if(f.subclass == IAX_COMMAND_LAGRQ) {
10298                /* Received a LAGRQ - echo back a LAGRP */
10299                fr->af.subclass = IAX_COMMAND_LAGRP;
10300                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10301             } else {
10302                /* Received LAGRP in response to our LAGRQ */
10303                unsigned int ts;
10304                /* This is a reply we've been given, actually measure the difference */
10305                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10306                iaxs[fr->callno]->lag = ts - fr->ts;
10307                if (iaxdebug)
10308                   ast_debug(1, "Peer %s lag measured as %dms\n",
10309                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10310             }
10311             break;
10312          case IAX_COMMAND_AUTHREQ:
10313             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10314                ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10315                break;
10316             }
10317             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10318                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10319                         .subclass = AST_CONTROL_HANGUP,
10320                };
10321                ast_log(LOG_WARNING, 
10322                   "I don't know how to authenticate %s to %s\n", 
10323                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10324                iax2_queue_frame(fr->callno, &hangup_fr);
10325             }
10326             if (!iaxs[fr->callno]) {
10327                ast_mutex_unlock(&iaxsl[fr->callno]);
10328                return 1;
10329             }
10330             break;
10331          case IAX_COMMAND_AUTHREP:
10332             /* For security, always ack immediately */
10333             if (delayreject)
10334                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10335             /* Ignore once we've started */
10336             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10337                ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10338                break;
10339             }
10340             if (authenticate_verify(iaxs[fr->callno], &ies)) {
10341                if (authdebug)
10342                   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);
10343                memset(&ied0, 0, sizeof(ied0));
10344                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10345                break;
10346             }
10347             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10348                /* This might re-enter the IAX code and need the lock */
10349                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10350             } else
10351                exists = 0;
10352             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10353                if (authdebug)
10354                   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);
10355                memset(&ied0, 0, sizeof(ied0));
10356                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10357                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10358                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10359                if (!iaxs[fr->callno]) {
10360                   ast_mutex_unlock(&iaxsl[fr->callno]);
10361                   return 1;
10362                }
10363             } else {
10364                /* Select an appropriate format */
10365                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10366                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10367                      using_prefs = "reqonly";
10368                   } else {
10369                      using_prefs = "disabled";
10370                   }
10371                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10372                   memset(&pref, 0, sizeof(pref));
10373                   strcpy(caller_pref_buf, "disabled");
10374                   strcpy(host_pref_buf, "disabled");
10375                } else {
10376                   using_prefs = "mine";
10377                   if (ies.codec_prefs)
10378                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10379                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10380                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10381                         pref = iaxs[fr->callno]->rprefs;
10382                         using_prefs = "caller";
10383                      } else {
10384                         pref = iaxs[fr->callno]->prefs;
10385                      }
10386                   } else /* if no codec_prefs IE do it the old way */
10387                      pref = iaxs[fr->callno]->prefs;
10388                
10389                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10390                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10391                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10392                }
10393                if (!format) {
10394                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10395                      ast_debug(1, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability);
10396                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10397                   }
10398                   if (!format) {
10399                      if (authdebug) {
10400                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
10401                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
10402                         else
10403                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
10404                      }
10405                      memset(&ied0, 0, sizeof(ied0));
10406                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10407                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10408                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10409                      if (!iaxs[fr->callno]) {
10410                         ast_mutex_unlock(&iaxsl[fr->callno]);
10411                         return 1;
10412                      }
10413                   } else {
10414                      /* Pick one... */
10415                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10416                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10417                            format = 0;
10418                      } else {
10419                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10420                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10421                            memset(&pref, 0, sizeof(pref));
10422                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
10423                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10424                            strcpy(caller_pref_buf,"disabled");
10425                            strcpy(host_pref_buf,"disabled");
10426                         } else {
10427                            using_prefs = "mine";
10428                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10429                               /* Do the opposite of what we tried above. */
10430                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10431                                  pref = iaxs[fr->callno]->prefs;                 
10432                               } else {
10433                                  pref = iaxs[fr->callno]->rprefs;
10434                                  using_prefs = "caller";
10435                               }
10436                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10437                            } else /* if no codec_prefs IE do it the old way */
10438                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
10439                         }
10440                      }
10441                      if (!format) {
10442                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10443                         if (authdebug) {
10444                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10445                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
10446                            else
10447                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
10448                         }
10449                         memset(&ied0, 0, sizeof(ied0));
10450                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10451                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10452                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10453                         if (!iaxs[fr->callno]) {
10454                            ast_mutex_unlock(&iaxsl[fr->callno]);
10455                            return 1;
10456                         }
10457                      }
10458                   }
10459                }
10460                if (format) {
10461                   /* Authentication received */
10462                   memset(&ied1, 0, sizeof(ied1));
10463                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10464                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10465                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10466                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10467                      ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
10468                                  "%srequested format = %s,\n"
10469                                  "%srequested prefs = %s,\n"
10470                                  "%sactual format = %s,\n"
10471                                  "%shost prefs = %s,\n"
10472                                  "%spriority = %s\n", 
10473                                  ast_inet_ntoa(sin.sin_addr), 
10474                                  VERBOSE_PREFIX_4,
10475                                  ast_getformatname(iaxs[fr->callno]->peerformat),
10476                                  VERBOSE_PREFIX_4,
10477                                  caller_pref_buf,
10478                                  VERBOSE_PREFIX_4,
10479                                  ast_getformatname(format),
10480                                  VERBOSE_PREFIX_4,
10481                                  host_pref_buf,
10482                                  VERBOSE_PREFIX_4,
10483                                  using_prefs);
10484 
10485                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10486                      if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
10487                         iax2_destroy(fr->callno);
10488                      else if (ies.vars) {
10489                         struct ast_datastore *variablestore;
10490                         struct ast_variable *var, *prev = NULL;
10491                         AST_LIST_HEAD(, ast_var_t) *varlist;
10492                         varlist = ast_calloc(1, sizeof(*varlist));
10493                         variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10494                         if (variablestore && varlist) {
10495                            variablestore->data = varlist;
10496                            variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10497                            AST_LIST_HEAD_INIT(varlist);
10498                            ast_debug(1, "I can haz IAX vars? w00t\n");
10499                            for (var = ies.vars; var; var = var->next) {
10500                               struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10501                               if (prev)
10502                                  ast_free(prev);
10503                               prev = var;
10504                               if (!newvar) {
10505                                  /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
10506                                  ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10507                               } else {
10508                                  AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10509                               }
10510                            }
10511                            if (prev)
10512                               ast_free(prev);
10513                            ies.vars = NULL;
10514                            ast_channel_datastore_add(c, variablestore);
10515                         } else {
10516                            ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10517                            if (variablestore)
10518                               ast_datastore_free(variablestore);
10519                            if (varlist)
10520                               ast_free(varlist);
10521                         }
10522                      }
10523                   } else {
10524                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10525                      /* If this is a TBD call, we're ready but now what...  */
10526                      ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10527                   }
10528                }
10529             }
10530             break;
10531          case IAX_COMMAND_DIAL:
10532             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
10533                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10534                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
10535                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
10536                   if (authdebug)
10537                      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);
10538                   memset(&ied0, 0, sizeof(ied0));
10539                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10540                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10541                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10542                   if (!iaxs[fr->callno]) {
10543                      ast_mutex_unlock(&iaxsl[fr->callno]);
10544                      return 1;
10545                   }
10546                } else {
10547                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10548                   ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
10549                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10550                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
10551                   if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
10552                      iax2_destroy(fr->callno);
10553                   else if (ies.vars) {
10554                      struct ast_datastore *variablestore;
10555                      struct ast_variable *var, *prev = NULL;
10556                      AST_LIST_HEAD(, ast_var_t) *varlist;
10557                      varlist = ast_calloc(1, sizeof(*varlist));
10558                      variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10559                      ast_debug(1, "I can haz IAX vars? w00t\n");
10560                      if (variablestore && varlist) {
10561                         variablestore->data = varlist;
10562                         variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10563                         AST_LIST_HEAD_INIT(varlist);
10564                         for (var = ies.vars; var; var = var->next) {
10565                            struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10566                            if (prev)
10567                               ast_free(prev);
10568                            prev = var;
10569                            if (!newvar) {
10570                               /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
10571                               ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10572                            } else {
10573                               AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10574                            }
10575                         }
10576                         if (prev)
10577                            ast_free(prev);
10578                         ies.vars = NULL;
10579                         ast_channel_datastore_add(c, variablestore);
10580                      } else {
10581                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10582                         if (variablestore)
10583                            ast_datastore_free(variablestore);
10584                         if (varlist)
10585                            ast_free(varlist);
10586                      }
10587                   }
10588                }
10589             }
10590             break;
10591          case IAX_COMMAND_INVAL:
10592             iaxs[fr->callno]->error = ENOTCONN;
10593             ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
10594             iax2_destroy(fr->callno);
10595             ast_debug(1, "Destroying call %d\n", fr->callno);
10596             break;
10597          case IAX_COMMAND_VNAK:
10598             ast_debug(1, "Received VNAK: resending outstanding frames\n");
10599             /* Force retransmission */
10600             vnak_retransmit(fr->callno, fr->iseqno);
10601             break;
10602          case IAX_COMMAND_REGREQ:
10603          case IAX_COMMAND_REGREL:
10604             /* For security, always ack immediately */
10605             if (delayreject)
10606                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10607             if (register_verify(fr->callno, &sin, &ies)) {
10608                if (!iaxs[fr->callno]) {
10609                   ast_mutex_unlock(&iaxsl[fr->callno]);
10610                   return 1;
10611                }
10612                /* Send delayed failure */
10613                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
10614                break;
10615             }
10616             if (!iaxs[fr->callno]) {
10617                ast_mutex_unlock(&iaxsl[fr->callno]);
10618                return 1;
10619             }
10620             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
10621                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
10622 
10623                if (f.subclass == IAX_COMMAND_REGREL)
10624                   memset(&sin, 0, sizeof(sin));
10625                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
10626                   ast_log(LOG_WARNING, "Registry error\n");
10627                if (!iaxs[fr->callno]) {
10628                   ast_mutex_unlock(&iaxsl[fr->callno]);
10629                   return 1;
10630                }
10631                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10632                   ast_mutex_unlock(&iaxsl[fr->callno]);
10633                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10634                   ast_mutex_lock(&iaxsl[fr->callno]);
10635                   if (!iaxs[fr->callno]) {
10636                      ast_mutex_unlock(&iaxsl[fr->callno]);
10637                      return 1;
10638                   }
10639                }
10640                break;
10641             }
10642             registry_authrequest(fr->callno);
10643             if (!iaxs[fr->callno]) {
10644                ast_mutex_unlock(&iaxsl[fr->callno]);
10645                return 1;
10646             }
10647             break;
10648          case IAX_COMMAND_REGACK:
10649             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
10650                ast_log(LOG_WARNING, "Registration failure\n");
10651             /* Send ack immediately, before we destroy */
10652             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10653             iax2_destroy(fr->callno);
10654             break;
10655          case IAX_COMMAND_REGREJ:
10656             if (iaxs[fr->callno]->reg) {
10657                if (authdebug) {
10658                   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));
10659                   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>");
10660                }
10661                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
10662             }
10663             /* Send ack immediately, before we destroy */
10664             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10665             iax2_destroy(fr->callno);
10666             break;
10667          case IAX_COMMAND_REGAUTH:
10668             /* Authentication request */
10669             if (registry_rerequest(&ies, fr->callno, &sin)) {
10670                memset(&ied0, 0, sizeof(ied0));
10671                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
10672                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
10673                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10674                if (!iaxs[fr->callno]) {
10675                   ast_mutex_unlock(&iaxsl[fr->callno]);
10676                   return 1;
10677                }
10678             }
10679             break;
10680          case IAX_COMMAND_TXREJ:
10681             iaxs[fr->callno]->transferring = 0;
10682             ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10683             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
10684             if (iaxs[fr->callno]->bridgecallno) {
10685                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
10686                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
10687                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
10688                }
10689             }
10690             break;
10691          case IAX_COMMAND_TXREADY:
10692             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
10693                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
10694                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
10695                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
10696                else
10697                   iaxs[fr->callno]->transferring = TRANSFER_READY;
10698                ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10699                if (iaxs[fr->callno]->bridgecallno) {
10700                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
10701                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
10702                      /* They're both ready, now release them. */
10703                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
10704                         ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10705                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10706 
10707                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
10708                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
10709 
10710                         memset(&ied0, 0, sizeof(ied0));
10711                         memset(&ied1, 0, sizeof(ied1));
10712                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10713                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10714                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
10715                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
10716                      } else {
10717                         ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10718                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10719 
10720                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
10721                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
10722                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
10723                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10724 
10725                         /* Stop doing lag & ping requests */
10726                         stop_stuff(fr->callno);
10727                         stop_stuff(iaxs[fr->callno]->bridgecallno);
10728 
10729                         memset(&ied0, 0, sizeof(ied0));
10730                         memset(&ied1, 0, sizeof(ied1));
10731                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10732                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10733                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
10734                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
10735                      }
10736 
10737                   }
10738                }
10739             }
10740             break;
10741          case IAX_COMMAND_TXREQ:
10742             try_transfer(iaxs[fr->callno], &ies);
10743             break;
10744          case IAX_COMMAND_TXCNT:
10745             if (iaxs[fr->callno]->transferring)
10746                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
10747             break;
10748          case IAX_COMMAND_TXREL:
10749             /* Send ack immediately, rather than waiting until we've changed addresses */
10750             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10751             complete_transfer(fr->callno, &ies);
10752             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
10753             break;   
10754          case IAX_COMMAND_TXMEDIA:
10755             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
10756                AST_LIST_LOCK(&frame_queue);
10757                AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10758                   /* Cancel any outstanding frames and start anew */
10759                   if ((fr->callno == cur->callno) && (cur->transfer))
10760                      cur->retries = -1;
10761                }
10762                AST_LIST_UNLOCK(&frame_queue);
10763                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
10764                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
10765             }
10766             break;
10767          case IAX_COMMAND_RTKEY:
10768             if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
10769                ast_log(LOG_WARNING, 
10770                   "we've been told to rotate our encryption key, "
10771                   "but this isn't an encrypted call. bad things will happen.\n"
10772                );
10773                break;
10774             }
10775 
10776             IAX_DEBUGDIGEST("Receiving", ies.challenge);
10777 
10778             ast_aes_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
10779             break;
10780          case IAX_COMMAND_DPREP:
10781             complete_dpreply(iaxs[fr->callno], &ies);
10782             break;
10783          case IAX_COMMAND_UNSUPPORT:
10784             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
10785             break;
10786          case IAX_COMMAND_FWDOWNL:
10787             /* Firmware download */
10788             if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
10789                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
10790                break;
10791             }
10792             memset(&ied0, 0, sizeof(ied0));
10793             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
10794             if (res < 0)
10795                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10796             else if (res > 0)
10797                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
10798             else
10799                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
10800             if (!iaxs[fr->callno]) {
10801                ast_mutex_unlock(&iaxsl[fr->callno]);
10802                return 1;
10803             }
10804             break;
10805          case IAX_COMMAND_CALLTOKEN:
10806          {
10807             struct iax_frame *cur;
10808             int found = 0;
10809             AST_LIST_LOCK(&frame_queue);
10810             AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10811                /* find the last sent frame in our frame queue for this callno.
10812                 * There are many things to take into account before resending this frame.
10813                 * All of these are taken care of in resend_with_token() */
10814                if (cur->callno == fr->callno) {
10815                   found = 1;
10816                   break;
10817                }
10818             }
10819             AST_LIST_UNLOCK(&frame_queue);
10820 
10821             /* find last sent frame */
10822             if (cur && found && ies.calltoken && ies.calltokendata) {
10823                resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
10824             }
10825             break;
10826          }
10827          default:
10828             ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
10829             memset(&ied0, 0, sizeof(ied0));
10830             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
10831             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
10832          }
10833          /* Free remote variables (if any) */
10834          if (ies.vars) {
10835             ast_variables_destroy(ies.vars);
10836             ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
10837             ies.vars = NULL;
10838          }
10839 
10840          /* Don't actually pass these frames along */
10841          if ((f.subclass != IAX_COMMAND_ACK) && 
10842            (f.subclass != IAX_COMMAND_TXCNT) && 
10843            (f.subclass != IAX_COMMAND_TXACC) && 
10844            (f.subclass != IAX_COMMAND_INVAL) &&
10845            (f.subclass != IAX_COMMAND_VNAK)) { 
10846             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
10847                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10848          }
10849          ast_mutex_unlock(&iaxsl[fr->callno]);
10850          return 1;
10851       }
10852       /* Unless this is an ACK or INVAL frame, ack it */
10853       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
10854          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10855    } else if (minivid) {
10856       f.frametype = AST_FRAME_VIDEO;
10857       if (iaxs[fr->callno]->videoformat > 0) 
10858          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
10859       else {
10860          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
10861          iax2_vnak(fr->callno);
10862          ast_mutex_unlock(&iaxsl[fr->callno]);
10863          return 1;
10864       }
10865       f.datalen = res - sizeof(*vh);
10866       if (f.datalen)
10867          f.data.ptr = thread->buf + sizeof(*vh);
10868       else
10869          f.data.ptr = NULL;
10870 #ifdef IAXTESTS
10871       if (test_resync) {
10872          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
10873       } else
10874 #endif /* IAXTESTS */
10875          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
10876    } else {
10877       /* A mini frame */
10878       f.frametype = AST_FRAME_VOICE;
10879       if (iaxs[fr->callno]->voiceformat > 0)
10880          f.subclass = iaxs[fr->callno]->voiceformat;
10881       else {
10882          ast_debug(1, "Received mini frame before first full voice frame\n");
10883          iax2_vnak(fr->callno);
10884          ast_mutex_unlock(&iaxsl[fr->callno]);
10885          return 1;
10886       }
10887       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
10888       if (f.datalen < 0) {
10889          ast_log(LOG_WARNING, "Datalen < 0?\n");
10890          ast_mutex_unlock(&iaxsl[fr->callno]);
10891          return 1;
10892       }
10893       if (f.datalen)
10894          f.data.ptr = thread->buf + sizeof(*mh);
10895       else
10896          f.data.ptr = NULL;
10897 #ifdef IAXTESTS
10898       if (test_resync) {
10899          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
10900       } else
10901 #endif /* IAXTESTS */
10902       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
10903       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
10904    }
10905    /* Don't pass any packets until we're started */
10906    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10907       ast_mutex_unlock(&iaxsl[fr->callno]);
10908       return 1;
10909    }
10910    /* Common things */
10911    f.src = "IAX2";
10912    f.mallocd = 0;
10913    f.offset = 0;
10914    f.len = 0;
10915    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
10916       f.samples = ast_codec_get_samples(&f);
10917       /* We need to byteswap incoming slinear samples from network byte order */
10918       if (f.subclass == AST_FORMAT_SLINEAR)
10919          ast_frame_byteswap_be(&f);
10920    } else
10921       f.samples = 0;
10922    iax_frame_wrap(fr, &f);
10923 
10924    /* If this is our most recent packet, use it as our basis for timestamping */
10925    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
10926       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
10927       fr->outoforder = 0;
10928    } else {
10929       if (iaxdebug && iaxs[fr->callno])
10930          ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last);
10931       fr->outoforder = -1;
10932    }
10933    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
10934    duped_fr = iaxfrdup2(fr);
10935    if (duped_fr) {
10936       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
10937    }
10938    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
10939       iaxs[fr->callno]->last = fr->ts;
10940 #if 1
10941       if (iaxdebug)
10942          ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10943 #endif
10944    }
10945 
10946    /* Always run again */
10947    ast_mutex_unlock(&iaxsl[fr->callno]);
10948    return 1;
10949 }

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

References ast_codec_get_samples(), AST_FRAME_VOICE, ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_test_flag, ast_tvnow(), ast_tvzero(), iax_frame::callno, ast_iax2_mini_hdr::callno, f, find_callno_locked(), find_tpeer(), fix_peerts(), iax2_vnak(), IAX_FLAG_FULL, iax_frame_wrap(), IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_STATE_STARTED, iaxfrdup2(), iaxs, chan_iax2_pvt::last, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, NEW_PREVENT, iax_frame::outoforder, iax2_trunk_peer::rxtrunktime, schedule_delivery(), iax2_trunk_peer::trunkact, iax_frame::ts, ast_iax2_mini_hdr::ts, and chan_iax2_pvt::voiceformat.

Referenced by socket_process().

09096 {
09097    unsigned char metatype;
09098    struct ast_iax2_meta_trunk_mini *mtm;
09099    struct ast_iax2_meta_trunk_hdr *mth;
09100    struct ast_iax2_meta_trunk_entry *mte;
09101    struct iax2_trunk_peer *tpeer;
09102    unsigned int ts;
09103    void *ptr;
09104    struct timeval rxtrunktime;
09105    struct ast_frame f = { 0, };
09106 
09107    if (packet_len < sizeof(*meta)) {
09108       ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 
09109          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09110       return 1;
09111    }
09112 
09113    if (meta->metacmd != IAX_META_TRUNK)
09114       return 1;
09115 
09116    if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09117       ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09118          (int) (sizeof(*meta) + sizeof(*mth)));
09119       return 1;
09120    }
09121    mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09122    ts = ntohl(mth->ts);
09123    metatype = meta->cmddata;
09124    packet_len -= (sizeof(*meta) + sizeof(*mth));
09125    ptr = mth->data;
09126    tpeer = find_tpeer(sin, sockfd);
09127    if (!tpeer) {
09128       ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 
09129          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09130       return 1;
09131    }
09132    tpeer->trunkact = ast_tvnow();
09133    if (!ts || ast_tvzero(tpeer->rxtrunktime))
09134       tpeer->rxtrunktime = tpeer->trunkact;
09135    rxtrunktime = tpeer->rxtrunktime;
09136    ast_mutex_unlock(&tpeer->lock);
09137    while (packet_len >= sizeof(*mte)) {
09138       /* Process channels */
09139       unsigned short callno, trunked_ts, len;
09140 
09141       if (metatype == IAX_META_TRUNK_MINI) {
09142          mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09143          ptr += sizeof(*mtm);
09144          packet_len -= sizeof(*mtm);
09145          len = ntohs(mtm->len);
09146          callno = ntohs(mtm->mini.callno);
09147          trunked_ts = ntohs(mtm->mini.ts);
09148       } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09149          mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09150          ptr += sizeof(*mte);
09151          packet_len -= sizeof(*mte);
09152          len = ntohs(mte->len);
09153          callno = ntohs(mte->callno);
09154          trunked_ts = 0;
09155       } else {
09156          ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09157          break;
09158       }
09159       /* Stop if we don't have enough data */
09160       if (len > packet_len)
09161          break;
09162       fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09163       if (!fr->callno)
09164          continue;
09165 
09166       /* If it's a valid call, deliver the contents.  If not, we
09167          drop it, since we don't have a scallno to use for an INVAL */
09168       /* Process as a mini frame */
09169       memset(&f, 0, sizeof(f));
09170       f.frametype = AST_FRAME_VOICE;
09171       if (!iaxs[fr->callno]) {
09172          /* drop it */
09173       } else if (iaxs[fr->callno]->voiceformat == 0) {
09174          ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09175          iax2_vnak(fr->callno);
09176       } else {
09177          f.subclass = iaxs[fr->callno]->voiceformat;
09178          f.datalen = len;
09179          if (f.datalen >= 0) {
09180             if (f.datalen)
09181                f.data.ptr = ptr;
09182             else
09183                f.data.ptr = NULL;
09184             if (trunked_ts)
09185                fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09186             else
09187                fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09188             /* Don't pass any packets until we're started */
09189             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09190                struct iax_frame *duped_fr;
09191 
09192                /* Common things */
09193                f.src = "IAX2";
09194                f.mallocd = 0;
09195                f.offset = 0;
09196                if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
09197                   f.samples = ast_codec_get_samples(&f);
09198                else
09199                   f.samples = 0;
09200                fr->outoforder = 0;
09201                iax_frame_wrap(fr, &f);
09202                duped_fr = iaxfrdup2(fr);
09203                if (duped_fr)
09204                   schedule_delivery(duped_fr, 1, 1, &fr->ts);
09205                if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09206                   iaxs[fr->callno]->last = fr->ts;
09207             }
09208          } else {
09209             ast_log(LOG_WARNING, "Datalen < 0?\n");
09210          }
09211       }
09212       ast_mutex_unlock(&iaxsl[fr->callno]);
09213       ptr += len;
09214       packet_len -= len;
09215    }
09216 
09217    return 1;
09218 }

static int socket_read ( int *  id,
int  fd,
short  events,
void *  cbdata 
) [static]

Definition at line 9016 of file chan_iax2.c.

References ast_copy_string(), ast_debug, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), iax2_thread::callno, ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), iax2_thread::list, LOG_WARNING, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, thread, and ast_iax2_full_hdr::type.

Referenced by network_thread(), peer_set_srcaddr(), and set_config().

09017 {
09018    struct iax2_thread *thread;
09019    socklen_t len;
09020    time_t t;
09021    static time_t last_errtime = 0;
09022    struct ast_iax2_full_hdr *fh;
09023 
09024    if (!(thread = find_idle_thread())) {
09025       time(&t);
09026       if (t != last_errtime)
09027          ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09028       last_errtime = t;
09029       usleep(1);
09030       return 1;
09031    }
09032 
09033    len = sizeof(thread->iosin);
09034    thread->iofd = fd;
09035    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09036    thread->buf_size = sizeof(thread->readbuf);
09037    thread->buf = thread->readbuf;
09038    if (thread->buf_len < 0) {
09039       if (errno != ECONNREFUSED && errno != EAGAIN)
09040          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09041       handle_error();
09042       thread->iostate = IAX_IOSTATE_IDLE;
09043       signal_condition(&thread->lock, &thread->cond);
09044       return 1;
09045    }
09046    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
09047       thread->iostate = IAX_IOSTATE_IDLE;
09048       signal_condition(&thread->lock, &thread->cond);
09049       return 1;
09050    }
09051    
09052    /* Determine if this frame is a full frame; if so, and any thread is currently
09053       processing a full frame for the same callno from this peer, then drop this
09054       frame (and the peer will retransmit it) */
09055    fh = (struct ast_iax2_full_hdr *) thread->buf;
09056    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09057       struct iax2_thread *cur = NULL;
09058       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09059       
09060       AST_LIST_LOCK(&active_list);
09061       AST_LIST_TRAVERSE(&active_list, cur, list) {
09062          if ((cur->ffinfo.callno == callno) &&
09063              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09064             break;
09065       }
09066       if (cur) {
09067          /* we found another thread processing a full frame for this call,
09068             so queue it up for processing later. */
09069          defer_full_frame(thread, cur);
09070          AST_LIST_UNLOCK(&active_list);
09071          thread->iostate = IAX_IOSTATE_IDLE;
09072          signal_condition(&thread->lock, &thread->cond);
09073          return 1;
09074       } else {
09075          /* this thread is going to process this frame, so mark it */
09076          thread->ffinfo.callno = callno;
09077          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09078          thread->ffinfo.type = fh->type;
09079          thread->ffinfo.csub = fh->csub;
09080       }
09081       AST_LIST_UNLOCK(&active_list);
09082    }
09083    
09084    /* Mark as ready and send on its way */
09085    thread->iostate = IAX_IOSTATE_READY;
09086 #ifdef DEBUG_SCHED_MULTITHREAD
09087    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09088 #endif
09089    signal_condition(&thread->lock, &thread->cond);
09090 
09091    return 1;
09092 }

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

Definition at line 8732 of file chan_iax2.c.

References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create_detached, ast_strdup, dp_lookup_thread(), and LOG_WARNING.

Referenced by socket_process().

08733 {
08734    pthread_t newthread;
08735    struct dpreq_data *dpr;
08736    
08737    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
08738       return;
08739 
08740    dpr->callno = callno;
08741    ast_copy_string(dpr->context, context, sizeof(dpr->context));
08742    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
08743    if (callerid)
08744       dpr->callerid = ast_strdup(callerid);
08745    if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
08746       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
08747    }
08748 }

static int start_network_thread ( void   )  [static]

Definition at line 11565 of file chan_iax2.c.

References ast_calloc, ast_cond_init(), ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), ast_pthread_create_detached, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, iax2_thread::list, LOG_WARNING, and thread.

Referenced by load_module().

11566 {
11567    struct iax2_thread *thread;
11568    int threadcount = 0;
11569    int x;
11570    for (x = 0; x < iaxthreadcount; x++) {
11571       thread = ast_calloc(1, sizeof(*thread));
11572       if (thread) {
11573          thread->type = IAX_THREAD_TYPE_POOL;
11574          thread->threadnum = ++threadcount;
11575          ast_mutex_init(&thread->lock);
11576          ast_cond_init(&thread->cond, NULL);
11577          if (ast_pthread_create_detached(&thread->threadid, NULL, iax2_process_thread, thread)) {
11578             ast_log(LOG_WARNING, "Failed to create new thread!\n");
11579             ast_free(thread);
11580             thread = NULL;
11581          }
11582          AST_LIST_LOCK(&idle_list);
11583          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
11584          AST_LIST_UNLOCK(&idle_list);
11585       }
11586    }
11587    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
11588    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
11589    ast_verb(2, "%d helper threads started\n", threadcount);
11590    return 0;
11591 }

static void stop_stuff ( int  callno  )  [static]

Definition at line 8435 of file chan_iax2.c.

References iax2_destroy_helper(), and iaxs.

Referenced by socket_process().

08436 {
08437    iax2_destroy_helper(iaxs[callno]);
08438 }

static void store_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1867 of file chan_iax2.c.

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

Referenced by __find_callno(), complete_transfer(), and socket_process().

01868 {
01869    if (!pvt->peercallno) {
01870       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01871       return;
01872    }
01873 
01874    ao2_link(iax_peercallno_pvts, pvt);
01875 }

static void store_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1848 of file chan_iax2.c.

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

Referenced by try_transfer().

01849 {
01850    if (!pvt->transfercallno) {
01851       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01852       return;
01853    }
01854 
01855    ao2_link(iax_transfercallno_pvts, pvt);
01856 }

static int timing_read ( int *  id,
int  fd,
short  events,
void *  cbdata 
) [static]

Definition at line 8621 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_debug, ast_free, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_timer_ack(), ast_tvnow(), ast_verbose, iax2_trunk_expired(), iax2_trunk_peer::lock, send_trunk(), timer, totalcalls, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.

Referenced by network_thread().

08622 {
08623    int res, processed = 0, totalcalls = 0;
08624    struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
08625    struct timeval now = ast_tvnow();
08626 
08627    if (iaxtrunkdebug)
08628       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
08629 
08630    if (timer) { 
08631       ast_timer_ack(timer, 1);
08632    }
08633 
08634    /* For each peer that supports trunking... */
08635    AST_LIST_LOCK(&tpeers);
08636    AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
08637       processed++;
08638       res = 0;
08639       ast_mutex_lock(&tpeer->lock);
08640       /* We can drop a single tpeer per pass.  That makes all this logic
08641          substantially easier */
08642       if (!drop && iax2_trunk_expired(tpeer, &now)) {
08643          /* Take it out of the list, but don't free it yet, because it
08644             could be in use */
08645          AST_LIST_REMOVE_CURRENT(list);
08646          drop = tpeer;
08647       } else {
08648          res = send_trunk(tpeer, &now);
08649          trunk_timed++; 
08650          if (iaxtrunkdebug)
08651             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);
08652       }     
08653       totalcalls += res;   
08654       res = 0;
08655       ast_mutex_unlock(&tpeer->lock);
08656    }
08657    AST_LIST_TRAVERSE_SAFE_END;
08658    AST_LIST_UNLOCK(&tpeers);
08659 
08660    if (drop) {
08661       ast_mutex_lock(&drop->lock);
08662       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
08663          because by the time they could get tpeerlock, we've already grabbed it */
08664       ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
08665       if (drop->trunkdata) {
08666          ast_free(drop->trunkdata);
08667          drop->trunkdata = NULL;
08668       }
08669       ast_mutex_unlock(&drop->lock);
08670       ast_mutex_destroy(&drop->lock);
08671       ast_free(drop);
08672       
08673    }
08674 
08675    if (iaxtrunkdebug)
08676       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
08677    iaxtrunkdebug = 0;
08678 
08679    return 1;
08680 }

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

Definition at line 13571 of file chan_iax2.c.

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

Referenced by load_objects().

13572 {
13573    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13574 
13575    /* The frames_received field is used to hold whether we're matching
13576     * against a full frame or not ... */
13577 
13578    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
13579       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13580 }

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

Definition at line 13564 of file chan_iax2.c.

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

13565 {
13566    const struct chan_iax2_pvt *pvt = obj;
13567 
13568    return pvt->transfercallno;
13569 }

static int transmit_trunk ( struct iax_frame f,
struct sockaddr_in *  sin,
int  sockfd 
) [static]

Definition at line 3057 of file chan_iax2.c.

References ast_debug, errno, f, and handle_error().

Referenced by send_trunk().

03058 {
03059    int res;
03060    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03061                sizeof(*sin));
03062    if (res < 0) {
03063       ast_debug(1, "Received error: %s\n", strerror(errno));
03064       handle_error();
03065    } else
03066       res = 0;
03067    return res;
03068 }

static int try_firmware ( char *  s  )  [static]

Definition at line 2759 of file chan_iax2.c.

References ast_calloc, AST_FILE_MODE, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strlen_zero(), ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, iax2_trunk_peer::list, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), and ast_iax2_firmware_header::version.

Referenced by reload_firmware().

02760 {
02761    struct stat stbuf;
02762    struct iax_firmware *cur = NULL;
02763    int ifd, fd, res, len, chunk;
02764    struct ast_iax2_firmware_header *fwh, fwh2;
02765    struct MD5Context md5;
02766    unsigned char sum[16], buf[1024];
02767    char *s2, *last;
02768 
02769    if (!(s2 = alloca(strlen(s) + 100))) {
02770       ast_log(LOG_WARNING, "Alloca failed!\n");
02771       return -1;
02772    }
02773 
02774    last = strrchr(s, '/');
02775    if (last)
02776       last++;
02777    else
02778       last = s;
02779 
02780    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
02781 
02782    if ((res = stat(s, &stbuf) < 0)) {
02783       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
02784       return -1;
02785    }
02786 
02787    /* Make sure it's not a directory */
02788    if (S_ISDIR(stbuf.st_mode))
02789       return -1;
02790    ifd = open(s, O_RDONLY);
02791    if (ifd < 0) {
02792       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
02793       return -1;
02794    }
02795    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
02796    if (fd < 0) {
02797       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02798       close(ifd);
02799       return -1;
02800    }
02801    /* Unlink our newly created file */
02802    unlink(s2);
02803    
02804    /* Now copy the firmware into it */
02805    len = stbuf.st_size;
02806    while(len) {
02807       chunk = len;
02808       if (chunk > sizeof(buf))
02809          chunk = sizeof(buf);
02810       res = read(ifd, buf, chunk);
02811       if (res != chunk) {
02812          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02813          close(ifd);
02814          close(fd);
02815          return -1;
02816       }
02817       res = write(fd, buf, chunk);
02818       if (res != chunk) {
02819          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02820          close(ifd);
02821          close(fd);
02822          return -1;
02823       }
02824       len -= chunk;
02825    }
02826    close(ifd);
02827    /* Return to the beginning */
02828    lseek(fd, 0, SEEK_SET);
02829    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02830       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02831       close(fd);
02832       return -1;
02833    }
02834    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02835       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02836       close(fd);
02837       return -1;
02838    }
02839    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02840       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02841       close(fd);
02842       return -1;
02843    }
02844    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02845       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02846       close(fd);
02847       return -1;
02848    }
02849    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
02850    if (fwh == MAP_FAILED) {
02851       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02852       close(fd);
02853       return -1;
02854    }
02855    MD5Init(&md5);
02856    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02857    MD5Final(sum, &md5);
02858    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02859       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02860       munmap((void*)fwh, stbuf.st_size);
02861       close(fd);
02862       return -1;
02863    }
02864 
02865    AST_LIST_TRAVERSE(&firmwares, cur, list) {
02866       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02867          /* Found a candidate */
02868          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02869             /* The version we have on loaded is older, load this one instead */
02870             break;
02871          /* This version is no newer than what we have.  Don't worry about it.
02872             We'll consider it a proper load anyhow though */
02873          munmap((void*)fwh, stbuf.st_size);
02874          close(fd);
02875          return 0;
02876       }
02877    }
02878    
02879    if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
02880       cur->fd = -1;
02881       AST_LIST_INSERT_TAIL(&firmwares, cur, list);
02882    }
02883    
02884    if (cur) {
02885       if (cur->fwh)
02886          munmap((void*)cur->fwh, cur->mmaplen);
02887       if (cur->fd > -1)
02888          close(cur->fd);
02889       cur->fwh = fwh;
02890       cur->fd = fd;
02891       cur->mmaplen = stbuf.st_size;
02892       cur->dead = 0;
02893    }
02894    
02895    return 0;
02896 }

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

Definition at line 7778 of file chan_iax2.c.

References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, inet_aton(), LOG_WARNING, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, TRANSFER_NONE, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.

Referenced by socket_process().

07779 {
07780    int newcall = 0;
07781    char newip[256];
07782    struct iax_ie_data ied;
07783    struct sockaddr_in new;
07784    
07785    
07786    memset(&ied, 0, sizeof(ied));
07787    if (ies->apparent_addr)
07788       memmove(&new, ies->apparent_addr, sizeof(new));
07789    if (ies->callno)
07790       newcall = ies->callno;
07791    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
07792       ast_log(LOG_WARNING, "Invalid transfer request\n");
07793       return -1;
07794    }
07795    pvt->transfercallno = newcall;
07796    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
07797    inet_aton(newip, &pvt->transfer.sin_addr);
07798    pvt->transfer.sin_family = AF_INET;
07799    pvt->transferid = ies->transferid;
07800    /* only store by transfercallno if this is a new transfer,
07801     * just in case we get a duplicate TXREQ */
07802    if (pvt->transferring == TRANSFER_NONE) {
07803       store_by_transfercallno(pvt);
07804    }
07805    pvt->transferring = TRANSFER_BEGIN;
07806 
07807    if (ies->transferid)
07808       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
07809    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
07810    return 0;
07811 }

static int uncompress_subclass ( unsigned char  csub  )  [static]

Definition at line 1389 of file chan_iax2.c.

References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

Referenced by decode_frame(), handle_call_token(), and socket_process().

01390 {
01391    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01392    if (csub & IAX_FLAG_SC_LOG) {
01393       /* special case for 'compressed' -1 */
01394       if (csub == 0xff)
01395          return -1;
01396       else
01397          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01398    }
01399    else
01400       return csub;
01401 }

static void unlink_peer ( struct iax2_peer peer  )  [static]

Definition at line 8069 of file chan_iax2.c.

References ao2_unlink, ast_sched_del(), iax2_peer::expire, peer_unref(), peers, iax2_peer::pokeexpire, and sched.

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

08070 {
08071    if (peer->expire > -1) {
08072       if (!ast_sched_del(sched, peer->expire)) {
08073          peer->expire = -1;
08074          peer_unref(peer);
08075       }
08076    }
08077 
08078    if (peer->pokeexpire > -1) {
08079       if (!ast_sched_del(sched, peer->pokeexpire)) {
08080          peer->pokeexpire = -1;
08081          peer_unref(peer);
08082       }
08083    }
08084 
08085    ao2_unlink(peers, peer);
08086 }

static int unload_module ( void   )  [static]

Definition at line 13529 of file chan_iax2.c.

References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.

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

Definition at line 5057 of file chan_iax2.c.

References ast_mutex_unlock().

Referenced by iax2_bridge().

05058 {
05059    ast_mutex_unlock(&iaxsl[callno1]);
05060    ast_mutex_unlock(&iaxsl[callno0]);
05061 }

static void unwrap_timestamp ( struct iax_frame fr  )  [static]

Definition at line 3724 of file chan_iax2.c.

References iax_frame::af, ast_debug, AST_FRAME_VIDEO, iax_frame::callno, ast_frame::frametype, iaxs, chan_iax2_pvt::last, and iax_frame::ts.

Referenced by schedule_delivery().

03725 {
03726    /* Video mini frames only encode the lower 15 bits of the session
03727     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
03728    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03729    const int lower_mask = (1 << ts_shift) - 1;
03730    const int upper_mask = ~lower_mask;
03731    const int last_upper = iaxs[fr->callno]->last & upper_mask;
03732 
03733    if ( (fr->ts & upper_mask) == last_upper ) {
03734       const int x = fr->ts - iaxs[fr->callno]->last;
03735       const int threshold = (ts_shift == 15) ? 25000 : 50000;
03736 
03737       if (x < -threshold) {
03738          /* Sudden big jump backwards in timestamp:
03739             What likely happened here is that miniframe timestamp has circled but we haven't
03740             gotten the update from the main packet.  We'll just pretend that we did, and
03741             update the timestamp appropriately. */
03742          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
03743          if (iaxdebug)
03744             ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
03745       } else if (x > threshold) {
03746          /* Sudden apparent big jump forwards in timestamp:
03747             What's likely happened is this is an old miniframe belonging to the previous
03748             top 15 or 16-bit timestamp that has turned up out of order.
03749             Adjust the timestamp appropriately. */
03750          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
03751          if (iaxdebug)
03752             ast_debug(1, "schedule_delivery: pushed back timestamp\n");
03753       }
03754    }
03755 }

static void update_jbsched ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 3759 of file chan_iax2.c.

References ast_tvdiff_ms(), ast_tvnow(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_replace(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, chan_iax2_pvt::rxcore, and sched.

Referenced by __get_from_jb(), and schedule_delivery().

03760 {
03761    int when;
03762    
03763    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
03764    
03765    when = jb_next(pvt->jb) - when;
03766 
03767    if (when <= 0) {
03768       /* XXX should really just empty until when > 0.. */
03769       when = 1;
03770    }
03771    
03772    pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 
03773       CALLNO_TO_PTR(pvt->callno));
03774 }

static void update_max_nontrunk ( void   )  [static]

Definition at line 1776 of file chan_iax2.c.

References ast_debug, iaxs, and TRUNK_CALL_START.

Referenced by __find_callno(), and make_trunk().

01777 {
01778    int max = 1;
01779    int x;
01780    /* XXX Prolly don't need locks here XXX */
01781    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01782       if (iaxs[x])
01783          max = x + 1;
01784    }
01785    maxnontrunkcall = max;
01786    if (iaxdebug)
01787       ast_debug(1, "New max nontrunk callno is %d\n", max);
01788 }

static void update_max_trunk ( void   )  [static]

Definition at line 1759 of file chan_iax2.c.

References ARRAY_LEN, ast_debug, iaxs, and TRUNK_CALL_START.

Referenced by iax2_destroy(), and make_trunk().

01760 {
01761    int max = TRUNK_CALL_START;
01762    int x;
01763 
01764    /* XXX Prolly don't need locks here XXX */
01765    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01766       if (iaxs[x]) {
01767          max = x + 1;
01768       }
01769    }
01770 
01771    maxtrunkcall = max;
01772    if (iaxdebug)
01773       ast_debug(1, "New max trunk callno is %d\n", max);
01774 }

static int update_packet ( struct iax_frame f  )  [static]

Definition at line 3186 of file chan_iax2.c.

References build_rand_pad(), ast_iax2_full_hdr::dcallno, decode_frame(), encrypt_frame(), f, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, and chan_iax2_pvt::iseqno.

Referenced by __attempt_transmit().

03187 {
03188    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
03189    struct ast_iax2_full_hdr *fh = f->data;
03190    struct ast_frame af;
03191 
03192    /* if frame is encrypted. decrypt before updating it. */
03193    if (f->encmethods) {
03194       decode_frame(&f->mydcx, fh, &af, &f->datalen);
03195    }
03196    /* Mark this as a retransmission */
03197    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03198    /* Update iseqno */
03199    f->iseqno = iaxs[f->callno]->iseqno;
03200    fh->iseqno = f->iseqno;
03201 
03202    /* Now re-encrypt the frame */
03203    if (f->encmethods) {
03204    /* since this is a retransmit frame, create a new random padding
03205     * before re-encrypting. */
03206       build_rand_pad(f->semirand, sizeof(f->semirand));
03207       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03208    }
03209    return 0;
03210 }

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 8180 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_strdupa, ast_strlen_zero(), ast_test_flag, ast_verb, iax2_peer::cid_name, iax2_peer::cid_num, context, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, mailbox, iax2_peer::mailbox, manager_event, iax2_peer::maxcallno, iax2_peer::name, peer_ref(), peer_unref(), peercnt_modify(), realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, strsep(), version, and iax2_peer::zonetag.

Referenced by socket_process().

08181 {
08182    /* Called from IAX thread only, with proper iaxsl lock */
08183    struct iax_ie_data ied;
08184    struct iax2_peer *p;
08185    int msgcount;
08186    char data[80];
08187    int version;
08188    const char *peer_name;
08189    int res = -1;
08190 
08191    memset(&ied, 0, sizeof(ied));
08192 
08193    peer_name = ast_strdupa(iaxs[callno]->peer);
08194 
08195    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
08196    ast_mutex_unlock(&iaxsl[callno]);
08197    if (!(p = find_peer(peer_name, 1))) {
08198       ast_mutex_lock(&iaxsl[callno]);
08199       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08200       return -1;
08201    }
08202    ast_mutex_lock(&iaxsl[callno]);
08203    if (!iaxs[callno])
08204       goto return_unref;
08205 
08206    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08207       if (sin->sin_addr.s_addr) {
08208          time_t nowtime;
08209          time(&nowtime);
08210          realtime_update_peer(peer_name, sin, nowtime);
08211       } else {
08212          realtime_update_peer(peer_name, sin, 0);
08213       }
08214    }
08215    if (inaddrcmp(&p->addr, sin)) {
08216       if (iax2_regfunk)
08217          iax2_regfunk(p->name, 1);
08218 
08219       /* modify entry in peercnts table as _not_ registered */
08220       peercnt_modify(0, 0, &p->addr);
08221 
08222       /* Stash the IP address from which they registered */
08223       memcpy(&p->addr, sin, sizeof(p->addr));
08224 
08225       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08226       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08227          ast_db_put("IAX/Registry", p->name, data);
08228          ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08229                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08230          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08231          register_peer_exten(p, 1);
08232          ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
08233       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
08234          ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08235                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08236          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08237          register_peer_exten(p, 0);
08238          ast_db_del("IAX/Registry", p->name);
08239          ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */
08240       }
08241       /* Update the host */
08242       /* Verify that the host is really there */
08243       iax2_poke_peer(p, callno);
08244    }
08245 
08246    /* modify entry in peercnts table as registered */
08247    if (p->maxcallno) {
08248       peercnt_modify(1, p->maxcallno, &p->addr);
08249    }
08250 
08251    /* Make sure our call still exists, an INVAL at the right point may make it go away */
08252    if (!iaxs[callno]) {
08253       res = -1;
08254       goto return_unref;
08255    }
08256 
08257    /* Store socket fd */
08258    p->sockfd = fd;
08259    /* Setup the expiry */
08260    if (p->expire > -1) {
08261       if (!ast_sched_del(sched, p->expire)) {
08262          p->expire = -1;
08263          peer_unref(p);
08264       }
08265    }
08266    /* treat an unspecified refresh interval as the minimum */
08267    if (!refresh)
08268       refresh = min_reg_expire;
08269    if (refresh > max_reg_expire) {
08270       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08271          p->name, max_reg_expire, refresh);
08272       p->expiry = max_reg_expire;
08273    } else if (refresh < min_reg_expire) {
08274       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08275          p->name, min_reg_expire, refresh);
08276       p->expiry = min_reg_expire;
08277    } else {
08278       p->expiry = refresh;
08279    }
08280    if (p->expiry && sin->sin_addr.s_addr) {
08281       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08282       if (p->expire == -1)
08283          peer_unref(p);
08284    }
08285    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08286    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08287    if (sin->sin_addr.s_addr) {
08288       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08289       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
08290       if (!ast_strlen_zero(p->mailbox)) {
08291          struct ast_event *event;
08292          int new, old;
08293          char *mailbox, *context;
08294 
08295          context = mailbox = ast_strdupa(p->mailbox);
08296          strsep(&context, "@");
08297          if (ast_strlen_zero(context))
08298             context = "default";
08299 
08300          event = ast_event_get_cached(AST_EVENT_MWI,
08301             AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08302             AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08303             AST_EVENT_IE_END);
08304          if (event) {
08305             new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08306             old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08307             ast_event_destroy(event);
08308          } else { /* Fall back on checking the mailbox directly */
08309             ast_app_inboxcount(p->mailbox, &new, &old);
08310          }
08311 
08312          if (new > 255) {
08313             new = 255;
08314          }
08315          if (old > 255) {
08316             old = 255;
08317          }
08318          msgcount = (old << 8) | new;
08319 
08320          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08321       }
08322       if (ast_test_flag(p, IAX_HASCALLERID)) {
08323          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08324          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08325       }
08326    }
08327    version = iax_check_version(devtype);
08328    if (version) 
08329       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08330 
08331    res = 0;
08332 
08333 return_unref:
08334    peer_unref(p);
08335 
08336    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08337 }

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

References CMP_MATCH, CMP_STOP, and user.

Referenced by load_objects().

01437 {
01438    struct iax2_user *user = obj, *user2 = arg;
01439 
01440    return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01441 }

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

Definition at line 12240 of file chan_iax2.c.

References ast_set_flag, IAX_DELME, and user.

Referenced by delete_users().

12241 {
12242    struct iax2_user *user = obj;
12243 
12244    ast_set_flag(user, IAX_DELME);
12245 
12246    return 0;
12247 }

static void user_destructor ( void *  obj  )  [static]

Definition at line 11991 of file chan_iax2.c.

References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), free_context(), and user.

Referenced by build_user().

11992 {
11993    struct iax2_user *user = obj;
11994 
11995    ast_free_ha(user->ha);
11996    free_context(user->contexts);
11997    if(user->vars) {
11998       ast_variables_destroy(user->vars);
11999       user->vars = NULL;
12000    }
12001    ast_string_field_free_memory(user);
12002 }

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

References ast_str_hash(), and user.

Referenced by load_objects().

01427 {
01428    const struct iax2_user *user = obj;
01429 
01430    return ast_str_hash(user->name);
01431 }

static struct iax2_user* user_ref ( struct iax2_user user  )  [inline, static]

Definition at line 1483 of file chan_iax2.c.

References ao2_ref, and user.

01484 {
01485    ao2_ref(user, +1);
01486    return user;
01487 }

static struct iax2_user* user_unref ( struct iax2_user user  )  [inline, static]

Definition at line 1489 of file chan_iax2.c.

References ao2_ref, and user.

Referenced by authenticate_request(), authenticate_verify(), build_user(), calltoken_required(), check_access(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), prune_users(), requirecalltoken_mark_auto(), and set_config().

01490 {
01491    ao2_ref(user, -1);
01492    return NULL;
01493 }

static void vnak_retransmit ( int  callno,
int  last 
) [static]

Definition at line 8536 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, f, iaxs, iax_frame::list, and send_packet().

Referenced by socket_process().

08537 {
08538    struct iax_frame *f;
08539 
08540    AST_LIST_LOCK(&frame_queue);
08541    AST_LIST_TRAVERSE(&frame_queue, f, list) {
08542       /* Send a copy immediately */
08543       if ((f->callno == callno) && iaxs[f->callno] &&
08544          ((unsigned char ) (f->oseqno - last) < 128) &&
08545          (f->retries >= 0)) {
08546          send_packet(f);
08547       }
08548    }
08549    AST_LIST_UNLOCK(&frame_queue);
08550 }

static int wait_for_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Note:
expects the pvt to be locked

Definition at line 4914 of file chan_iax2.c.

References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, iaxs, and chan_iax2_pvt::peercallno.

Referenced by iax2_indicate(), and iax2_setoption().

04915 {
04916    unsigned short callno = pvt->callno;
04917 
04918    if (!pvt->peercallno) {
04919       /* We don't know the remote side's call number, yet.  :( */
04920       int count = 10;
04921       while (count-- && pvt && !pvt->peercallno) {
04922          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
04923          pvt = iaxs[callno];
04924       }
04925       if (!pvt->peercallno) {
04926          return -1;
04927       }
04928    }
04929 
04930    return 0;
04931 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 13752 of file chan_iax2.c.

char accountcode[AST_MAX_ACCOUNT_CODE] [static]

Definition at line 244 of file chan_iax2.c.

Referenced by __ast_channel_alloc_ap(), __oh323_new(), ast_call_forward(), ast_cdr_setaccount(), begin_dial_channel(), build_gateway(), check_peer_ok(), dahdi_new(), dial_exec_full(), do_forward(), findmeexec(), gtalk_new(), jingle_new(), local_call(), mgcp_new(), sip_new(), and tds_log().

int adsi = 0 [static]

Definition at line 248 of file chan_iax2.c.

Referenced by build_gateway().

int amaflags = 0 [static]

Definition at line 247 of file chan_iax2.c.

Referenced by build_gateway().

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 13752 of file chan_iax2.c.

int authdebug = 1 [static]

Definition at line 160 of file chan_iax2.c.

int autokill = 0 [static]

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

Referenced by __unload_module(), build_callno_limits(), load_objects(), reload_config(), set_config_destroy(), and set_peercnt_limit().

struct ao2_container* callno_pool [static]

table of available call numbers

Definition at line 713 of file chan_iax2.c.

const unsigned int CALLNO_POOL_BUCKETS = 2699 [static]

Definition at line 718 of file chan_iax2.c.

struct ao2_container* callno_pool_trunk [static]

table of available trunk call numbers

Definition at line 716 of file chan_iax2.c.

struct ao2_container* calltoken_ignores [static]

Table containing ip addresses not requiring calltoken validation

Definition at line 757 of file chan_iax2.c.

Referenced by __unload_module(), add_calltoken_ignore(), calltoken_required(), load_objects(), reload_config(), and set_config_destroy().

struct ast_cli_entry cli_iax2[] [static]

Definition at line 13411 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

unsigned int cos

Definition at line 171 of file chan_iax2.c.

struct sockaddr_in debugaddr [static]

Definition at line 960 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_debug(), iax_outputframe(), and reload_config().

uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048 [static]

Definition at line 759 of file chan_iax2.c.

uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static]

Definition at line 761 of file chan_iax2.c.

char default_parkinglot[AST_MAX_CONTEXT] [static]

Definition at line 141 of file chan_iax2.c.

int defaultsockfd = -1 [static]

Definition at line 183 of file chan_iax2.c.

int delayreject = 0 [static]

Definition at line 249 of file chan_iax2.c.

int global_max_trunk_mtu [static]

Maximum MTU, 0 if not used

Definition at line 136 of file chan_iax2.c.

uint16_t global_maxcallno [static]

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

int global_rtautoclear = 120 [static]

Definition at line 303 of file chan_iax2.c.

struct ast_flags globalflags = { 0 } [static]

Definition at line 252 of file chan_iax2.c.

Referenced by __expire_registry(), __find_callno(), aji_create_client(), aji_load_config(), apply_general_options(), build_peer(), build_user(), check_access(), find_or_create(), find_user(), find_user_realtime(), forward_message(), handle_minivm_show_settings(), iax2_request(), iax2_trunk_queue(), load_config(), make_email_file(), populate_defaults(), send_trunk(), sendmail(), set_config(), set_config_destroy(), socket_process(), update_registry(), and vm_execmain().

int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static]

Definition at line 230 of file chan_iax2.c.

int iax2_encryption = 0 [static]

Definition at line 250 of file chan_iax2.c.

int(*) iax2_regfunk(const char *username, int onoff) = NULL

Definition at line 185 of file chan_iax2.c.

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

struct ast_switch iax2_switch [static]

Definition at line 13297 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

struct ast_channel_tech iax2_tech [static]

Definition at line 1074 of file chan_iax2.c.

Referenced by __unload_module(), acf_channel_read(), ast_iax2_new(), function_iaxpeer(), iax2_bridge(), iax2_prov_app(), and load_module().

struct ast_datastore_info iax2_variable_datastore_info [static]

Initial value:

 {
   .type = "IAX2_VARIABLE",
   .duplicate = iax2_dup_variable_datastore,
   .destroy = iax2_free_variable_datastore,
}

Definition at line 1118 of file chan_iax2.c.

Referenced by acf_iaxvar_read(), acf_iaxvar_write(), ast_iax2_new(), authenticate_reply(), iax2_call(), and socket_process().

struct ao2_container* iax_peercallno_pvts [static]

Another container of iax2_pvt structures.

Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.

Definition at line 937 of file chan_iax2.c.

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_peercallno(), and store_by_peercallno().

struct ao2_container* iax_transfercallno_pvts [static]

Another container of iax2_pvt structures.

*

Active IAX2 pvt stucts used during transfering a call are stored here.

Definition at line 953 of file chan_iax2.c.

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_transfercallno(), and store_by_transfercallno().

int iaxactivethreadcount = 0 [static]

Definition at line 502 of file chan_iax2.c.

Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().

int iaxcompat = 0 [static]

Definition at line 162 of file chan_iax2.c.

int iaxdebug = 0 [static]

Definition at line 232 of file chan_iax2.c.

int iaxdefaultdpcache = 10 * 60 [static]

Definition at line 165 of file chan_iax2.c.

int iaxdefaulttimeout = 5 [static]

Definition at line 167 of file chan_iax2.c.

int iaxdynamicthreadcount = 0 [static]

Definition at line 500 of file chan_iax2.c.

Referenced by find_idle_thread(), and iax2_process_thread().

int iaxdynamicthreadnum = 0 [static]

Definition at line 501 of file chan_iax2.c.

Referenced by find_idle_thread().

int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static]

Definition at line 499 of file chan_iax2.c.

Referenced by find_idle_thread(), and set_config().

struct ast_custom_function iaxpeer_function

Definition at line 13203 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS+1] [static]

an array of iax2 pvt structures

The container for active chan_iax2_pvt structures is implemented as an array for extremely quick direct access to the correct pvt structure based on the local call number. The local call number is used as the index into the array where the associated pvt structure is stored.

Definition at line 926 of file chan_iax2.c.

Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __find_callno(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), acf_channel_read(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), handle_cli_iax2_show_channels(), iax2_ack_registry(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_setoption(), iax2_start_transfer(), iax2_vnak(), iax2_write(), load_module(), log_jitterstats(), make_trunk(), network_thread(), register_verify(), registry_authrequest(), registry_rerequest(), resend_with_token(), save_osptoken(), save_rr(), schedule_delivery(), scheduled_destroy(), send_command_final(), send_command_locked(), send_packet(), socket_process(), socket_process_meta(), stop_stuff(), unwrap_timestamp(), update_max_nontrunk(), update_max_trunk(), update_packet(), update_registry(), vnak_retransmit(), and wait_for_peercallno().

ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static]

chan_iax2_pvt structure locks

These locks are used when accessing a pvt structure in the iaxs array. The index used here is the same as used in the iaxs array. It is the local call number for the associated pvt struct.

Definition at line 946 of file chan_iax2.c.

int iaxthreadcount = DEFAULT_THREAD_COUNT [static]

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

struct ast_custom_function iaxvar_function [static]

Definition at line 9286 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct io_context* io [static]

Definition at line 227 of file chan_iax2.c.

int jittertargetextra = 40 [static]

Definition at line 153 of file chan_iax2.c.

int lagrq_time = 10 [static]

Definition at line 149 of file chan_iax2.c.

char language[MAX_LANGUAGE] = "" [static]

Definition at line 143 of file chan_iax2.c.

int last_authmethod = 0 [static]

Definition at line 163 of file chan_iax2.c.

const time_t MAX_CALLTOKEN_DELAY = 10 [static]

Definition at line 731 of file chan_iax2.c.

int max_reg_expire [static]

Definition at line 175 of file chan_iax2.c.

int max_retries = 4 [static]

Definition at line 147 of file chan_iax2.c.

int maxauthreq = 3 [static]

Definition at line 146 of file chan_iax2.c.

int maxjitterbuffer = 1000 [static]

Definition at line 150 of file chan_iax2.c.

int maxjitterinterps = 10 [static]

Definition at line 152 of file chan_iax2.c.

int maxnontrunkcall = 1 [static]

Definition at line 1027 of file chan_iax2.c.

int maxtrunkcall = TRUNK_CALL_START [static]

Definition at line 1026 of file chan_iax2.c.

int min_reg_expire [static]

Definition at line 174 of file chan_iax2.c.

char mohinterpret[MAX_MUSICCLASS] [static]

Definition at line 245 of file chan_iax2.c.

char mohsuggest[MAX_MUSICCLASS] [static]

Definition at line 246 of file chan_iax2.c.

Referenced by check_peer_ok(), create_addr_from_peer(), and sip_alloc().

struct ast_netsock_list* netsock [static]

Definition at line 181 of file chan_iax2.c.

Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().

pthread_t netthreadid = AST_PTHREADT_NULL [static]

Definition at line 254 of file chan_iax2.c.

struct ast_netsock_list* outsock [static]

used if sourceaddress specified and bindaddr == INADDR_ANY

Definition at line 182 of file chan_iax2.c.

Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().

char* papp = "IAX2Provision" [static]

Definition at line 11195 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

char* pdescrip [static]

Initial value:

 
"  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
"the calling entity is in fact an IAXy) with the given template or\n"
"default if one is not specified.  Returns -1 on error or 0 on success.\n"

Definition at line 11197 of file chan_iax2.c.

Referenced by load_module().

struct ao2_container* peercnts [static]

Table containing peercnt objects for every ip address consuming a callno

Definition at line 751 of file chan_iax2.c.

Referenced by __unload_module(), handle_cli_iax2_show_callno_limits(), load_objects(), peercnt_add(), peercnt_modify(), peercnt_remove(), peercnt_remove_by_addr(), reload_config(), and sched_delay_remove().

struct ao2_container* peers [static]

Definition at line 745 of file chan_iax2.c.

Referenced by __iax2_show_peers(), __unload_module(), _sip_show_peers(), authenticate_reply(), build_peer(), complete_iax2_peers(), complete_iax2_unregister(), complete_sip_peer(), complete_sip_registered_peer(), complete_sip_user(), delete_users(), expire_register(), find_peer(), handle_cli_iax2_unregister(), iax2_getpeername(), iax2_getpeertrunk(), load_module(), load_objects(), manager_iax2_show_peer_list(), poke_all_peers(), prune_peers(), register_verify(), set_config(), sip_do_reload(), sip_poke_all_peers(), sip_prune_realtime(), sip_show_inuse(), sip_show_objects(), sip_show_users(), unlink_peer(), and unload_module().

int ping_time = 21 [static]

Definition at line 148 of file chan_iax2.c.

struct ast_codec_pref prefs [static]

Definition at line 127 of file chan_iax2.c.

Referenced by ast_best_codec(), ast_rtp_codec_setpref(), build_peer(), build_user(), check_access(), create_addr(), gtalk_create_member(), gtalk_load_config(), jingle_create_member(), jingle_load_config(), new_iax(), set_config(), set_local_capabilities(), and set_peer_capabilities().

char* psyn = "Provision a calling IAXy with a given template" [static]

Definition at line 11196 of file chan_iax2.c.

Referenced by load_module().

struct { ... } qos [static]

Referenced by acf_channel_read(), peer_set_srcaddr(), reload_config(), set_config(), and start_rtp().

int randomcalltokendata [static]

Definition at line 729 of file chan_iax2.c.

char regcontext[AST_MAX_CONTEXT] = "" [static]

Definition at line 144 of file chan_iax2.c.

int resyncthreshold = 1000 [static]

Definition at line 151 of file chan_iax2.c.

struct sched_context* sched [static]

Definition at line 228 of file chan_iax2.c.

ast_cond_t sched_cond [static]

Definition at line 257 of file chan_iax2.c.

ast_mutex_t sched_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]

Definition at line 256 of file chan_iax2.c.

Referenced by __unload_module(), iax2_sched_add(), iax2_sched_replace(), iax2_transmit(), and sched_thread().

pthread_t schedthreadid = AST_PTHREADT_NULL [static]

Definition at line 255 of file chan_iax2.c.

int srvlookup = 0 [static]

Definition at line 177 of file chan_iax2.c.

Referenced by build_peer().

const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static]

Definition at line 129 of file chan_iax2.c.

int test_losspct = 0 [static]

Definition at line 236 of file chan_iax2.c.

struct ast_timer* timer [static]

Definition at line 179 of file chan_iax2.c.

Referenced by __unload_module(), build_peer(), build_user(), check_timer(), find_timer(), load_module(), network_thread(), pthread_timer_ack(), pthread_timer_close(), pthread_timer_destructor(), pthread_timer_disable_continuous(), pthread_timer_enable_continuous(), pthread_timer_get_event(), pthread_timer_hash(), pthread_timer_open(), pthread_timer_set_rate(), read_pipe(), run_timer(), timing_read(), timing_test(), and write_byte().

unsigned int tos

Definition at line 170 of file chan_iax2.c.

uint16_t total_nonval_callno_used = 0 [static]

Definition at line 768 of file chan_iax2.c.

int trunk_maxmtu [static]

Definition at line 137 of file chan_iax2.c.

int trunk_nmaxmtu [static]

Trunk MTU statistics

Definition at line 137 of file chan_iax2.c.

int trunk_timed [static]

Definition at line 137 of file chan_iax2.c.

int trunk_untimed [static]

Definition at line 137 of file chan_iax2.c.

int trunkfreq = 20 [static]

Definition at line 157 of file chan_iax2.c.

int trunkmaxsize = MAX_TRUNKDATA [static]

Definition at line 158 of file chan_iax2.c.

struct ao2_container* users [static]

Definition at line 748 of file chan_iax2.c.

Referenced by __unload_module(), authenticate_request(), authenticate_verify(), build_user(), check_access(), delete_users(), find_user(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), load_module(), load_objects(), pp_each_user_exec(), prune_users(), set_config(), and unload_module().


Generated on Wed Aug 18 22:34:10 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7