Tue Mar 2 17:32:51 2010

Asterisk developer's documentation


chan_iax2.c File Reference

Implementation of Inter-Asterisk eXchange Version 2. 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  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
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   ARRAY_LEN(iaxs) / 2
#define TS_GAP_FOR_JB_RESYNC   5000

Enumerations

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

Call token validation settings.

More...
enum  iax2_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_channel_write (struct ast_channel *chan, const char *function, char *data, const char *value)
static int acf_iaxvar_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int acf_iaxvar_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
static int add_calltoken_ignore (const char *addr)
static void add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
static int addr_range_cmp_cb (void *obj, void *arg, int flags)
static int addr_range_delme_cb (void *obj, void *arg, int flags)
static int addr_range_hash_cb (const void *obj, const int flags)
static int addr_range_match_address_cb (void *obj, void *arg, int flags)
static int apply_context (struct iax2_context *con, const char *context)
static int ast_cli_netstats (struct mansession *s, int fd, int limit_fmt)
static struct ast_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
struct ast_custom_function iaxpeer_function
static struct chan_iax2_pvtiaxs [IAX_MAX_CALLS]
 an array of iax2 pvt structures
static ast_mutex_t iaxsl [ARRAY_LEN(iaxs)]
 chan_iax2_pvt structure locks
static int iaxthreadcount = DEFAULT_THREAD_COUNT
static int iaxtrunkdebug = 0
static struct ast_custom_function iaxvar_function
static struct io_contextio
static int jittertargetextra = 40
static int lagrq_time = 10
static char language [MAX_LANGUAGE] = ""
static int last_authmethod = 0
static 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.

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

#define DEBUG_SUPPORT

Definition at line 119 of file chan_iax2.c.

#define DEFAULT_CONTEXT   "default"

Definition at line 138 of file chan_iax2.c.

Referenced by check_access(), handle_cli_iax2_show_users(), and reload_config().

#define DEFAULT_DROP   3

Definition at line 117 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

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

Referenced by build_peer().

#define DEFAULT_MAX_THREAD_COUNT   100

Definition at line 114 of file chan_iax2.c.

#define DEFAULT_MAXMS   2000

Definition at line 205 of file chan_iax2.c.

#define DEFAULT_RETRY_TIME   1000

Definition at line 115 of file chan_iax2.c.

Referenced by __find_callno(), and complete_transfer().

#define DEFAULT_THREAD_COUNT   10

Definition at line 113 of file chan_iax2.c.

#define DEFAULT_TRUNKDATA   640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 487 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 124 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 408 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 210 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 187 of file chan_iax2.c.

Referenced by cache_get_callno_locked(), and set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH
Value:

Definition at line 196 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWFREE
Value:

Definition at line 201 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH

Definition at line 189 of file chan_iax2.c.

Referenced by set_config().

#define IAX_DEBUGDIGEST ( msg,
key   ) 

Definition at line 213 of file chan_iax2.c.

Referenced by iax2_key_rotate(), and socket_process().

#define MARK_IAX_SUBCLASS_TX   0x8000

Definition at line 495 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 484 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 742 of file chan_iax2.c.

Referenced by load_objects().

#define MAX_RETRY_TIME   10000

Definition at line 482 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 489 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 133 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 154 of file chan_iax2.c.

Referenced by set_config(), and set_config_destroy().

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

Definition at line 746 of file chan_iax2.c.

Referenced by load_module(), and load_objects().

#define MEMORY_SIZE   100

Definition at line 116 of file chan_iax2.c.

#define MIN_JITTER_BUFFER   10

Definition at line 485 of file chan_iax2.c.

#define MIN_RETRY_TIME   100

Definition at line 481 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME   60

Definition at line 121 of file chan_iax2.c.

Referenced by make_trunk(), and sched_delay_remove().

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

Definition at line 99 of file chan_iax2.c.

#define schedule_action ( func,
data   )     __schedule_action(func, data, __PRETTY_FUNCTION__)
#define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2
#define TS_GAP_FOR_JB_RESYNC   5000

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

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

anonymous enum
Enumerator:
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 1728 of file chan_iax2.c.

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

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

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

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

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

enum iax2_state
Enumerator:
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 258 of file chan_iax2.c.

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

Enumerator:
IAX_IOSTATE_IDLE 
IAX_IOSTATE_READY 
IAX_IOSTATE_PROCESSING 
IAX_IOSTATE_SCHEDREADY 

Definition at line 843 of file chan_iax2.c.

Enumerator:
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 850 of file chan_iax2.c.

00850                       {
00851    IAX_THREAD_TYPE_POOL,
00852    IAX_THREAD_TYPE_DYNAMIC,
00853 };

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

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

Definition at line 450 of file chan_iax2.c.


Function Documentation

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

Definition at line 3214 of file chan_iax2.c.

References chan_iax2_pvt::addr, iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_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, iax_frame::final, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, MAX_RETRY_TIME, iax_frame::oseqno, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_command(), send_packet(), ast_frame::subclass, iax_frame::transfer, iax_frame::ts, update_packet(), and iax2_registry::us.

Referenced by attempt_transmit().

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

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

Definition at line 8436 of file chan_iax2.c.

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

Referenced by auth_reject().

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

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

Definition at line 4324 of file chan_iax2.c.

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

Referenced by auto_congest().

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

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

Definition at line 8485 of file chan_iax2.c.

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

Referenced by auto_hangup().

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

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 3009 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, and iax_frame::retrans.

Referenced by __get_from_jb(), and schedule_delivery().

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

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

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

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

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 2486 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, callno_entry::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), iax2_getpeername(), iax2_sched_add(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, chan_iax2_pvt::lagid, LOG_WARNING, match(), NEW_ALLOW, new_iax(), OBJ_POINTER, parkinglot, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, replace_callno(), send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), chan_iax2_pvt::transfer, TRUNK_CALL_START, and update_max_nontrunk().

Referenced by find_callno(), and find_callno_locked().

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

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

Definition at line 3777 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, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.

Referenced by get_from_jb().

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

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

Definition at line 7763 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

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

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

Definition at line 11269 of file chan_iax2.c.

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

Referenced by iax2_poke_noanswer().

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

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

Definition at line 8548 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

08549 {
08550    struct iax2_peer *peer = (struct iax2_peer *)data;
08551    iax2_poke_peer(peer, 0);
08552    peer_unref(peer);
08553 }

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

Definition at line 6218 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(), RESULT_SHOWUSAGE, RESULT_SUCCESS, status, and iax2_peer::username.

Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().

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

static void __reg_module ( void   )  [static]

Definition at line 13776 of file chan_iax2.c.

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

Definition at line 1246 of file chan_iax2.c.

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

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

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

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

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

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

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

Definition at line 1339 of file chan_iax2.c.

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

Referenced by send_lagrq().

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

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

Definition at line 1294 of file chan_iax2.c.

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

Referenced by send_ping().

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

static int __unload_module ( void   )  [static]

Definition at line 13463 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(), delete_users(), iax2_destroy(), iax_provision_unload(), iaxactivethreadcount, reload_firmware(), sched_context_destroy(), sched_lock, thread, and iax2_thread::threadid.

Referenced by load_module(), and unload_module().

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

static void __unreg_module ( void   )  [static]

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

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

13249 {
13250    struct chan_iax2_pvt *pvt;
13251    unsigned int callno;
13252    int res = 0;
13253 
13254    if (!chan || chan->tech != &iax2_tech) {
13255       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13256       return -1;
13257    }
13258 
13259    callno = PTR_TO_CALLNO(chan->tech_pvt);
13260    ast_mutex_lock(&iaxsl[callno]);
13261    if (!(pvt = iaxs[callno])) {
13262       ast_mutex_unlock(&iaxsl[callno]);
13263       return -1;
13264    }
13265 
13266    if (!strcasecmp(args, "osptoken")) {
13267       ast_copy_string(buf, pvt->osptoken, buflen);
13268    } else if (!strcasecmp(args, "peerip")) {
13269       ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13270    } else if (!strcasecmp(args, "peername")) {
13271       ast_copy_string(buf, pvt->username, buflen);
13272    } else {
13273       res = -1;
13274    }
13275 
13276    ast_mutex_unlock(&iaxsl[callno]);
13277 
13278    return res;
13279 }

static int acf_channel_write ( struct ast_channel chan,
const char *  function,
char *  data,
const char *  value 
) [static]

Definition at line 13220 of file chan_iax2.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_string_field_set, chan_iax2_pvt::callno, LOG_ERROR, chan_iax2_pvt::osptoken, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.

13221 {
13222    struct chan_iax2_pvt *pvt;
13223    unsigned int callno;
13224    int res = 0;
13225 
13226    if (!chan || chan->tech != &iax2_tech) {
13227       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13228       return -1;
13229    }
13230 
13231    callno = PTR_TO_CALLNO(chan->tech_pvt);
13232    ast_mutex_lock(&iaxsl[callno]);
13233    if (!(pvt = iaxs[callno])) {
13234       ast_mutex_unlock(&iaxsl[callno]);
13235       return -1;
13236    }
13237 
13238    if (!strcasecmp(args, "osptoken"))
13239       ast_string_field_set(pvt, osptoken, value);
13240    else
13241       res = -1;
13242 
13243    ast_mutex_unlock(&iaxsl[callno]);
13244 
13245    return res;
13246 }

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

Definition at line 9216 of file chan_iax2.c.

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

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

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

Definition at line 9239 of file chan_iax2.c.

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

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

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

Definition at line 2239 of file chan_iax2.c.

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

Referenced by set_config().

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

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

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

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

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

Definition at line 1901 of file chan_iax2.c.

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

Referenced by load_objects().

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

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

Definition at line 1888 of file chan_iax2.c.

References addr_range::delme.

Referenced by set_config_destroy().

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

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

Definition at line 1895 of file chan_iax2.c.

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

Referenced by load_objects().

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

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

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

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

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

Definition at line 7027 of file chan_iax2.c.

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

Referenced by check_access().

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

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

Definition at line 6732 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, jb_getinfo(), iax_rr::jitter, jb_info::jitter, chan_iax2_pvt::last_iax_message, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, MARK_IAX_SUBCLASS_TX, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, and chan_iax2_pvt::remote_rr.

Referenced by handle_cli_iax2_show_netstats(), and manager_iax2_show_netstats().

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

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

Create new call, interface with the PBX core.

Definition at line 5309 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_channel::exten, chan_iax2_pvt::exten, chan_iax2_pvt::host, iax2_ami_channelupdate(), chan_iax2_pvt::iaxvars, ast_datastore::inheritance, chan_iax2_pvt::language, LOG_ERROR, LOG_WARNING, ast_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().

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

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

Definition at line 3292 of file chan_iax2.c.

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and network_thread().

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

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

Definition at line 8470 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

Definition at line 8456 of file chan_iax2.c.

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

Referenced by auth_fail().

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

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

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

Referenced by authenticate_reply(), and registry_rerequest().

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

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 7652 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, iax_ie_data::buf, chan_iax2_pvt::callno, chan_iax2_pvt::challenge, iax_ies::challenge, ast_datastore::data, DATASTORE_INHERIT_FOREVER, chan_iax2_pvt::encmethods, iax_ies::encmethods, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, ast_datastore::inheritance, LOG_ERROR, iax2_peer::mask, merge_encryption(), ast_variable::name, iax2_peer::name, ast_variable::next, iax2_peer::outkey, chan_iax2_pvt::owner, chan_iax2_pvt::peer, peer_unref(), iax_ie_data::pos, realtime_peer(), iax2_peer::secret, send_command(), chan_iax2_pvt::username, iax2_peer::username, iax_ies::username, ast_variable::value, var, and iax_ies::vars.

Referenced by socket_process().

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

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 7305 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, iax_ie_data::buf, chan_iax2_pvt::challenge, iax2_user::curauthreq, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, iax2_user::maxauthreq, OBJ_POINTER, iax_ie_data::pos, send_command(), send_command_final(), user_unref(), and chan_iax2_pvt::username.

Referenced by socket_process().

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

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

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

Referenced by socket_process().

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

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

Definition at line 4337 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

Referenced by iax2_call().

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

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

Definition at line 8500 of file chan_iax2.c.

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

Referenced by iax2_dprequest(), and iax2_provision().

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

static void build_callno_limits ( struct ast_variable v  )  [static]

Definition at line 2184 of file chan_iax2.c.

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

Referenced by set_config().

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

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

Definition at line 11589 of file chan_iax2.c.

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

Referenced by build_user().

11590 {
11591    struct iax2_context *con;
11592 
11593    if ((con = ast_calloc(1, sizeof(*con))))
11594       ast_copy_string(con->context, context, sizeof(con->context));
11595    
11596    return con;
11597 }

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

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

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

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

Definition at line 5761 of file chan_iax2.c.

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

Referenced by authenticate(), and decrypt_frame().

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

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

Create peer structure based on configuration.

Definition at line 11737 of file chan_iax2.c.

References iax2_peer::addr, iax2_peer::adsi, 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(), iax2_peer::authmethods, CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, cid_name, cid_num, context, iax2_peer::dbsecret, iax2_peer::defaddr, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::expire, iax2_peer::expiry, get_auth_methods(), get_encrypt_methods(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::inkeys, ast_variable::lineno, LOG_WARNING, iax2_peer::mailbox, mailbox, iax2_peer::mask, iax2_peer::maxcallno, iax2_peer::maxms, mwi_event_cb(), iax2_peer::mwi_event_sub, ast_variable::name, iax2_peer::name, ast_variable::next, OBJ_POINTER, iax2_peer::outkey, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), iax2_peer::peercontext, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, prefs, iax2_peer::prefs, regexten, S_OR, secret, iax2_peer::smoothing, iax2_peer::sockfd, strsep(), unlink_peer(), ast_variable::value, and zonetag.

Referenced by realtime_peer(), and set_config().

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

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

Definition at line 5751 of file chan_iax2.c.

References ast_random().

Referenced by build_ecx_key(), and update_packet().

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

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

Create in-memory user structure from configuration.

Definition at line 12001 of file chan_iax2.c.

References iax2_user::adsi, iax2_user::amaflags, ao2_alloc, ao2_find, ao2_unlink, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_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(), iax2_user::authmethods, build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_user::calltoken_required, CALLTOKEN_YES, iax2_user::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, iax2_user::dbsecret, iax2_user::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, ast_variable::lineno, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, iax2_user::name, ast_variable::next, iax2_context::next, OBJ_POINTER, parkinglot, prefs, iax2_user::prefs, secret, iax2_user::secret, user_destructor(), user_unref(), ast_variable::value, and iax2_user::vars.

Referenced by realtime_user(), and set_config().

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

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

Definition at line 12809 of file chan_iax2.c.

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

Referenced by find_cache().

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

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

Definition at line 5603 of file chan_iax2.c.

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

Referenced by schedule_delivery().

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

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

Definition at line 5470 of file chan_iax2.c.

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

Referenced by iax2_send(), and socket_process().

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

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

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

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

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

Definition at line 2389 of file chan_iax2.c.

References ast_random().

Referenced by create_callno_pools().

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

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

Definition at line 1937 of file chan_iax2.c.

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

Referenced by handle_call_token().

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

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

Definition at line 7038 of file chan_iax2.c.

References iax2_user::accountcode, iax2_user::adsi, chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::amaflags, iax2_user::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_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(), iax2_user::authmethods, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, iax_ies::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, iax_ies::codec_prefs, iax2_context::context, chan_iax2_pvt::context, context, iax2_user::contexts, iax2_user::dbsecret, DEFAULT_CONTEXT, iax_ies::dnid, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, ast_variable::file, iax_ies::format, iax2_user::ha, iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, iax2_user::language, iax_ies::language, LOG_WARNING, iax2_user::maxauthreq, iax2_user::mohinterpret, iax2_user::mohsuggest, ast_variable::name, iax2_user::name, ast_variable::next, parkinglot, iax2_user::parkinglot, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, iax_ies::rdnis, realtime_user(), secret, iax2_user::secret, user_unref(), iax_ies::username, ast_variable::value, chan_iax2_pvt::vars, iax2_user::vars, iax_ies::version, and version.

Referenced by socket_process().

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

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

Definition at line 8824 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

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

Referenced by peer_set_srcaddr().

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

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

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

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

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

Definition at line 3546 of file chan_iax2.c.

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

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

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

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

Definition at line 6459 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_unregister().

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

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

Definition at line 7856 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(), chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingtime, remove_by_peercallno(), remove_by_transfercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, store_by_peercallno(), chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.

Referenced by socket_process().

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

static unsigned char compress_subclass ( int  subclass  )  [static]

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

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

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

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

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

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

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

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

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

static int create_callno_pools ( void   )  [static]

Definition at line 2394 of file chan_iax2.c.

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

Referenced by load_objects().

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

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

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

Referenced by decrypt_frame(), and update_packet().

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

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

Definition at line 5911 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

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

Referenced by socket_read().

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

static void delete_users ( void   )  [static]

Definition at line 12245 of file chan_iax2.c.

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

Referenced by __unload_module(), and set_config_destroy().

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

static void destroy_firmware ( struct iax_firmware cur  )  [static]

Definition at line 2750 of file chan_iax2.c.

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

Referenced by reload_firmware().

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

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

Definition at line 8685 of file chan_iax2.c.

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

Referenced by dp_lookup_thread(), and socket_process().

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

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

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

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

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

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

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

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

Definition at line 8116 of file chan_iax2.c.

References __expire_registry(), and schedule_action.

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

08117 {
08118 #ifdef SCHED_MULTITHREADED
08119    if (schedule_action(__expire_registry, data))
08120 #endif      
08121       __expire_registry(data);
08122    return 0;
08123 }

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

Definition at line 12882 of file chan_iax2.c.

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

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

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

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

References __find_callno().

Referenced by iax2_poke_peer(), and socket_process().

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

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

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

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

Definition at line 1182 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_thread::cond, iax2_thread::ffinfo, iax2_process_thread(), IAX_THREAD_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, iax2_thread::init_cond, iax2_thread::init_lock, iax2_thread::lock, thread, iax2_thread::threadid, iax2_thread::threadnum, and iax2_thread::type.

Referenced by __schedule_action(), and socket_read().

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

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

Definition at line 1448 of file chan_iax2.c.

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

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

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

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

Definition at line 5643 of file chan_iax2.c.

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

Referenced by iax2_trunk_queue(), and socket_process_meta().

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

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

Definition at line 1476 of file chan_iax2.c.

References ao2_find, iax2_user::name, and OBJ_POINTER.

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

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

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

Definition at line 5455 of file chan_iax2.c.

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

Referenced by socket_process_meta().

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

static void free_context ( struct iax2_context con  )  [static]

Definition at line 11379 of file chan_iax2.c.

References ast_free, and iax2_context::next.

Referenced by build_user(), and user_destructor().

11380 {
11381    struct iax2_context *conl;
11382    while(con) {
11383       conl = con;
11384       con = con->next;
11385       ast_free(conl);
11386    }
11387 }

static void free_signaling_queue_entry ( struct signaling_queue_entry s  )  [static]

Definition at line 1576 of file chan_iax2.c.

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

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

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

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

Definition at line 13132 of file chan_iax2.c.

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

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

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

Definition at line 11599 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

11600 {
11601    int methods = 0;
11602    if (strstr(value, "rsa"))
11603       methods |= IAX_AUTH_RSA;
11604    if (strstr(value, "md5"))
11605       methods |= IAX_AUTH_MD5;
11606    if (strstr(value, "plaintext"))
11607       methods |= IAX_AUTH_PLAINTEXT;
11608    return methods;
11609 }

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

Definition at line 1325 of file chan_iax2.c.

References ast_true(), and IAX_ENCRYPT_AES128.

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

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

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

Definition at line 3853 of file chan_iax2.c.

References __get_from_jb(), and schedule_action.

Referenced by update_jbsched().

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

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

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

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

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

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

Referenced by socket_process().

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

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

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

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

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

Definition at line 3301 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_unref(), and ast_cli_args::word.

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

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

Definition at line 12786 of file chan_iax2.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 6666 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_cli_args::argc, ARRAY_LEN, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_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, jb_getinfo(), jb_info::jitter, MARK_IAX_SUBCLASS_TX, jb_info::min, chan_iax2_pvt::owner, chan_iax2_pvt::remote_rr, S_OR, and ast_cli_entry::usage.

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

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

Definition at line 6516 of file chan_iax2.c.

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

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

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

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

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

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

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

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

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

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

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

Definition at line 6625 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, ast_cli_args::fd, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), iax2_registry::us, ast_cli_entry::usage, and iax2_registry::username.

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

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

Definition at line 3568 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(), iax_frame::retries, and ast_cli_entry::usage.

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

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

Definition at line 6347 of file chan_iax2.c.

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

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

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

Definition at line 6144 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, iax2_user::authmethods, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_context::context, iax2_user::contexts, DEFAULT_CONTEXT, ast_cli_args::fd, FORMAT, FORMAT2, iax2_user::ha, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, iax2_user::inkeys, iax2_user::name, iax2_user::secret, ast_cli_entry::usage, and user_unref().

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

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

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

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

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

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

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

static void handle_deferred_full_frames ( struct iax2_thread thread  )  [static]

Handle any deferred full frames for this thread.

Definition at line 8954 of file chan_iax2.c.

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

Referenced by iax2_process_thread().

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

static int handle_error ( void   )  [static]

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

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

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

Acknowledgment received for OUR registration.

Definition at line 7921 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(), 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, iax2_registry::us, and iax_ies::username.

Referenced by socket_process().

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

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

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

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

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

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

Referenced by ast_iax2_new(), and iax2_answer().

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

static int iax2_answer ( struct ast_channel c  )  [static]

Definition at line 5219 of file chan_iax2.c.

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

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

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

Definition at line 7980 of file chan_iax2.c.

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

Referenced by iax2_register().

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

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

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

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

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

Definition at line 4675 of file chan_iax2.c.

References ast_channel::_state, add_empty_calltoken_ie(), create_addr_info::adsi, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_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(), iax_ie_data::buf, 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, create_addr_info::context, ast_channel::context, parsed_dial_string::context, create_addr(), ast_datastore::data, chan_iax2_pvt::encmethods, create_addr_info::encmethods, parsed_dial_string::exten, iax2_datetime(), iax2_sched_add(), 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, chan_iax2_pvt::initid, parsed_dial_string::key, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::nativeformats, parsed_dial_string::options, chan_iax2_pvt::osptoken, create_addr_info::outkey, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, create_addr_info::peercontext, chan_iax2_pvt::pingtime, parsed_dial_string::port, iax_ie_data::pos, create_addr_info::prefs, PTR_TO_CALLNO, secret, create_addr_info::secret, send_command(), create_addr_info::sockfd, chan_iax2_pvt::sockfd, ast_channel::tech_pvt, create_addr_info::timezone, create_addr_info::username, parsed_dial_string::username, and var.

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

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

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

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

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

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

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

static void iax2_destroy ( int  callno  )  [static]

Definition at line 3130 of file chan_iax2.c.

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

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

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

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 1529 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, iax2_user::curauthreq, 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, user_unref(), and chan_iax2_pvt::username.

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

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

static int iax2_devicestate ( void *  data  )  [static]

Part of the device state notification system ---.

Definition at line 13282 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(), parsed_dial_string::peer, and peer_unref().

13283 {
13284    struct parsed_dial_string pds;
13285    char *tmp = ast_strdupa(data);
13286    struct iax2_peer *p;
13287    int res = AST_DEVICE_INVALID;
13288 
13289    memset(&pds, 0, sizeof(pds));
13290    parse_dial_string(tmp, &pds);
13291 
13292    if (ast_strlen_zero(pds.peer)) {
13293       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13294       return res;
13295    }
13296    
13297    ast_debug(3, "Checking device state for device %s\n", pds.peer);
13298 
13299    /* SLD: FIXME: second call to find_peer during registration */
13300    if (!(p = find_peer(pds.peer, 1)))
13301       return res;
13302 
13303    res = AST_DEVICE_UNAVAILABLE;
13304    ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13305       pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13306    
13307    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
13308        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13309       /* Peer is registered, or have default IP address
13310          and a valid registration */
13311       if (p->historicms == 0 || p->historicms <= p->maxms)
13312          /* let the core figure out whether it is in use or not */
13313          res = AST_DEVICE_UNKNOWN;  
13314    }
13315 
13316    peer_unref(p);
13317 
13318    return res;
13319 }

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

Definition at line 3970 of file chan_iax2.c.

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

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

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

Definition at line 3975 of file chan_iax2.c.

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

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

static int iax2_do_register ( struct iax2_registry reg  )  [static]

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

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

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

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

Definition at line 7770 of file chan_iax2.c.

References __iax2_do_register_s(), and schedule_action.

Referenced by iax2_ack_registry(), and iax2_do_register().

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

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

Definition at line 8515 of file chan_iax2.c.

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

Referenced by find_cache(), and socket_process().

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

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

Definition at line 1125 of file chan_iax2.c.

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

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

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

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

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

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

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

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

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

Definition at line 3997 of file chan_iax2.c.

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

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

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

Definition at line 1149 of file chan_iax2.c.

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

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

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

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

Referenced by __find_callno().

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

static int iax2_getpeertrunk ( struct sockaddr_in  sin  )  [static]

Definition at line 5287 of file chan_iax2.c.

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

Referenced by check_access().

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

static int iax2_hangup ( struct ast_channel c  )  [static]

Definition at line 4867 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, iax_ie_data::buf, CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, LOG_ERROR, LOG_WARNING, iax_ie_data::pos, PTR_TO_CALLNO, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.

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

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

Definition at line 5230 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(), chan_iax2_pvt::mohinterpret, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().

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

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

Definition at line 4982 of file chan_iax2.c.

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

Referenced by iax2_send().

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

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

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

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

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

Definition at line 11292 of file chan_iax2.c.

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

Referenced by iax2_poke_peer().

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

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

Definition at line 11313 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, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax_ie_data::pos, send_command(), and iax2_peer::sockfd.

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

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

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

Definition at line 11304 of file chan_iax2.c.

References iax2_poke_peer().

Referenced by load_module().

11305 {
11306    struct iax2_peer *peer = obj;
11307 
11308    iax2_poke_peer(peer, 0);
11309 
11310    return 0;
11311 }

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

Definition at line 8555 of file chan_iax2.c.

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

Referenced by __iax2_poke_noanswer(), and socket_process().

08556 {
08557    struct iax2_peer *peer = (struct iax2_peer *)data;
08558    peer->pokeexpire = -1;
08559 #ifdef SCHED_MULTITHREADED
08560    if (schedule_action(__iax2_poke_peer_s, data))
08561 #endif      
08562       __iax2_poke_peer_s(data);
08563    return 0;
08564 }

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

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

Referenced by iax2_hangup(), and send_command_final().

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

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

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

Definition at line 10959 of file chan_iax2.c.

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

Referenced by find_idle_thread(), and start_network_thread().

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

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

Definition at line 11144 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(), NEW_FORCE, iax_ie_data::pos, send_command(), and create_addr_info::sockfd.

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

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

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

References ast_channel_trylock, ast_channel_unlock, ast_queue_control_data(), and DEADLOCK_AVOIDANCE.

Referenced by socket_process().

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

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

References ast_channel_trylock, ast_channel_unlock, ast_queue_frame(), and DEADLOCK_AVOIDANCE.

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

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

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

References ast_channel_trylock, ast_channel_unlock, ast_queue_hangup(), and DEADLOCK_AVOIDANCE.

Referenced by iax2_predestroy().

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

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

Definition at line 4976 of file chan_iax2.c.

References ast_log(), ast_null_frame, and LOG_NOTICE.

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

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

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

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

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

Definition at line 11389 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_info::capability, create_addr(), find_callno_locked(), create_addr_info::found, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, LOG_WARNING, make_trunk(), create_addr_info::maxtime, chan_iax2_pvt::maxtime, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), parsed_dial_string::peer, parsed_dial_string::port, ast_channel::readformat, create_addr_info::sockfd, and ast_channel::writeformat.

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

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

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

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

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

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

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

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

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

Definition at line 3992 of file chan_iax2.c.

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

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

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

Definition at line 3980 of file chan_iax2.c.

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

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

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

Definition at line 4934 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, ast_option_header::data, errno, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().

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

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

Definition at line 5015 of file chan_iax2.c.

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

Referenced by iax2_bridge().

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

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

Definition at line 5269 of file chan_iax2.c.

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

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

static int iax2_transmit ( struct iax_frame fr  )  [static]

Definition at line 3952 of file chan_iax2.c.

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

Referenced by iax2_send().

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

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

Definition at line 8609 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

08610 {
08611    /* Drop when trunk is about 5 seconds idle */
08612    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
08613       return 1;
08614    return 0;
08615 }

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

Definition at line 5678 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, ast_frame::data, ast_frame::datalen, DEFAULT_TRUNKDATA, f, find_tpeer(), IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, ast_frame::ptr, send_trunk(), chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.

Referenced by iax2_send().

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

static int iax2_vnak ( int  callno  )  [static]

Definition at line 8527 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_VNAK, and send_command_immediate().

Referenced by socket_process(), and socket_process_meta().

08528 {
08529    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
08530 }

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

Definition at line 6940 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, ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, PTR_TO_CALLNO, and ast_channel::tech_pvt.

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

static int iax_check_version ( char *  dev  )  [static]

Definition at line 2899 of file chan_iax2.c.

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

Referenced by update_registry().

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

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

Definition at line 978 of file chan_iax2.c.

References ast_verbose.

Referenced by load_module().

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

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

Definition at line 984 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

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

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

Definition at line 2919 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

References debugaddr, and iax_showframe().

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

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

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

Definition at line 8771 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

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

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

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

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

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

static void insert_idle_thread ( struct iax2_thread thread  )  [static]

Definition at line 1167 of file chan_iax2.c.

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

Referenced by iax2_process_thread().

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

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

Definition at line 1013 of file chan_iax2.c.

References ast_verbose.

Referenced by handle_cli_iax2_set_debug_jb().

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

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

Definition at line 989 of file chan_iax2.c.

References ast_log(), and LOG_ERROR.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

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

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

Definition at line 1001 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

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

static int load_module ( void   )  [static]

Load IAX2 module, load configuraiton ---.

Definition at line 13665 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, config, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax_debug_output(), iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), io_context_create(), io_context_destroy(), jb_error_output(), jb_setoutput(), jb_warning_output(), load_objects(), LOG_ERROR, manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), peer_set_sock_cb(), reload_firmware(), RQ_CHAR, RQ_UINTEGER2, sched_context_create(), sched_context_destroy(), SENTINEL, set_config(), and start_network_thread().

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

static int load_objects ( void   )  [static]

Definition at line 13606 of file chan_iax2.c.

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

Referenced by load_module().

13607 {
13608    peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
13609    peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
13610 
13611    if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
13612       goto container_fail;
13613    } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
13614       goto container_fail;
13615    } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
13616       goto container_fail;
13617    } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
13618       goto container_fail;
13619    } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
13620       goto container_fail;
13621    } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13622       goto container_fail;
13623    } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13624       goto container_fail;
13625    } else if (create_callno_pools()) {
13626       goto container_fail;
13627    }
13628 
13629    return 0;
13630 
13631 container_fail:
13632    if (peers) {
13633       ao2_ref(peers, -1);
13634    }
13635    if (users) {
13636       ao2_ref(users, -1);
13637    }
13638    if (iax_peercallno_pvts) {
13639       ao2_ref(iax_peercallno_pvts, -1);
13640    }
13641    if (iax_transfercallno_pvts) {
13642       ao2_ref(iax_transfercallno_pvts, -1);
13643    }
13644    if (peercnts) {
13645       ao2_ref(peercnts, -1);
13646    }
13647    if (callno_limits) {
13648       ao2_ref(callno_limits, -1);
13649    }
13650    if (calltoken_ignores) {
13651       ao2_ref(calltoken_ignores, -1);
13652    }
13653    if (callno_pool) {
13654       ao2_ref(callno_pool, -1);
13655    }
13656    if (callno_pool_trunk) {
13657       ao2_ref(callno_pool_trunk, -1);
13658    }
13659    return AST_MODULE_LOAD_FAILURE;
13660 }

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

Definition at line 5050 of file chan_iax2.c.

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

Referenced by iax2_bridge().

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

static void log_jitterstats ( unsigned short  callno  )  [static]

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

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

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

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

Definition at line 1791 of file chan_iax2.c.

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

Referenced by iax2_request(), and socket_process().

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

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

Definition at line 6509 of file chan_iax2.c.

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

Referenced by load_module().

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

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 6561 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(), RESULT_SUCCESS, status, and iax2_peer::username.

Referenced by load_module().

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

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

callback to display iax peers in manager

Definition at line 6548 of file chan_iax2.c.

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

Referenced by load_module().

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

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

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

Referenced by __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().

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

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

Definition at line 5777 of file chan_iax2.c.

References ast_aes_decrypt, ast_log(), and LOG_WARNING.

Referenced by decode_frame().

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

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

Definition at line 5801 of file chan_iax2.c.

References ast_aes_encrypt, ast_log(), and LOG_WARNING.

Referenced by encrypt_frame().

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

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

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

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

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

Definition at line 1101 of file chan_iax2.c.

Referenced by build_peer().

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

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

Definition at line 11496 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(), iax_frame::callno, f, iax2_sched_add(), iax_frame_free(), iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), iax_frame::sentyet, and timing_read().

Referenced by start_network_thread().

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

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

Definition at line 1669 of file chan_iax2.c.

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

Referenced by __find_callno().

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

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

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

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

References CMP_MATCH, CMP_STOP, and iax2_peer::name.

Referenced by load_objects().

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

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

Definition at line 12227 of file chan_iax2.c.

References ast_set_flag, and IAX_DELME.

Referenced by delete_users().

12228 {
12229    struct iax2_peer *peer = obj;
12230 
12231    ast_set_flag(peer, IAX_DELME);
12232 
12233    return 0;
12234 }

static void peer_destructor ( void *  obj  )  [static]

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

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

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

References ast_str_hash(), and iax2_peer::name.

Referenced by load_objects().

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

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

Definition at line 1464 of file chan_iax2.c.

References ao2_ref.

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

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

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

Definition at line 13560 of file chan_iax2.c.

References iax2_peer::sockfd.

Referenced by load_module().

13561 {
13562    struct iax2_peer *peer = obj;
13563 
13564    if (peer->sockfd < 0)
13565       peer->sockfd = defaultsockfd;
13566 
13567    return 0;
13568 }

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

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

Referenced by build_peer().

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

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

peer_status: Report Peer status in character string

Definition at line 3447 of file chan_iax2.c.

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

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

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

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

Definition at line 2075 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

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

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

Definition at line 1915 of file chan_iax2.c.

References peercnt::addr, CMP_MATCH, and CMP_STOP.

Referenced by load_objects().

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

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

Definition at line 1909 of file chan_iax2.c.

References peercnt::addr.

Referenced by load_objects().

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

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

Definition at line 2047 of file chan_iax2.c.

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

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

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

static void peercnt_remove ( struct peercnt peercnt  )  [static]

Definition at line 2127 of file chan_iax2.c.

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

Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().

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

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

Definition at line 2166 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

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

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

Definition at line 2152 of file chan_iax2.c.

References ao2_ref, and peercnt_remove().

Referenced by sched_delay_remove().

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

static void poke_all_peers ( void   )  [static]

Definition at line 12743 of file chan_iax2.c.

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

Referenced by reload_config().

12744 {
12745    struct ao2_iterator i;
12746    struct iax2_peer *peer;
12747 
12748    i = ao2_iterator_init(peers, 0);
12749    while ((peer = ao2_iterator_next(&i))) {
12750       iax2_poke_peer(peer, 0);
12751       peer_unref(peer);
12752    }
12753    ao2_iterator_destroy(&i);
12754 }

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

Definition at line 2036 of file chan_iax2.c.

References CMP_MATCH, and addr_range::delme.

Referenced by reload_config().

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

static void prune_peers ( void   )  [static]

Definition at line 12288 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_prune_realtime(), and reload_config().

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

static void prune_users ( void   )  [static]

Definition at line 12272 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_prune_realtime(), and reload_config().

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

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

Definition at line 13577 of file chan_iax2.c.

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

Referenced by load_objects().

13578 {
13579    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13580 
13581    /* The frames_received field is used to hold whether we're matching
13582     * against a full frame or not ... */
13583 
13584    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
13585       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13586 }

static void pvt_destructor ( void *  obj  )  [static]

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

Referenced by new_iax().

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

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

Definition at line 13570 of file chan_iax2.c.

References chan_iax2_pvt::peercallno.

Referenced by load_objects().

13571 {
13572    const struct chan_iax2_pvt *pvt = obj;
13573 
13574    return pvt->peercallno;
13575 }

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

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

Referenced by __send_command().

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

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

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

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

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

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

Definition at line 4013 of file chan_iax2.c.

References iax2_peer::addr, ao2_link, ast_copy_flags, ast_debug, ast_get_time_t(), ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_peer(), iax2_peer::expire, expire_registry(), hp, iax2_sched_add(), IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, iax2_peer::name, ast_variable::name, ast_variable::next, peer_ref(), peer_unref(), realtime_update_peer(), reg_source_db(), SENTINEL, ast_variable::value, and var.

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

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

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

Definition at line 4204 of file chan_iax2.c.

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

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

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

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

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

Definition at line 4133 of file chan_iax2.c.

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

Referenced by calltoken_required(), and check_access().

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

static void reg_source_db ( struct iax2_peer p  )  [static]

Definition at line 8127 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, iax2_peer::name, peer_ref(), peer_unref(), and register_peer_exten().

Referenced by realtime_peer(), and set_config().

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

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

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

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

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

Verify inbound registration.

Definition at line 7436 of file chan_iax2.c.

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

Referenced by socket_process().

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

static int registry_authrequest ( int  callno  )  [static]

Definition at line 8335 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

Definition at line 8383 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_ie_data::buf, iax_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, REG_STATE_NOAUTH, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.

Referenced by socket_process().

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

static char* regstate2str ( int  regstate  )  [static]

Definition at line 6603 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_show_registry().

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

static int reload ( void   )  [static]

Definition at line 12804 of file chan_iax2.c.

References reload_config().

12805 {
12806    return reload_config();
12807 }

static int reload_config ( void   )  [static]

Definition at line 12755 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_reload(), and reload().

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

static void reload_firmware ( int  unload  )  [static]

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

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

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

static void remove_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1878 of file chan_iax2.c.

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

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

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

static void remove_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1859 of file chan_iax2.c.

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

Referenced by complete_transfer(), and iax2_destroy().

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

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

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

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

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

Definition at line 4492 of file chan_iax2.c.

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

Referenced by handle_call_token().

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

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

Definition at line 4408 of file chan_iax2.c.

References iax_frame::af, 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, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, iax_frame::encmethods, ast_frame::frametype, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, remove_by_peercallno(), chan_iax2_pvt::rseqno, send_command(), and ast_frame::subclass.

Referenced by socket_process().

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

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

Definition at line 8864 of file chan_iax2.c.

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

Referenced by socket_process().

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

static void save_rr ( struct iax_frame fr,
struct iax_ies ies 
) [static]
static void sched_delay_remove ( struct sockaddr_in *  sin,
struct callno_entry callno_entry 
) [static]

Definition at line 2436 of file chan_iax2.c.

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

Referenced by pvt_destructor().

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

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

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

Referenced by start_network_thread().

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

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 3868 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, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, ast_frame::subclass, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().

Referenced by socket_process(), and socket_process_meta().

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

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

Definition at line 1562 of file chan_iax2.c.

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

Referenced by iax2_hangup().

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

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

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

Referenced by handle_call_token(), and socket_process().

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

static int send_command ( struct chan_iax2_pvt i,
char  type,
int  command,
unsigned int  ts,
const unsigned char *  data,
int  datalen,
int  seqno 
) [static]
static int send_command_final ( struct chan_iax2_pvt i,
char  type,
int  command,
unsigned int  ts,
const unsigned char *  data,
int  datalen,
int  seqno 
) [static]
Note:
Since this function calls iax2_predestroy() -> iax2_queue_hangup(), the pvt struct for the given call number may disappear during its execution.

Definition at line 7007 of file chan_iax2.c.

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

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

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

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

Definition at line 7017 of file chan_iax2.c.

References __send_command().

Referenced by iax2_vnak(), and socket_process().

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

static int send_command_locked ( unsigned short  callno,
char  type,
int  command,
unsigned int  ts,
const unsigned char *  data,
int  datalen,
int  seqno 
) [static]

Definition at line 6993 of file chan_iax2.c.

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

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

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

static int send_command_transfer ( struct chan_iax2_pvt i,
char  type,
int  command,
unsigned int  ts,
const unsigned char *  data,
int  datalen 
) [static]

Definition at line 7022 of file chan_iax2.c.

References __send_command().

Referenced by socket_process(), and try_transfer().

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

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

Definition at line 1360 of file chan_iax2.c.

References __send_lagrq(), and schedule_action.

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

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

static int send_packet ( struct iax_frame f  )  [static]

Definition at line 3071 of file chan_iax2.c.

References chan_iax2_pvt::addr, iax2_trunk_peer::addr, ast_debug, ast_inet_ntoa(), iax_frame::callno, iax_frame::data, iax_frame::datalen, errno, handle_error(), iax_showframe(), chan_iax2_pvt::peercallno, iax2_trunk_peer::sockfd, chan_iax2_pvt::transfer, transfer, iax_frame::transfer, and iax_frame::ts.

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

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

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

Definition at line 1315 of file chan_iax2.c.

References __send_ping(), and schedule_action.

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

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

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

References AST_LIST_REMOVE_HEAD, signaling_queue_entry::f, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_send(), s, and chan_iax2_pvt::signaling_queue.

Referenced by socket_process().

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

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

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

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

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

Load configuration.

Definition at line 12322 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_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_ENCRYPT_KEYROTATE, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_TRUNK_MTU, MAX_TRUNKDATA, ast_variable::name, ast_variable::next, peer_unref(), prefs, qos, reg_source_db(), secret, set_config_destroy(), socket_read(), user_unref(), and ast_variable::value.

Referenced by load_module(), and reload_config().

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

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

Definition at line 1996 of file chan_iax2.c.

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

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

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

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

Definition at line 2022 of file chan_iax2.c.

References ast_debug, and set_peercnt_limit().

Referenced by reload_config().

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

static void signal_condition ( ast_mutex_t lock,
ast_cond_t cond 
) [static]
static int socket_process ( struct iax2_thread thread  )  [static]

Definition at line 9290 of file chan_iax2.c.

References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, 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(), chan_iax2_pvt::authmethods, iax_ie_data::buf, iax2_thread::buf, iax2_thread::buf_len, CACHE_FLAG_TRANSMITTED, iax_frame::cacheable, calc_timestamp(), iax_ies::called_number, iax2_peer::callno, chan_iax2_pvt::callno, iax_frame::callno, iax_ies::calltoken, iax_ies::calltokendata, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, check_access(), check_provisioning(), chan_iax2_pvt::chosenformat, chan_iax2_pvt::cid_num, cid_num, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), context, chan_iax2_pvt::context, ast_iax2_full_hdr::csub, ast_datastore::data, ast_frame::data, ast_frame::datalen, DATASTORE_INHERIT_FOREVER, ast_iax2_full_hdr::dcallno, DEADLOCK_AVOIDANCE, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::encmethods, iax_ies::encmethods, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, chan_iax2_pvt::exten, 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, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, chan_iax2_pvt::hold_signaling, 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_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(), chan_iax2_pvt::iaxvars, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::initid, chan_iax2_pvt::inkeys, iax2_thread::iofd, iax2_thread::iosin, chan_iax2_pvt::iseqno, iax_frame::iseqno, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, ast_frame::len, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event, iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, chan_iax2_pvt::mohsuggest, iax_ies::musiconhold, iax2_peer::name, ast_variable::name, ast_channel::nativeformats, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, ast_variable::next, ast_frame::offset, chan_iax2_pvt::oseqno, iax_frame::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::outoforder, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), peer_ref(), peer_unref(), chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, iax_ies::provver, iax_ies::provverpres, ast_frame::ptr, raw_hangup(), ast_channel::readformat, iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rprefs, chan_iax2_pvt::rseqno, S_OR, ast_frame::samples, save_osptoken(), save_rr(), ast_iax2_full_hdr::scallno, schedule_delivery(), chan_iax2_pvt::secret, send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), send_signaling(), iax_ies::serviceident, iax2_peer::smoothing, socket_process_meta(), spawn_dp_lookup(), ast_frame::src, chan_iax2_pvt::state, stop_stuff(), store_by_peercallno(), ast_frame::subclass, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MEDIAPASS, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), iax_frame::ts, ast_iax2_full_hdr::ts, ast_iax2_full_hdr::type, uncompress_subclass(), update_registry(), iax_ies::username, ast_variable::value, var, iax_ies::vars, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.

Referenced by handle_deferred_full_frames(), and iax2_process_thread().

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

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

References ast_codec_get_samples(), AST_FRAME_VOICE, ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_test_flag, ast_tvnow(), ast_tvzero(), iax_frame::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, ast_iax2_meta_hdr::cmddata, ast_frame::data, ast_iax2_meta_trunk_hdr::data, ast_iax2_meta_hdr::data, ast_frame::datalen, find_callno_locked(), find_tpeer(), fix_peerts(), ast_frame::frametype, iax2_vnak(), IAX_FLAG_FULL, iax_frame_wrap(), IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_STATE_STARTED, iaxfrdup2(), chan_iax2_pvt::last, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_frame::mallocd, ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, NEW_PREVENT, ast_frame::offset, iax_frame::outoforder, ast_frame::ptr, iax2_trunk_peer::rxtrunktime, ast_frame::samples, schedule_delivery(), ast_frame::src, chan_iax2_pvt::state, ast_frame::subclass, iax2_trunk_peer::trunkact, iax_frame::ts, ast_iax2_mini_hdr::ts, ast_iax2_meta_trunk_hdr::ts, and chan_iax2_pvt::voiceformat.

Referenced by socket_process().

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

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

Definition at line 9012 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::buf, iax2_thread::buf_len, iax2_thread::buf_size, iax2_thread::callno, iax2_thread::cond, ast_iax2_full_hdr::csub, iax2_thread::csub, iax2_thread::curfunc, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), iax2_thread::iofd, iax2_thread::iosin, iax2_thread::iostate, iax2_thread::lock, LOG_WARNING, iax2_thread::readbuf, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, thread, ast_iax2_full_hdr::type, and iax2_thread::type.

Referenced by peer_set_srcaddr(), and set_config().

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

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

Definition at line 8728 of file chan_iax2.c.

References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create_detached, ast_strdup, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, dp_lookup_thread(), and LOG_WARNING.

Referenced by socket_process().

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

static int start_network_thread ( void   )  [static]

Definition at line 11561 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_background, ast_pthread_create_detached, ast_verb, iax2_thread::cond, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, iax2_thread::lock, LOG_WARNING, network_thread(), sched_thread(), thread, iax2_thread::threadid, iax2_thread::threadnum, and iax2_thread::type.

Referenced by load_module().

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

static void stop_stuff ( int  callno  )  [static]

Definition at line 8431 of file chan_iax2.c.

References iax2_destroy_helper().

Referenced by socket_process().

08432 {
08433    iax2_destroy_helper(iaxs[callno]);
08434 }

static void store_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1868 of file chan_iax2.c.

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

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

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

static void store_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1849 of file chan_iax2.c.

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

Referenced by try_transfer().

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

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

Definition at line 8617 of file chan_iax2.c.

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

Referenced by network_thread().

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

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

Definition at line 13595 of file chan_iax2.c.

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

Referenced by load_objects().

13596 {
13597    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13598 
13599    /* The frames_received field is used to hold whether we're matching
13600     * against a full frame or not ... */
13601 
13602    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
13603       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13604 }

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

Definition at line 13588 of file chan_iax2.c.

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

13589 {
13590    const struct chan_iax2_pvt *pvt = obj;
13591 
13592    return pvt->transfercallno;
13593 }

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

Definition at line 3058 of file chan_iax2.c.

References ast_debug, iax_frame::data, iax_frame::datalen, errno, and handle_error().

Referenced by send_trunk().

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

static int try_firmware ( char *  s  )  [static]

Definition at line 2760 of file chan_iax2.c.

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

Referenced by reload_firmware().

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

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

Definition at line 7779 of file chan_iax2.c.

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

Referenced by socket_process().

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

static int uncompress_subclass ( unsigned char  csub  )  [static]

Definition at line 1390 of file chan_iax2.c.

References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

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

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

static void unlink_peer ( struct iax2_peer peer  )  [static]

Definition at line 8065 of file chan_iax2.c.

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

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

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

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

Definition at line 5058 of file chan_iax2.c.

References ast_mutex_unlock().

Referenced by iax2_bridge().

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

static void unwrap_timestamp ( struct iax_frame fr  )  [static]

Definition at line 3725 of file chan_iax2.c.

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

Referenced by schedule_delivery().

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

static void update_jbsched ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 3760 of file chan_iax2.c.

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

Referenced by __get_from_jb(), and schedule_delivery().

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

static void update_max_nontrunk ( void   )  [static]

Definition at line 1777 of file chan_iax2.c.

References ast_debug, and TRUNK_CALL_START.

Referenced by __find_callno(), and make_trunk().

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

static void update_max_trunk ( void   )  [static]

Definition at line 1760 of file chan_iax2.c.

References ARRAY_LEN, ast_debug, and TRUNK_CALL_START.

Referenced by iax2_destroy(), and make_trunk().

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

static int update_packet ( struct iax_frame f  )  [static]

Definition at line 3187 of file chan_iax2.c.

References build_rand_pad(), iax_frame::callno, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, ast_iax2_full_hdr::dcallno, decode_frame(), iax_frame::ecx, iax_frame::encmethods, encrypt_frame(), IAX_FLAG_RETRANS, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, iax_frame::mydcx, and iax_frame::semirand.

Referenced by __attempt_transmit().

03188 {
03189    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
03190    struct ast_iax2_full_hdr *fh = f->data;
03191    struct ast_frame af;
03192 
03193    /* if frame is encrypted. decrypt before updating it. */
03194    if (f->encmethods) {
03195       decode_frame(&f->mydcx, fh, &af, &f->datalen);
03196    }
03197    /* Mark this as a retransmission */
03198    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03199    /* Update iseqno */
03200    f->iseqno = iaxs[f->callno]->iseqno;
03201    fh->iseqno = f->iseqno;
03202 
03203    /* Now re-encrypt the frame */
03204    if (f->encmethods) {
03205    /* since this is a retransmit frame, create a new random padding
03206     * before re-encrypting. */
03207       build_rand_pad(f->semirand, sizeof(f->semirand));
03208       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03209    }
03210    return 0;
03211 }

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 8176 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, iax_ie_data::buf, iax2_peer::cid_name, iax2_peer::cid_num, context, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, inaddrcmp(), LOG_NOTICE, LOG_WARNING, mailbox, iax2_peer::mailbox, manager_event, iax2_peer::maxcallno, iax2_peer::name, peer_ref(), peer_unref(), peercnt_modify(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), send_command_final(), iax2_peer::sockfd, strsep(), version, and iax2_peer::zonetag.

Referenced by socket_process().

08177 {
08178    /* Called from IAX thread only, with proper iaxsl lock */
08179    struct iax_ie_data ied;
08180    struct iax2_peer *p;
08181    int msgcount;
08182    char data[80];
08183    int version;
08184    const char *peer_name;
08185    int res = -1;
08186 
08187    memset(&ied, 0, sizeof(ied));
08188 
08189    peer_name = ast_strdupa(iaxs[callno]->peer);
08190 
08191    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
08192    ast_mutex_unlock(&iaxsl[callno]);
08193    if (!(p = find_peer(peer_name, 1))) {
08194       ast_mutex_lock(&iaxsl[callno]);
08195       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08196       return -1;
08197    }
08198    ast_mutex_lock(&iaxsl[callno]);
08199    if (!iaxs[callno])
08200       goto return_unref;
08201 
08202    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08203       if (sin->sin_addr.s_addr) {
08204          time_t nowtime;
08205          time(&nowtime);
08206          realtime_update_peer(peer_name, sin, nowtime);
08207       } else {
08208          realtime_update_peer(peer_name, sin, 0);
08209       }
08210    }
08211    if (inaddrcmp(&p->addr, sin)) {
08212       if (iax2_regfunk)
08213          iax2_regfunk(p->name, 1);
08214 
08215       /* modify entry in peercnts table as _not_ registered */
08216       peercnt_modify(0, 0, &p->addr);
08217 
08218       /* Stash the IP address from which they registered */
08219       memcpy(&p->addr, sin, sizeof(p->addr));
08220 
08221       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08222       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08223          ast_db_put("IAX/Registry", p->name, data);
08224          ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08225                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08226          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08227          register_peer_exten(p, 1);
08228          ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
08229       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
08230          ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08231                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08232          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08233          register_peer_exten(p, 0);
08234          ast_db_del("IAX/Registry", p->name);
08235          ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */
08236       }
08237       /* Update the host */
08238       /* Verify that the host is really there */
08239       iax2_poke_peer(p, callno);
08240    }
08241 
08242    /* modify entry in peercnts table as registered */
08243    if (p->maxcallno) {
08244       peercnt_modify(1, p->maxcallno, &p->addr);
08245    }
08246 
08247    /* Make sure our call still exists, an INVAL at the right point may make it go away */
08248    if (!iaxs[callno]) {
08249       res = -1;
08250       goto return_unref;
08251    }
08252 
08253    /* Store socket fd */
08254    p->sockfd = fd;
08255    /* Setup the expiry */
08256    if (p->expire > -1) {
08257       if (!ast_sched_del(sched, p->expire)) {
08258          p->expire = -1;
08259          peer_unref(p);
08260       }
08261    }
08262    /* treat an unspecified refresh interval as the minimum */
08263    if (!refresh)
08264       refresh = min_reg_expire;
08265    if (refresh > max_reg_expire) {
08266       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08267          p->name, max_reg_expire, refresh);
08268       p->expiry = max_reg_expire;
08269    } else if (refresh < min_reg_expire) {
08270       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08271          p->name, min_reg_expire, refresh);
08272       p->expiry = min_reg_expire;
08273    } else {
08274       p->expiry = refresh;
08275    }
08276    if (p->expiry && sin->sin_addr.s_addr) {
08277       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08278       if (p->expire == -1)
08279          peer_unref(p);
08280    }
08281    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08282    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08283    if (sin->sin_addr.s_addr) {
08284       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08285       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
08286       if (!ast_strlen_zero(p->mailbox)) {
08287          struct ast_event *event;
08288          int new, old;
08289          char *mailbox, *context;
08290 
08291          context = mailbox = ast_strdupa(p->mailbox);
08292          strsep(&context, "@");
08293          if (ast_strlen_zero(context))
08294             context = "default";
08295 
08296          event = ast_event_get_cached(AST_EVENT_MWI,
08297             AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08298             AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08299             AST_EVENT_IE_END);
08300          if (event) {
08301             new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08302             old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08303             ast_event_destroy(event);
08304          } else { /* Fall back on checking the mailbox directly */
08305             ast_app_inboxcount(p->mailbox, &new, &old);
08306          }
08307 
08308          if (new > 255) {
08309             new = 255;
08310          }
08311          if (old > 255) {
08312             old = 255;
08313          }
08314          msgcount = (old << 8) | new;
08315 
08316          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08317       }
08318       if (ast_test_flag(p, IAX_HASCALLERID)) {
08319          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08320          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08321       }
08322    }
08323    version = iax_check_version(devtype);
08324    if (version) 
08325       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08326 
08327    res = 0;
08328 
08329 return_unref:
08330    peer_unref(p);
08331 
08332    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08333 }

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

References CMP_MATCH, CMP_STOP, and iax2_user::name.

Referenced by load_objects().

01438 {
01439    struct iax2_user *user = obj, *user2 = arg;
01440 
01441    return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01442 }

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

Definition at line 12236 of file chan_iax2.c.

References ast_set_flag, and IAX_DELME.

Referenced by delete_users().

12237 {
12238    struct iax2_user *user = obj;
12239 
12240    ast_set_flag(user, IAX_DELME);
12241 
12242    return 0;
12243 }

static void user_destructor ( void *  obj  )  [static]

Definition at line 11987 of file chan_iax2.c.

References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), iax2_user::contexts, free_context(), iax2_user::ha, and iax2_user::vars.

Referenced by build_user().

11988 {
11989    struct iax2_user *user = obj;
11990 
11991    ast_free_ha(user->ha);
11992    free_context(user->contexts);
11993    if(user->vars) {
11994       ast_variables_destroy(user->vars);
11995       user->vars = NULL;
11996    }
11997    ast_string_field_free_memory(user);
11998 }

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

References ast_str_hash(), and iax2_user::name.

Referenced by load_objects().

01428 {
01429    const struct iax2_user *user = obj;
01430 
01431    return ast_str_hash(user->name);
01432 }

static struct iax2_user* user_ref ( struct iax2_user user  )  [static, read]

Definition at line 1484 of file chan_iax2.c.

References ao2_ref.

01485 {
01486    ao2_ref(user, +1);
01487    return user;
01488 }

static struct iax2_user* user_unref ( struct iax2_user user  )  [static, read]
static void vnak_retransmit ( int  callno,
int  last 
) [static]

Definition at line 8532 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax_frame::callno, f, iax_frame::oseqno, iax_frame::retries, and send_packet().

Referenced by socket_process().

08533 {
08534    struct iax_frame *f;
08535 
08536    AST_LIST_LOCK(&frame_queue);
08537    AST_LIST_TRAVERSE(&frame_queue, f, list) {
08538       /* Send a copy immediately */
08539       if ((f->callno == callno) && iaxs[f->callno] &&
08540          ((unsigned char ) (f->oseqno - last) < 128) &&
08541          (f->retries >= 0)) {
08542          send_packet(f);
08543       }
08544    }
08545    AST_LIST_UNLOCK(&frame_queue);
08546 }

static int wait_for_peercallno ( struct chan_iax2_pvt pvt  )  [static]
Note:
expects the pvt to be locked

Definition at line 4915 of file chan_iax2.c.

References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, and chan_iax2_pvt::peercallno.

Referenced by iax2_indicate(), and iax2_setoption().

04916 {
04917    unsigned short callno = pvt->callno;
04918 
04919    if (!pvt->peercallno) {
04920       /* We don't know the remote side's call number, yet.  :( */
04921       int count = 10;
04922       while (count-- && pvt && !pvt->peercallno) {
04923          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
04924          pvt = iaxs[callno];
04925       }
04926       if (!pvt->peercallno) {
04927          return -1;
04928       }
04929    }
04930 
04931    return 0;
04932 }


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

char accountcode[AST_MAX_ACCOUNT_CODE] [static]
int adsi = 0 [static]

Definition at line 247 of file chan_iax2.c.

int amaflags = 0 [static]

Definition at line 246 of file chan_iax2.c.

Definition at line 13776 of file chan_iax2.c.

int authdebug = 1 [static]

Definition at line 159 of file chan_iax2.c.

int autokill = 0 [static]

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

struct ao2_container* callno_pool [static]

table of available call numbers

Definition at line 712 of file chan_iax2.c.

const unsigned int CALLNO_POOL_BUCKETS = 2699 [static]

Definition at line 717 of file chan_iax2.c.

struct ao2_container* callno_pool_trunk [static]

table of available trunk call numbers

Definition at line 715 of file chan_iax2.c.

struct ao2_container* calltoken_ignores [static]

Table containing ip addresses not requiring calltoken validation

Definition at line 756 of file chan_iax2.c.

struct ast_cli_entry cli_iax2[] [static]

Definition at line 13435 of file chan_iax2.c.

unsigned int cos

Definition at line 170 of file chan_iax2.c.

struct sockaddr_in debugaddr [static]

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

uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static]

Definition at line 760 of file chan_iax2.c.

char default_parkinglot[AST_MAX_CONTEXT] [static]

Definition at line 140 of file chan_iax2.c.

int defaultsockfd = -1 [static]

Definition at line 182 of file chan_iax2.c.

int delayreject = 0 [static]

Definition at line 248 of file chan_iax2.c.

int global_max_trunk_mtu [static]

Maximum MTU, 0 if not used

Definition at line 135 of file chan_iax2.c.

uint16_t global_maxcallno [static]

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

int global_rtautoclear = 120 [static]

Definition at line 302 of file chan_iax2.c.

struct ast_flags globalflags = { 0 } [static]

Definition at line 251 of file chan_iax2.c.

int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static]

Definition at line 229 of file chan_iax2.c.

int iax2_encryption = 0 [static]

Definition at line 249 of file chan_iax2.c.

int(* iax2_regfunk)(const char *username, int onoff) = NULL
struct ast_switch iax2_switch [static]

Definition at line 13321 of file chan_iax2.c.

struct ast_channel_tech iax2_tech [static]

Definition at line 1074 of file chan_iax2.c.

Initial value:
 {
   .type = "IAX2_VARIABLE",
   .duplicate = iax2_dup_variable_datastore,
   .destroy = iax2_free_variable_datastore,
}

Definition at line 1119 of file chan_iax2.c.

Another container of iax2_pvt structures.

Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.

Definition at line 936 of file chan_iax2.c.

Another container of iax2_pvt structures.

* Active IAX2 pvt stucts used during transfering a call are stored here.

Definition at line 952 of file chan_iax2.c.

int iaxactivethreadcount = 0 [static]

Definition at line 501 of file chan_iax2.c.

Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().

int iaxcompat = 0 [static]

Definition at line 161 of file chan_iax2.c.

int iaxdebug = 0 [static]

Definition at line 231 of file chan_iax2.c.

int iaxdefaultdpcache = 10 * 60 [static]

Definition at line 164 of file chan_iax2.c.

int iaxdefaulttimeout = 5 [static]

Definition at line 166 of file chan_iax2.c.

int iaxdynamicthreadcount = 0 [static]

Definition at line 499 of file chan_iax2.c.

Referenced by find_idle_thread(), and iax2_process_thread().

int iaxdynamicthreadnum = 0 [static]

Definition at line 500 of file chan_iax2.c.

Referenced by find_idle_thread().

int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static]

Definition at line 498 of file chan_iax2.c.

Referenced by find_idle_thread(), and set_config().

Definition at line 13199 of file chan_iax2.c.

struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static]

an array of iax2 pvt structures

The container for active chan_iax2_pvt structures is implemented as an array for extremely quick direct access to the correct pvt structure based on the local call number. The local call number is used as the index into the array where the associated pvt structure is stored.

Definition at line 925 of file chan_iax2.c.

ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static]

chan_iax2_pvt structure locks

These locks are used when accessing a pvt structure in the iaxs array. The index used here is the same as used in the iaxs array. It is the local call number for the associated pvt struct.

Definition at line 945 of file chan_iax2.c.

int iaxthreadcount = DEFAULT_THREAD_COUNT [static]

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

Definition at line 9282 of file chan_iax2.c.

struct io_context* io [static]

Definition at line 226 of file chan_iax2.c.

int jittertargetextra = 40 [static]

Definition at line 152 of file chan_iax2.c.

int lagrq_time = 10 [static]

Definition at line 148 of file chan_iax2.c.

char language[MAX_LANGUAGE] = "" [static]

Definition at line 142 of file chan_iax2.c.

int last_authmethod = 0 [static]

Definition at line 162 of file chan_iax2.c.

const time_t MAX_CALLTOKEN_DELAY = 10 [static]

Definition at line 730 of file chan_iax2.c.

int max_reg_expire [static]

Definition at line 174 of file chan_iax2.c.

int max_retries = 4 [static]

Definition at line 146 of file chan_iax2.c.

int maxauthreq = 3 [static]

Definition at line 145 of file chan_iax2.c.

int maxjitterbuffer = 1000 [static]

Definition at line 149 of file chan_iax2.c.

int maxjitterinterps = 10 [static]

Definition at line 151 of file chan_iax2.c.

int maxnontrunkcall = 1 [static]

Definition at line 1026 of file chan_iax2.c.

int maxtrunkcall = TRUNK_CALL_START [static]

Definition at line 1025 of file chan_iax2.c.

int min_reg_expire [static]

Definition at line 173 of file chan_iax2.c.

char mohinterpret[MAX_MUSICCLASS] [static]

Definition at line 244 of file chan_iax2.c.

char mohsuggest[MAX_MUSICCLASS] [static]

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

pthread_t netthreadid = AST_PTHREADT_NULL [static]

Definition at line 253 of file chan_iax2.c.

struct ast_netsock_list* outsock [static]

used if sourceaddress specified and bindaddr == INADDR_ANY

Definition at line 181 of file chan_iax2.c.

char* papp = "IAX2Provision" [static]

Definition at line 11191 of file chan_iax2.c.

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

struct ao2_container* peercnts [static]

Table containing peercnt objects for every ip address consuming a callno

Definition at line 750 of file chan_iax2.c.

struct ao2_container* peers [static]

Definition at line 744 of file chan_iax2.c.

int ping_time = 21 [static]

Definition at line 147 of file chan_iax2.c.

struct ast_codec_pref prefs [static]
char* psyn = "Provision a calling IAXy with a given template" [static]

Definition at line 11192 of file chan_iax2.c.

struct { ... } qos [static]

Referenced by peer_set_srcaddr(), and set_config().

int randomcalltokendata [static]

Definition at line 728 of file chan_iax2.c.

char regcontext[AST_MAX_CONTEXT] = "" [static]

Definition at line 143 of file chan_iax2.c.

int resyncthreshold = 1000 [static]

Definition at line 150 of file chan_iax2.c.

struct sched_context* sched [static]

Definition at line 227 of file chan_iax2.c.

Definition at line 256 of file chan_iax2.c.

ast_mutex_t sched_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]
pthread_t schedthreadid = AST_PTHREADT_NULL [static]

Definition at line 254 of file chan_iax2.c.

int srvlookup = 0 [static]

Definition at line 176 of file chan_iax2.c.

Referenced by build_peer().

const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static]

Definition at line 128 of file chan_iax2.c.

int test_losspct = 0 [static]

Definition at line 235 of file chan_iax2.c.

struct ast_timer* timer [static]
unsigned int tos

Definition at line 169 of file chan_iax2.c.

uint16_t total_nonval_callno_used = 0 [static]

Definition at line 767 of file chan_iax2.c.

int trunk_maxmtu [static]

Definition at line 136 of file chan_iax2.c.

int trunk_nmaxmtu [static]

Trunk MTU statistics

Definition at line 136 of file chan_iax2.c.

int trunk_timed [static]

Definition at line 136 of file chan_iax2.c.

int trunk_untimed [static]

Definition at line 136 of file chan_iax2.c.

int trunkfreq = 20 [static]

Definition at line 156 of file chan_iax2.c.

int trunkmaxsize = MAX_TRUNKDATA [static]

Definition at line 157 of file chan_iax2.c.

struct ao2_container* users [static]

Definition at line 747 of file chan_iax2.c.


Generated on 2 Mar 2010 for Asterisk - the Open Source PBX by  doxygen 1.6.1