Thu Apr 3 08:21:13 2014

Asterisk developer's documentation


chan_iax2.c File Reference

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

#include "asterisk.h"
#include <sys/mman.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <signal.h>
#include <strings.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/md5.h"
#include "asterisk/cdr.h"
#include "asterisk/crypto.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/localtime.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/event.h"
#include "asterisk/astobj2.h"
#include "asterisk/timing.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/test.h"
#include "asterisk/data.h"
#include "asterisk/netsock2.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "jitterbuf.h"

Go to the source code of this file.

Data Structures

struct  addr_range
struct  callno_entry
struct  chan_iax2_pvt
struct  create_addr_info
struct  dpreq_data
struct  iax2_context
struct  iax2_dpcache
struct  iax2_peer
struct  iax2_pkt_buf
struct  iax2_registry
struct  iax2_thread
struct  iax2_trunk_peer
struct  iax2_user
struct  iax_dual
struct  iax_firmware
struct  iax_rr
struct  parsed_dial_string
struct  signaling_queue_entry

Defines

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

Enumerations

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

Call token validation settings.

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

Functions

static void __attempt_transmit (const void *data)
static void __auth_reject (const void *nothing)
static void __auto_congest (const void *nothing)
static void __auto_hangup (const void *nothing)
static int __do_deliver (void *data)
static void __expire_registry (const void *data)
static int __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
static void __get_from_jb (const void *p)
static void __iax2_do_register_s (const void *data)
static void __iax2_poke_noanswer (const void *data)
static void __iax2_poke_peer_s (const void *data)
static int __iax2_show_peers (int fd, int *total, struct mansession *s, const int argc, const char *const argv[])
static int __schedule_action (void(*func)(const void *data), const void *data, const char *funcname)
static int __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final)
static void __send_lagrq (const void *data)
static void __send_ping (const void *data)
static int __unload_module (void)
static int acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen)
static int acf_iaxvar_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int acf_iaxvar_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
static int add_calltoken_ignore (const char *addr)
static void add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
static int addr_range_cmp_cb (void *obj, void *arg, int flags)
static int addr_range_delme_cb (void *obj, void *arg, int flags)
static int addr_range_hash_cb (const void *obj, const int flags)
static int addr_range_match_address_cb (void *obj, void *arg, int flags)
static int apply_context (struct iax2_context *con, const char *context)
static int ast_cli_netstats (struct mansession *s, int fd, int limit_fmt)
 AST_DATA_STRUCTURE (iax2_user, DATA_EXPORT_IAX2_USER)
 AST_DATA_STRUCTURE (iax2_peer, DATA_EXPORT_IAX2_PEER)
static struct ast_channelast_iax2_new (int callno, int state, format_t capability, const char *linkedid, unsigned int cachable)
 Create new call, interface with the PBX core.
static AST_LIST_HEAD_NOLOCK (iax_frame)
 a list of frames that may need to be retransmitted
static AST_LIST_HEAD_STATIC (dynamic_list, iax2_thread)
static AST_LIST_HEAD_STATIC (active_list, iax2_thread)
static AST_LIST_HEAD_STATIC (idle_list, iax2_thread)
static AST_LIST_HEAD_STATIC (dpcache, iax2_dpcache)
static AST_LIST_HEAD_STATIC (firmwares, iax_firmware)
static AST_LIST_HEAD_STATIC (registrations, iax2_registry)
static AST_LIST_HEAD_STATIC (tpeers, iax2_trunk_peer)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,"Inter Asterisk eXchange (Ver 2)",.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DRIVER,.nonoptreq="res_crypto",)
static int attempt_transmit (const void *data)
static int auth_fail (int callno, int failcode)
static int auth_reject (const void *data)
static int authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt)
static int authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
static int authenticate_request (int call_num)
static int authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies)
static int auto_congest (const void *data)
static int auto_hangup (const void *data)
static void build_callno_limits (struct ast_variable *v)
static struct iax2_contextbuild_context (const char *context)
static void build_ecx_key (const unsigned char *digest, struct chan_iax2_pvt *pvt)
static void build_encryption_keys (const unsigned char *digest, struct chan_iax2_pvt *pvt)
static struct iax2_peerbuild_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
 Create peer structure based on configuration.
static void build_rand_pad (unsigned char *buf, ssize_t len)
static struct iax2_userbuild_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
 Create in-memory user structure from configuration.
static int cache_get_callno_locked (const char *data)
static unsigned int calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset)
static unsigned int calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
static unsigned int calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
static int callno_hash (const void *obj, const int flags)
static int calltoken_required (struct sockaddr_in *sin, const char *name, int subclass)
static int check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies)
static int check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
static int check_srcaddr (struct sockaddr *sa, socklen_t salen)
 Check if address can be used as packet source.
static void cleanup_thread_list (void *head)
static int complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static char * complete_iax2_peers (const char *line, const char *word, int pos, int state, uint64_t flags)
static char * complete_iax2_unregister (const char *line, const char *word, int pos, int state)
static int complete_transfer (int callno, struct iax_ies *ies)
static unsigned char compress_subclass (format_t subclass)
static void construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
static int create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
static int create_callno_pools (void)
static int decode_frame (ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static int decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static void defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here)
 Queue the last read full frame for processing by a certain thread.
static void delete_users (void)
static void destroy_firmware (struct iax_firmware *cur)
static void dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
static void * dp_lookup_thread (void *data)
static void encmethods_to_str (int e, struct ast_str **buf)
static int encrypt_frame (ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
static int expire_registry (const void *data)
static struct iax2_dpcachefind_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
static int find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame)
static int find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame)
static struct iax2_threadfind_idle_thread (void)
static struct iax2_peerfind_peer (const char *name, int realtime)
static struct iax2_trunk_peerfind_tpeer (struct sockaddr_in *sin, int fd)
static struct iax2_userfind_user (const char *name)
static unsigned int fix_peerts (struct timeval *rxtrunktime, int callno, unsigned int ts)
static void free_context (struct iax2_context *con)
static void free_signaling_queue_entry (struct signaling_queue_entry *s)
static int function_iaxpeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int get_auth_methods (const char *value)
static int get_encrypt_methods (const char *s)
static int get_from_jb (const void *p)
static struct callno_entryget_unused_callno (int trunk, int validated)
static int handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct sockaddr_in *sin, int fd)
static char * handle_cli_iax2_provision (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_debug_jb (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_debug_trunk (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_mtu (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Set trunk MTU from CLI.
static char * handle_cli_iax2_show_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_callno_limits (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_firmware (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_netstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show one peer in detail.
static char * handle_cli_iax2_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_test_losspct (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void handle_deferred_full_frames (struct iax2_thread *thread)
 Handle any deferred full frames for this thread.
static int handle_error (void)
static int iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno)
 Acknowledgment received for OUR registration.
static int attribute_pure iax2_allow_new (int frametype, int subclass, int inbound)
static void iax2_ami_channelupdate (struct chan_iax2_pvt *pvt)
 Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers.
static int iax2_answer (struct ast_channel *c)
static int iax2_append_register (const char *hostname, const char *username, const char *secret, const char *porta)
static enum ast_bridge_result iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
static int iax2_call (struct ast_channel *c, char *dest, int timeout)
static int iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 part of the IAX2 dial plan switch interface
static unsigned int iax2_datetime (const char *tz)
static void iax2_destroy (int callno)
static void iax2_destroy_helper (struct chan_iax2_pvt *pvt)
static int iax2_devicestate (void *data)
 Part of the device state notification system ---.
static int iax2_digit_begin (struct ast_channel *c, char digit)
static int iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration)
static int iax2_do_register (struct iax2_registry *reg)
static int iax2_do_register_s (const void *data)
static void iax2_dprequest (struct iax2_dpcache *dp, int callno)
static void * iax2_dup_variable_datastore (void *)
static int iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Execute IAX2 dialplan switch.
static int iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 switch interface.
static int iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan)
static void iax2_frame_free (struct iax_frame *fr)
static void iax2_free_variable_datastore (void *)
static int iax2_getpeername (struct sockaddr_in sin, char *host, int len)
static int iax2_getpeertrunk (struct sockaddr_in sin)
static int iax2_hangup (struct ast_channel *c)
static int iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen)
static int iax2_key_rotate (const void *vpvt)
static void iax2_lock_owner (int callno)
static int iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 Switch interface.
static int iax2_poke_noanswer (const void *data)
static int iax2_poke_peer (struct iax2_peer *peer, int heldcall)
static int iax2_poke_peer_cb (void *obj, void *arg, int flags)
static int iax2_poke_peer_s (const void *data)
static int iax2_predestroy (int callno)
static void * iax2_process_thread (void *data)
static void iax2_process_thread_cleanup (void *data)
static int iax2_prov_app (struct ast_channel *chan, const char *data)
static int iax2_provision (struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
static int iax2_queryoption (struct ast_channel *c, int option, void *data, int *datalen)
static int iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen)
 Queue a control frame on the ast_channel owner.
static int iax2_queue_frame (int callno, struct ast_frame *f)
 Queue a frame to a call's owning asterisk channel.
static int iax2_queue_hangup (int callno)
 Queue a hangup frame on the ast_channel owner.
static struct ast_frameiax2_read (struct ast_channel *c)
static int iax2_register (const char *value, int lineno)
static struct ast_channeliax2_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static int iax2_sched_add (struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data)
static int iax2_sched_replace (int id, struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data)
static int iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
static int iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen)
static int iax2_sendimage (struct ast_channel *c, struct ast_frame *img)
static int iax2_sendtext (struct ast_channel *c, const char *text)
static int iax2_setoption (struct ast_channel *c, int option, void *data, int datalen)
static int iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly)
static int iax2_transfer (struct ast_channel *c, const char *dest)
static int iax2_transmit (struct iax_frame *fr)
static int iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now)
static int iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr)
static int iax2_vnak (int callno)
static int iax2_write (struct ast_channel *c, struct ast_frame *f)
static int iax_check_version (char *dev)
static void iax_debug_output (const char *data)
static void iax_error_output (const char *data)
static int iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
static void iax_outputframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
static int iax_park (struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context)
static void * iax_park_thread (void *stuff)
static struct iax_frameiaxfrdup2 (struct iax_frame *fr)
static void insert_idle_thread (struct iax2_thread *thread)
static void jb_debug_output (const char *fmt,...)
static void jb_error_output (const char *fmt,...)
static void jb_warning_output (const char *fmt,...)
static int load_module (void)
 Load IAX2 module, load configuraiton ---.
static int load_objects (void)
static void lock_both (unsigned short callno0, unsigned short callno1)
static void log_jitterstats (unsigned short callno)
static int make_trunk (unsigned short callno, int locked)
static int manager_iax2_show_netstats (struct mansession *s, const struct message *m)
static int manager_iax2_show_peer_list (struct mansession *s, const struct message *m)
 callback to display iax peers in manager format
static int manager_iax2_show_peers (struct mansession *s, const struct message *m)
 callback to display iax peers in manager
static int manager_iax2_show_registry (struct mansession *s, const struct message *m)
static int match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
static void memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
static void memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
static void merge_encryption (struct chan_iax2_pvt *p, unsigned int enc)
static void mwi_event_cb (const struct ast_event *event, void *userdata)
static void network_change_event_cb (const struct ast_event *, void *)
static int network_change_event_sched_cb (const void *data)
static void network_change_event_subscribe (void)
static void network_change_event_unsubscribe (void)
static void * network_thread (void *ignore)
static struct chan_iax2_pvtnew_iax (struct sockaddr_in *sin, const char *host)
static void parse_dial_string (char *data, struct parsed_dial_string *pds)
 Parses an IAX dial string into its component parts.
static int peer_cmp_cb (void *obj, void *arg, int flags)
static int peer_delme_cb (void *obj, void *arg, int flags)
static void peer_destructor (void *obj)
static int peer_hash_cb (const void *obj, const int flags)
static struct iax2_peerpeer_ref (struct iax2_peer *peer)
static int peer_set_sock_cb (void *obj, void *arg, int flags)
static int peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr)
 Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found.
static int peer_status (struct iax2_peer *peer, char *status, int statuslen)
 peer_status: Report Peer status in character string
static struct iax2_peerpeer_unref (struct iax2_peer *peer)
static int peercnt_add (struct sockaddr_in *sin)
static int peercnt_cmp_cb (void *obj, void *arg, int flags)
static int peercnt_hash_cb (const void *obj, const int flags)
static void peercnt_modify (unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
static void peercnt_remove (struct peercnt *peercnt)
static int peercnt_remove_by_addr (struct sockaddr_in *sin)
static int peercnt_remove_cb (const void *obj)
static int peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root)
static void poke_all_peers (void)
static int prune_addr_range_cb (void *obj, void *arg, int flags)
static void prune_peers (void)
static void prune_users (void)
static int pvt_cmp_cb (void *obj, void *arg, int flags)
static void pvt_destructor (void *obj)
static int pvt_hash_cb (const void *obj, const int flags)
static int queue_signalling (struct chan_iax2_pvt *pvt, struct ast_frame *f)
 All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.
static int raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
static struct iax2_peerrealtime_peer (const char *peername, struct sockaddr_in *sin)
static void realtime_update_peer (const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
static struct iax2_userrealtime_user (const char *username, struct sockaddr_in *sin)
static void reg_source_db (struct iax2_peer *p)
static void register_peer_exten (struct iax2_peer *peer, int onoff)
static int register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies)
 Verify inbound registration.
static int registry_authrequest (int callno)
static int registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin)
static char * regstate2str (int regstate)
static int reload (void)
static int reload_config (void)
static void reload_firmware (int unload)
static void remove_by_peercallno (struct chan_iax2_pvt *pvt)
static void remove_by_transfercallno (struct chan_iax2_pvt *pvt)
static int replace_callno (const void *obj)
static void requirecalltoken_mark_auto (const char *name, int subclass)
static void resend_with_token (int callno, struct iax_frame *f, const char *newtoken)
static void save_osptoken (struct iax_frame *fr, struct iax_ies *ies)
static void save_rr (struct iax_frame *fr, struct iax_ies *ies)
static void sched_delay_remove (struct sockaddr_in *sin, struct callno_entry *callno_entry)
static int schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
static int scheduled_destroy (const void *vid)
static int send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno, int sockfd, struct iax_ie_data *ied)
static int send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int)
static int send_lagrq (const void *data)
static int send_packet (struct iax_frame *f)
static int send_ping (const void *data)
static void send_signaling (struct chan_iax2_pvt *pvt)
 This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.
static int send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now)
static int set_config (const char *config_file, int reload)
 Load configuration.
static void set_config_destroy (void)
static void set_hangup_source_and_cause (int callno, unsigned char causecode)
static void set_peercnt_limit (struct peercnt *peercnt)
static int set_peercnt_limit_all_cb (void *obj, void *arg, int flags)
static void signal_condition (ast_mutex_t *lock, ast_cond_t *cond)
static int socket_process (struct iax2_thread *thread)
static int socket_process_meta (int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd, struct iax_frame *fr)
static int socket_read (int *id, int fd, short events, void *cbdata)
static void spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid)
static int start_network_thread (void)
static void stop_stuff (int callno)
static void store_by_peercallno (struct chan_iax2_pvt *pvt)
static void store_by_transfercallno (struct chan_iax2_pvt *pvt)
static int timing_read (int *id, int fd, short events, void *cbdata)
static int transfercallno_pvt_cmp_cb (void *obj, void *arg, int flags)
static int transfercallno_pvt_hash_cb (const void *obj, const int flags)
static int transmit_frame (void *data)
static int transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
static int try_firmware (char *s)
static int try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static format_t uncompress_subclass (unsigned char csub)
static void unlink_peer (struct iax2_peer *peer)
static int unload_module (void)
static void unlock_both (unsigned short callno0, unsigned short callno1)
static void unwrap_timestamp (struct iax_frame *fr)
static void update_jbsched (struct chan_iax2_pvt *pvt)
static int update_packet (struct iax_frame *f)
static int update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
static int user_cmp_cb (void *obj, void *arg, int flags)
static int user_delme_cb (void *obj, void *arg, int flags)
static void user_destructor (void *obj)
static int user_hash_cb (const void *obj, const int flags)
static struct iax2_useruser_ref (struct iax2_user *user)
static struct iax2_useruser_unref (struct iax2_user *user)
static int users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root)
static void vnak_retransmit (int callno, int last)
static int wait_for_peercallno (struct chan_iax2_pvt *pvt)

Variables

static char accountcode [AST_MAX_ACCOUNT_CODE]
static int adsi = 0
static int amaflags = 0
static int authdebug = 1
static int autokill = 0
static struct ao2_containercallno_pool
static const unsigned int CALLNO_POOL_BUCKETS = 2699
static struct ao2_containercallno_pool_trunk
static struct ast_cli_entry cli_iax2 []
static struct sockaddr_in debugaddr
static char default_parkinglot [AST_MAX_CONTEXT]
static int defaultsockfd = -1
static int delayreject = 0
static int global_max_trunk_mtu
static int global_rtautoclear = 120
static struct ast_flags64 globalflags = { 0 }
static format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH
static struct ast_data_entry iax2_data_providers []
static int iax2_encryption = 0
static int(* iax2_regfunk )(const char *username, int onoff) = NULL
static struct ast_switch iax2_switch
static struct ast_channel_tech iax2_tech
static struct ast_datastore_info iax2_variable_datastore_info
static struct ao2_containeriax_peercallno_pvts
 Another container of iax2_pvt structures.
static struct ao2_containeriax_transfercallno_pvts
 Another container of iax2_pvt structures.
static int iaxactivethreadcount = 0
static int iaxcompat = 0
static int iaxdebug = 0
static int iaxdefaultdpcache = 10 * 60
static int iaxdefaulttimeout = 5
static int iaxdynamicthreadcount = 0
static int iaxdynamicthreadnum = 0
static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT
static struct ast_custom_function iaxpeer_function
static struct chan_iax2_pvtiaxs [IAX_MAX_CALLS]
 an array of iax2 pvt structures
static ast_mutex_t iaxsl [ARRAY_LEN(iaxs)]
 chan_iax2_pvt structure locks
static int iaxthreadcount = DEFAULT_THREAD_COUNT
static int iaxtrunkdebug = 0
static struct ast_custom_function iaxvar_function
static struct io_contextio
static int jittertargetextra = 40
static int lagrq_time = 10
static char language [MAX_LANGUAGE] = ""
static int last_authmethod = 0
static int max_reg_expire
static int max_retries = 4
static int maxauthreq = 3
static int maxjitterbuffer = 1000
static int maxjitterinterps = 10
static int min_reg_expire
static char mohinterpret [MAX_MUSICCLASS]
static char mohsuggest [MAX_MUSICCLASS]
static struct ast_netsock_listnetsock
static pthread_t netthreadid = AST_PTHREADT_NULL
static int network_change_event_sched_id = -1
static struct ast_event_subnetwork_change_event_subscription
static struct ast_netsock_listoutsock
static char * papp = "IAX2Provision"
static struct ast_data_handler peers_data_provider
static int ping_time = 21
static struct ast_codec_pref prefs
struct {
   unsigned int   cos
   unsigned int   tos
qos
static char regcontext [AST_MAX_CONTEXT] = ""
static int resyncthreshold = 1000
static struct ast_sched_threadsched
static int srvlookup = 0
static const char tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)"
static int test_losspct = 0
static struct ast_timertimer
static int trunk_maxmtu
static int trunk_nmaxmtu
static int trunk_timed
static int trunk_untimed
static int trunkfreq = 20
static int trunkmaxsize = MAX_TRUNKDATA
static struct ast_data_handler users_data_provider

Detailed Description

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

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

Definition in file chan_iax2.c.


Define Documentation

#define ACN_FORMAT1   "%-20.25s %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 243 of file chan_iax2.c.

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

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

Referenced by handle_call_token().

#define CALLTOKEN_IE_FORMAT   "%u?%s"

Referenced by handle_call_token().

#define DATA_EXPORT_IAX2_PEER ( MEMBER   ) 

Definition at line 14624 of file chan_iax2.c.

#define DATA_EXPORT_IAX2_USER ( MEMBER   ) 

Definition at line 14701 of file chan_iax2.c.

#define DEBUG_SCHED_MULTITHREAD

Definition at line 235 of file chan_iax2.c.

#define DEBUG_SUPPORT

Definition at line 251 of file chan_iax2.c.

#define DEFAULT_CONTEXT   "default"
#define DEFAULT_DROP   3

Definition at line 249 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

Definition at line 345 of file chan_iax2.c.

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

#define DEFAULT_FREQ_OK   60 * 1000

Definition at line 344 of file chan_iax2.c.

Referenced by build_peer().

#define DEFAULT_MAX_THREAD_COUNT   100

Definition at line 246 of file chan_iax2.c.

#define DEFAULT_MAXMS   2000

Definition at line 343 of file chan_iax2.c.

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

#define DEFAULT_RETRY_TIME   1000

Definition at line 247 of file chan_iax2.c.

Referenced by __find_callno(), and complete_transfer().

#define DEFAULT_THREAD_COUNT   10

Definition at line 245 of file chan_iax2.c.

#define DEFAULT_TRUNKDATA   640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 624 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

#define DONT_RESCHEDULE   -2

Definition at line 367 of file chan_iax2.c.

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

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

Definition at line 256 of file chan_iax2.c.

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

Definition at line 545 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

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

Allow the FWDOWNL command?

Definition at line 433 of file chan_iax2.c.

Referenced by set_config(), and socket_process().

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

Already disconnected

Definition at line 416 of file chan_iax2.c.

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

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

Definition at line 348 of file chan_iax2.c.

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

#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF

Definition at line 322 of file chan_iax2.c.

Referenced by cache_get_callno_locked(), and set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH
Value:

Definition at line 334 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWFREE
Value:

Definition at line 339 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH

Definition at line 324 of file chan_iax2.c.

Referenced by set_config().

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

only consider requested format and ignore capabilities

Definition at line 423 of file chan_iax2.c.

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

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

Force old behaviour by turning off prefs

Definition at line 422 of file chan_iax2.c.

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

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

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

Definition at line 421 of file chan_iax2.c.

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

#define IAX_DEBUGDIGEST ( msg,
key   ) 

Definition at line 351 of file chan_iax2.c.

Referenced by iax2_key_rotate(), and socket_process().

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

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

Definition at line 432 of file chan_iax2.c.

Referenced by socket_process().

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

Needs to be deleted

Definition at line 408 of file chan_iax2.c.

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

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

Whether we should assume encrypted tx/rx

Definition at line 419 of file chan_iax2.c.

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

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

Forces call encryption, if encryption not possible hangup

Definition at line 437 of file chan_iax2.c.

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

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

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

Definition at line 427 of file chan_iax2.c.

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

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

CallerID has been specified

Definition at line 407 of file chan_iax2.c.

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

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

Allow immediate off-hook to extension s

Definition at line 434 of file chan_iax2.c.

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

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

Whether we have a key populated

Definition at line 420 of file chan_iax2.c.

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

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

Maximum outstanding AUTHREQ restriction is in place

Definition at line 431 of file chan_iax2.c.

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

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

This is a provisioning request

Definition at line 417 of file chan_iax2.c.

Referenced by iax2_provision(), and socket_process().

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

Whether or not we quelch audio

Definition at line 418 of file chan_iax2.c.

Referenced by iax2_write(), and socket_process().

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

Allow receiving of connected line updates

Definition at line 436 of file chan_iax2.c.

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

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

erase me on expire

Definition at line 426 of file chan_iax2.c.

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

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

let realtime stay till your reload

Definition at line 424 of file chan_iax2.c.

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

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

When using realtime, ignore registration expiration

Definition at line 428 of file chan_iax2.c.

Referenced by realtime_peer(), and set_config().

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

Save Systname on Realtime Updates

Definition at line 415 of file chan_iax2.c.

Referenced by realtime_update_peer(), and set_config().

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

Send a realtime update

Definition at line 425 of file chan_iax2.c.

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

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

Send ANI along with CallerID

Definition at line 414 of file chan_iax2.c.

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

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

Allow sending of connected line updates

Definition at line 435 of file chan_iax2.c.

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

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

Turn on and off caller id shrinking

Definition at line 438 of file chan_iax2.c.

Referenced by check_access(), and set_config().

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

Temporary (realtime)

Definition at line 409 of file chan_iax2.c.

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

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

When doing IAX2 transfers, transfer media only

Definition at line 430 of file chan_iax2.c.

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

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

Send trunk timestamps

Definition at line 429 of file chan_iax2.c.

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

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

Definition at line 632 of file chan_iax2.c.

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

#define MAX_JITTER_BUFFER   50

Definition at line 621 of file chan_iax2.c.

#define MAX_PEER_BUCKETS   563

Referenced by load_objects().

#define MAX_RETRY_TIME   10000

Definition at line 619 of file chan_iax2.c.

Referenced by __attempt_transmit(), and iax2_send().

#define MAX_TIMESTAMP_SKEW   160

maximum difference between actual and predicted ts for sending

Definition at line 626 of file chan_iax2.c.

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

#define MAX_TRUNK_MTU   1240

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

Definition at line 265 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_mtu(), and set_config().

#define MAX_TRUNKDATA   640 * 200

40ms, uncompressed linear * 200 channels

Definition at line 289 of file chan_iax2.c.

Referenced by set_config(), and set_config_destroy().

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

Referenced by load_module(), and load_objects().

#define MEMORY_SIZE   100

Definition at line 248 of file chan_iax2.c.

#define MIN_JITTER_BUFFER   10

Definition at line 622 of file chan_iax2.c.

#define MIN_RETRY_TIME   100

Definition at line 618 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME   60

Definition at line 253 of file chan_iax2.c.

Referenced by make_trunk(), and sched_delay_remove().

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

Definition at line 231 of file chan_iax2.c.

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

Definition at line 1098 of file chan_iax2.c.

#define TS_GAP_FOR_JB_RESYNC   5000

Definition at line 629 of file chan_iax2.c.

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

Definition at line 2048 of file chan_iax2.c.

Referenced by __find_callno(), and make_trunk().

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

Definition at line 2047 of file chan_iax2.c.

Referenced by iax2_destroy(), and make_trunk().


Enumeration Type Documentation

anonymous enum
Enumerator:
CACHE_FLAG_EXISTS 

Extension exists

CACHE_FLAG_NONEXISTENT 

Extension is nonexistent

CACHE_FLAG_CANEXIST 

Extension can exist

CACHE_FLAG_PENDING 

Waiting to hear back response

CACHE_FLAG_TIMEOUT 

Timed out

CACHE_FLAG_TRANSMITTED 

Request transmitted

CACHE_FLAG_UNKNOWN 

Timeout

CACHE_FLAG_MATCHMORE 

Matchmore

Definition at line 943 of file chan_iax2.c.

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

anonymous enum
Enumerator:
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 1974 of file chan_iax2.c.

01974      {
01975    /* do not allow a new call number, only search ones in use for match */
01976    NEW_PREVENT = 0,
01977    /* search for match first, then allow a new one to be allocated */
01978    NEW_ALLOW = 1,
01979    /* do not search for match, force a new call number */
01980    NEW_FORCE = 2,
01981    /* do not search for match, force a new call number.  Signifies call number
01982     * has been calltoken validated */
01983    NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01984 };

Call token validation settings.

Enumerator:
CALLTOKEN_DEFAULT 

Default calltoken required unless the ip is in the ignorelist.

CALLTOKEN_YES 

Require call token validation.

CALLTOKEN_AUTO 

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

CALLTOKEN_NO 

Do not require call token validation.

Definition at line 446 of file chan_iax2.c.

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

enum iax2_state
Enumerator:
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 395 of file chan_iax2.c.

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

Enumerator:
IAX_IOSTATE_IDLE 
IAX_IOSTATE_READY 
IAX_IOSTATE_PROCESSING 
IAX_IOSTATE_SCHEDREADY 

Definition at line 984 of file chan_iax2.c.

Enumerator:
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 991 of file chan_iax2.c.

00991                       {
00992    IAX_THREAD_TYPE_POOL,
00993    IAX_THREAD_TYPE_DYNAMIC,
00994 };

Enumerator:
REG_STATE_UNREGISTERED 
REG_STATE_REGSENT 
REG_STATE_AUTHSENT 
REG_STATE_REGISTERED 
REG_STATE_REJECTED 
REG_STATE_TIMEOUT 
REG_STATE_NOAUTH 

Definition at line 577 of file chan_iax2.c.

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

Definition at line 587 of file chan_iax2.c.


Function Documentation

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

Definition at line 3485 of file chan_iax2.c.

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

Referenced by attempt_transmit().

03486 {
03487    /* Attempt to transmit the frame to the remote peer...
03488       Called without iaxsl held. */
03489    struct iax_frame *f = (struct iax_frame *)data;
03490    int freeme = 0;
03491    int callno = f->callno;
03492 
03493    /* Make sure this call is still active */
03494    if (callno) 
03495       ast_mutex_lock(&iaxsl[callno]);
03496    if (callno && iaxs[callno]) {
03497       if (f->retries < 0) {
03498          /* Already ACK'd */
03499          freeme = 1;
03500       } else if (f->retries >= max_retries) {
03501          /* Too many attempts.  Record an error. */
03502          if (f->transfer) {
03503             /* Transfer timeout */
03504             send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03505          } else if (f->final) {
03506             iax2_destroy(callno);
03507          } else {
03508             if (iaxs[callno]->owner) {
03509                ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n",
03510                   ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),
03511                   iaxs[f->callno]->owner->name,
03512                   f->af.frametype,
03513                   f->af.subclass.integer,
03514                   f->ts,
03515                   f->oseqno);
03516             }
03517             iaxs[callno]->error = ETIMEDOUT;
03518             if (iaxs[callno]->owner) {
03519                struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03520                /* Hangup the fd */
03521                iax2_queue_frame(callno, &fr); /* XXX */
03522                /* Remember, owner could disappear */
03523                if (iaxs[callno] && iaxs[callno]->owner)
03524                   iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03525             } else {
03526                if (iaxs[callno]->reg) {
03527                   memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03528                   iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03529                   iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03530                }
03531                iax2_destroy(callno);
03532             }
03533          }
03534          freeme = 1;
03535       } else {
03536          /* Update it if it needs it */
03537          update_packet(f);
03538          /* Attempt transmission */
03539          send_packet(f);
03540          f->retries++;
03541          /* Try again later after 10 times as long */
03542          f->retrytime *= 10;
03543          if (f->retrytime > MAX_RETRY_TIME)
03544             f->retrytime = MAX_RETRY_TIME;
03545          /* Transfer messages max out at one second */
03546          if (f->transfer && (f->retrytime > 1000))
03547             f->retrytime = 1000;
03548          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03549       }
03550    } else {
03551       /* Make sure it gets freed */
03552       f->retries = -1;
03553       freeme = 1;
03554    }
03555 
03556    if (freeme) {
03557       /* Don't attempt delivery, just remove it from the queue */
03558       AST_LIST_REMOVE(&frame_queue[callno], f, list);
03559       ast_mutex_unlock(&iaxsl[callno]);
03560       f->retrans = -1; /* this is safe because this is the scheduled function */
03561       /* Free the IAX frame */
03562       iax2_frame_free(f);
03563    } else if (callno) {
03564       ast_mutex_unlock(&iaxsl[callno]);
03565    }
03566 }

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

Definition at line 9012 of file chan_iax2.c.

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

Referenced by auth_reject().

09013 {
09014    /* Called from IAX thread only, without iaxs lock */
09015    int callno = (int)(long)(nothing);
09016    struct iax_ie_data ied;
09017    ast_mutex_lock(&iaxsl[callno]);
09018    if (iaxs[callno]) {
09019       memset(&ied, 0, sizeof(ied));
09020       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
09021          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
09022          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
09023       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
09024          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
09025          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09026       }
09027       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
09028    }
09029    ast_mutex_unlock(&iaxsl[callno]);
09030 }

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

Definition at line 4675 of file chan_iax2.c.

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

Referenced by auto_congest().

04676 {
04677    int callno = PTR_TO_CALLNO(nothing);
04678    struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04679    ast_mutex_lock(&iaxsl[callno]);
04680    if (iaxs[callno]) {
04681       iaxs[callno]->initid = -1;
04682       iax2_queue_frame(callno, &f);
04683       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04684    }
04685    ast_mutex_unlock(&iaxsl[callno]);
04686 }

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

Definition at line 9061 of file chan_iax2.c.

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

Referenced by auto_hangup().

09062 {
09063    /* Called from IAX thread only, without iaxs lock */
09064    int callno = (int)(long)(nothing);
09065    struct iax_ie_data ied;
09066    ast_mutex_lock(&iaxsl[callno]);
09067    if (iaxs[callno]) {
09068       memset(&ied, 0, sizeof(ied));
09069       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09070       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09071       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09072    }
09073    ast_mutex_unlock(&iaxsl[callno]);
09074 }

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

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

Referenced by __get_from_jb(), and schedule_delivery().

03274 {
03275    /* Just deliver the packet by using queueing.  This is called by
03276      the IAX thread with the iaxsl lock held. */
03277    struct iax_frame *fr = data;
03278    fr->retrans = -1;
03279    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03280    if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03281       iax2_queue_frame(fr->callno, &fr->af);
03282    /* Free our iax frame */
03283    iax2_frame_free(fr);
03284    /* And don't run again */
03285    return 0;
03286 }

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

Definition at line 8637 of file chan_iax2.c.

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

Referenced by expire_registry().

08638 {
08639    struct iax2_peer *peer = (struct iax2_peer *) data;
08640 
08641    if (!peer)
08642       return;
08643    if (peer->expire == -1) {
08644       /* Removed already (possibly through CLI), ignore */
08645       return;
08646    }
08647 
08648    peer->expire = -1;
08649 
08650    ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08651    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08652       realtime_update_peer(peer->name, &peer->addr, 0);
08653    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08654    /* modify entry in peercnts table as _not_ registered */
08655    peercnt_modify((unsigned char) 0, 0, &peer->addr);
08656    /* Reset the address */
08657    memset(&peer->addr, 0, sizeof(peer->addr));
08658    /* Reset expiry value */
08659    peer->expiry = min_reg_expire;
08660    if (!ast_test_flag64(peer, IAX_TEMPONLY))
08661       ast_db_del("IAX/Registry", peer->name);
08662    register_peer_exten(peer, 0);
08663    ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
08664    if (iax2_regfunk)
08665       iax2_regfunk(peer->name, 0);
08666 
08667    if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08668       unlink_peer(peer);
08669 
08670    peer_unref(peer);
08671 }

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

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

Referenced by find_callno(), and find_callno_locked().

02780 {
02781    int res = 0;
02782    int x;
02783    /* this call is calltoken validated as long as it is either NEW_FORCE
02784     * or NEW_ALLOW_CALLTOKEN_VALIDATED */
02785    int validated = (new > NEW_ALLOW) ? 1 : 0;
02786    char host[80];
02787 
02788    if (new <= NEW_ALLOW) {
02789       if (callno) {
02790          struct chan_iax2_pvt *pvt;
02791          struct chan_iax2_pvt tmp_pvt = {
02792             .callno = dcallno,
02793             .peercallno = callno,
02794             .transfercallno = callno,
02795             /* hack!! */
02796             .frames_received = check_dcallno,
02797          };
02798 
02799          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02800          /* this works for finding normal call numbers not involving transfering */ 
02801          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02802             if (return_locked) {
02803                ast_mutex_lock(&iaxsl[pvt->callno]);
02804             }
02805             res = pvt->callno;
02806             ao2_ref(pvt, -1);
02807             pvt = NULL;
02808             return res;
02809          }
02810          /* this searches for transfer call numbers that might not get caught otherwise */
02811          memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02812          memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02813          if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02814             if (return_locked) {
02815                ast_mutex_lock(&iaxsl[pvt->callno]);
02816             }
02817             res = pvt->callno;
02818             ao2_ref(pvt, -1);
02819             pvt = NULL;
02820             return res;
02821          }
02822       }
02823          /* This will occur on the first response to a message that we initiated,
02824        * such as a PING. */
02825       if (dcallno) {
02826          ast_mutex_lock(&iaxsl[dcallno]);
02827       }
02828       if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02829          iaxs[dcallno]->peercallno = callno;
02830          res = dcallno;
02831          store_by_peercallno(iaxs[dcallno]);
02832          if (!res || !return_locked) {
02833             ast_mutex_unlock(&iaxsl[dcallno]);
02834          }
02835          return res;
02836       }
02837       if (dcallno) {
02838          ast_mutex_unlock(&iaxsl[dcallno]);
02839       }
02840 #ifdef IAX_OLD_FIND
02841       /* If we get here, we SHOULD NOT find a call structure for this
02842          callno; if we do, it means that there is a call structure that
02843          has a peer callno but did NOT get entered into the hash table,
02844          which is bad.
02845 
02846          If we find a call structure using this old, slow method, output a log
02847          message so we'll know about it. After a few months of leaving this in
02848          place, if we don't hear about people seeing these messages, we can
02849          remove this code for good.
02850       */
02851 
02852       for (x = 1; !res && x < maxnontrunkcall; x++) {
02853          ast_mutex_lock(&iaxsl[x]);
02854          if (iaxs[x]) {
02855             /* Look for an exact match */
02856             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02857                res = x;
02858             }
02859          }
02860          if (!res || !return_locked)
02861             ast_mutex_unlock(&iaxsl[x]);
02862       }
02863       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02864          ast_mutex_lock(&iaxsl[x]);
02865          if (iaxs[x]) {
02866             /* Look for an exact match */
02867             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02868                res = x;
02869             }
02870          }
02871          if (!res || !return_locked)
02872             ast_mutex_unlock(&iaxsl[x]);
02873       }
02874 #endif
02875    }
02876    if (!res && (new >= NEW_ALLOW)) {
02877       struct callno_entry *callno_entry;
02878       /* It may seem odd that we look through the peer list for a name for
02879        * this *incoming* call.  Well, it is weird.  However, users don't
02880        * have an IP address/port number that we can match against.  So,
02881        * this is just checking for a peer that has that IP/port and
02882        * assuming that we have a user of the same name.  This isn't always
02883        * correct, but it will be changed if needed after authentication. */
02884       if (!iax2_getpeername(*sin, host, sizeof(host)))
02885          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02886 
02887       if (peercnt_add(sin)) {
02888          /* This address has hit its callnumber limit.  When the limit
02889           * is reached, the connection is not added to the peercnts table.*/
02890          return 0;
02891       }
02892 
02893       if (!(callno_entry = get_unused_callno(0, validated))) {
02894          /* since we ran out of space, remove the peercnt
02895           * entry we added earlier */
02896          peercnt_remove_by_addr(sin);
02897          ast_log(LOG_WARNING, "No more space\n");
02898          return 0;
02899       }
02900       x = callno_entry->callno;
02901       ast_mutex_lock(&iaxsl[x]);
02902 
02903       iaxs[x] = new_iax(sin, host);
02904       update_max_nontrunk();
02905       if (iaxs[x]) {
02906          if (iaxdebug)
02907             ast_debug(1, "Creating new call structure %d\n", x);
02908          iaxs[x]->callno_entry = callno_entry;
02909          iaxs[x]->sockfd = sockfd;
02910          iaxs[x]->addr.sin_port = sin->sin_port;
02911          iaxs[x]->addr.sin_family = sin->sin_family;
02912          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02913          iaxs[x]->peercallno = callno;
02914          iaxs[x]->callno = x;
02915          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02916          iaxs[x]->expiry = min_reg_expire;
02917          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02918          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02919          iaxs[x]->amaflags = amaflags;
02920          ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
02921          ast_string_field_set(iaxs[x], accountcode, accountcode);
02922          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02923          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02924          ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02925 
02926          if (iaxs[x]->peercallno) {
02927             store_by_peercallno(iaxs[x]);
02928          }
02929       } else {
02930          ast_log(LOG_WARNING, "Out of resources\n");
02931          ast_mutex_unlock(&iaxsl[x]);
02932          replace_callno(callno_entry);
02933          return 0;
02934       }
02935       if (!return_locked)
02936          ast_mutex_unlock(&iaxsl[x]);
02937       res = x;
02938    }
02939    return res;
02940 }

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

Definition at line 4069 of file chan_iax2.c.

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

Referenced by get_from_jb().

04070 {
04071    int callno = PTR_TO_CALLNO(p);
04072    struct chan_iax2_pvt *pvt = NULL;
04073    struct iax_frame *fr;
04074    jb_frame frame;
04075    int ret;
04076    long ms;
04077    long next;
04078    struct timeval now = ast_tvnow();
04079    
04080    /* Make sure we have a valid private structure before going on */
04081    ast_mutex_lock(&iaxsl[callno]);
04082    pvt = iaxs[callno];
04083    if (!pvt) {
04084       /* No go! */
04085       ast_mutex_unlock(&iaxsl[callno]);
04086       return;
04087    }
04088 
04089    pvt->jbid = -1;
04090    
04091    /* round up a millisecond since ast_sched_runq does; */
04092    /* prevents us from spinning while waiting for our now */
04093    /* to catch up with runq's now */
04094    now.tv_usec += 1000;
04095    
04096    ms = ast_tvdiff_ms(now, pvt->rxcore);
04097    
04098    if(ms >= (next = jb_next(pvt->jb))) {
04099       ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
04100       switch(ret) {
04101       case JB_OK:
04102          fr = frame.data;
04103          __do_deliver(fr);
04104          /* __do_deliver() can cause the call to disappear */
04105          pvt = iaxs[callno];
04106          break;
04107       case JB_INTERP:
04108       {
04109          struct ast_frame af = { 0, };
04110          
04111          /* create an interpolation frame */
04112          af.frametype = AST_FRAME_VOICE;
04113          af.subclass.codec = pvt->voiceformat;
04114          af.samples  = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
04115          af.src  = "IAX2 JB interpolation";
04116          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
04117          af.offset = AST_FRIENDLY_OFFSET;
04118          
04119          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
04120           * which we'd need to malloc, and then it would free it.  That seems like a drag */
04121          if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
04122             iax2_queue_frame(callno, &af);
04123             /* iax2_queue_frame() could cause the call to disappear */
04124             pvt = iaxs[callno];
04125          }
04126       }
04127          break;
04128       case JB_DROP:
04129          iax2_frame_free(frame.data);
04130          break;
04131       case JB_NOFRAME:
04132       case JB_EMPTY:
04133          /* do nothing */
04134          break;
04135       default:
04136          /* shouldn't happen */
04137          break;
04138       }
04139    }
04140    if (pvt)
04141       update_jbsched(pvt);
04142    ast_mutex_unlock(&iaxsl[callno]);
04143 }

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

Definition at line 8308 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

08309 {
08310    struct iax2_registry *reg = (struct iax2_registry *)data;
08311    reg->expire = -1;
08312    iax2_do_register(reg);
08313 }

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

Definition at line 12060 of file chan_iax2.c.

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

Referenced by iax2_poke_noanswer().

12061 {
12062    struct iax2_peer *peer = (struct iax2_peer *)data;
12063    int callno;
12064 
12065    if (peer->lastms > -1) {
12066       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
12067       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
12068       ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
12069    }
12070    if ((callno = peer->callno) > 0) {
12071       ast_mutex_lock(&iaxsl[callno]);
12072       iax2_destroy(callno);
12073       ast_mutex_unlock(&iaxsl[callno]);
12074    }
12075    peer->callno = 0;
12076    peer->lastms = -1;
12077    /* Try again quickly */
12078    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
12079    if (peer->pokeexpire == -1)
12080       peer_unref(peer);
12081 }

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

Definition at line 9121 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

09122 {
09123    struct iax2_peer *peer = (struct iax2_peer *)data;
09124    iax2_poke_peer(peer, 0);
09125    peer_unref(peer);
09126 }

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

Definition at line 6672 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().

06673 {
06674    regex_t regexbuf;
06675    int havepattern = 0;
06676    int total_peers = 0;
06677    int online_peers = 0;
06678    int offline_peers = 0;
06679    int unmonitored_peers = 0;
06680    struct ao2_iterator i;
06681 
06682 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s\n"
06683 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s\n"
06684 
06685    struct iax2_peer *peer = NULL;
06686    char name[256];
06687    struct ast_str *encmethods = ast_str_alloca(256);
06688    int registeredonly=0;
06689    char idtext[256] = "";
06690    switch (argc) {
06691    case 6:
06692       if (!strcasecmp(argv[3], "registered"))
06693          registeredonly = 1;
06694       else
06695          return RESULT_SHOWUSAGE;
06696       if (!strcasecmp(argv[4], "like")) {
06697          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06698             return RESULT_SHOWUSAGE;
06699          havepattern = 1;
06700       } else
06701          return RESULT_SHOWUSAGE;
06702       break;
06703    case 5:
06704       if (!strcasecmp(argv[3], "like")) {
06705          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06706             return RESULT_SHOWUSAGE;
06707          havepattern = 1;
06708       } else
06709          return RESULT_SHOWUSAGE;
06710       break;
06711    case 4:
06712       if (!strcasecmp(argv[3], "registered"))
06713          registeredonly = 1;
06714       else
06715          return RESULT_SHOWUSAGE;
06716       break;
06717    case 3:
06718       break;
06719    default:
06720       return RESULT_SHOWUSAGE;
06721    }
06722 
06723 
06724    if (!s)
06725       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status");
06726 
06727    i = ao2_iterator_init(peers, 0);
06728    for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
06729       char nm[20];
06730       char status[20];
06731       int retstatus;
06732       struct sockaddr_in peer_addr;
06733 
06734       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06735 
06736       if (registeredonly && !peer_addr.sin_addr.s_addr) {
06737          continue;
06738       }
06739       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0)) {
06740          continue;
06741       }
06742 
06743       if (!ast_strlen_zero(peer->username))
06744          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06745       else
06746          ast_copy_string(name, peer->name, sizeof(name));
06747 
06748       encmethods_to_str(peer->encmethods, &encmethods);
06749       retstatus = peer_status(peer, status, sizeof(status));
06750       if (retstatus > 0)
06751          online_peers++;
06752       else if (!retstatus)
06753          offline_peers++;
06754       else
06755          unmonitored_peers++;
06756 
06757       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06758 
06759       if (s) {
06760          astman_append(s,
06761             "Event: PeerEntry\r\n%s"
06762             "Channeltype: IAX2\r\n"
06763             "ObjectName: %s\r\n"
06764             "ChanObjectType: peer\r\n"
06765             "IPaddress: %s\r\n"
06766             "IPport: %d\r\n"
06767             "Dynamic: %s\r\n"
06768             "Trunk: %s\r\n"
06769             "Encryption: %s\r\n"
06770             "Status: %s\r\n\r\n",
06771             idtext,
06772             name,
06773             ast_sockaddr_stringify_addr(&peer->addr),
06774             ast_sockaddr_port(&peer->addr),
06775             ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06776             ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06777             peer->encmethods ? ast_str_buffer(encmethods) : "no",
06778             status);
06779       } else {
06780          ast_cli(fd, FORMAT, name,
06781             ast_sockaddr_stringify_addr(&peer->addr),
06782             ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06783             nm,
06784             ast_sockaddr_port(&peer->addr),
06785             ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : "   ",
06786             peer->encmethods ? "(E)" : "   ",
06787             status);
06788       }
06789       total_peers++;
06790    }
06791    ao2_iterator_destroy(&i);
06792 
06793    if (!s)
06794       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06795          total_peers, online_peers, offline_peers, unmonitored_peers);
06796 
06797    if (havepattern)
06798       regfree(&regexbuf);
06799 
06800    if (total)
06801       *total = total_peers;
06802 
06803    return RESULT_SUCCESS;
06804 #undef FORMAT
06805 #undef FORMAT2
06806 }

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

Definition at line 1461 of file chan_iax2.c.

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

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

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

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

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

07501 {
07502    struct ast_frame f = { 0, };
07503    int res = 0;
07504 
07505    f.frametype = type;
07506    f.subclass.integer = command;
07507    f.datalen = datalen;
07508    f.src = __FUNCTION__;
07509    f.data.ptr = (void *) data;
07510 
07511    if ((res = queue_signalling(i, &f)) <= 0) {
07512       return res;
07513    }
07514 
07515    return iax2_send(i, &f, ts, seqno, now, transfer, final);
07516 }

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

Definition at line 1572 of file chan_iax2.c.

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

Referenced by send_lagrq().

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

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

Definition at line 1505 of file chan_iax2.c.

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

Referenced by send_ping().

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

static int __unload_module ( void   )  [static]

Definition at line 14428 of file chan_iax2.c.

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

Referenced by load_module(), and unload_module().

14429 {
14430    struct ast_context *con;
14431    int x;
14432 
14433    network_change_event_unsubscribe();
14434 
14435    ast_manager_unregister("IAXpeers");
14436    ast_manager_unregister("IAXpeerlist");
14437    ast_manager_unregister("IAXnetstats");
14438    ast_manager_unregister("IAXregistry");
14439    ast_unregister_application(papp);
14440    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14441    ast_unregister_switch(&iax2_switch);
14442    ast_channel_unregister(&iax2_tech);
14443 
14444    if (netthreadid != AST_PTHREADT_NULL) {
14445       pthread_cancel(netthreadid);
14446       pthread_kill(netthreadid, SIGURG);
14447       pthread_join(netthreadid, NULL);
14448    }
14449 
14450    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14451       if (iaxs[x]) {
14452          iax2_destroy(x);
14453       }
14454    }
14455 
14456    /* Call for all threads to halt */
14457    cleanup_thread_list(&active_list);
14458    cleanup_thread_list(&dynamic_list);
14459    cleanup_thread_list(&idle_list);
14460 
14461    ast_netsock_release(netsock);
14462    ast_netsock_release(outsock);
14463    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14464       if (iaxs[x]) {
14465          iax2_destroy(x);
14466       }
14467    }
14468    ast_manager_unregister( "IAXpeers" );
14469    ast_manager_unregister( "IAXpeerlist" );
14470    ast_manager_unregister( "IAXnetstats" );
14471    ast_manager_unregister( "IAXregistry" );
14472    ast_unregister_application(papp);
14473 #ifdef TEST_FRAMEWORK
14474    AST_TEST_UNREGISTER(test_iax2_peers_get);
14475    AST_TEST_UNREGISTER(test_iax2_users_get);
14476 #endif
14477    ast_data_unregister(NULL);
14478    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14479    ast_unregister_switch(&iax2_switch);
14480    ast_channel_unregister(&iax2_tech);
14481    delete_users();
14482    iax_provision_unload();
14483    reload_firmware(1);
14484 
14485    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14486       ast_mutex_destroy(&iaxsl[x]);
14487    }
14488 
14489    ao2_ref(peers, -1);
14490    ao2_ref(users, -1);
14491    ao2_ref(iax_peercallno_pvts, -1);
14492    ao2_ref(iax_transfercallno_pvts, -1);
14493    ao2_ref(peercnts, -1);
14494    ao2_ref(callno_limits, -1);
14495    ao2_ref(calltoken_ignores, -1);
14496    ao2_ref(callno_pool, -1);
14497    ao2_ref(callno_pool_trunk, -1);
14498    if (timer) {
14499       ast_timer_close(timer);
14500       timer = NULL;
14501    }
14502    transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14503    sched = ast_sched_thread_destroy(sched);
14504 
14505    con = ast_context_find(regcontext);
14506    if (con)
14507       ast_context_destroy(con, "IAX2");
14508    ast_unload_realtime("iaxpeers");
14509    return 0;
14510 }

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

Definition at line 14068 of file chan_iax2.c.

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

14069 {
14070    struct chan_iax2_pvt *pvt;
14071    unsigned int callno;
14072    int res = 0;
14073 
14074    if (!chan || chan->tech != &iax2_tech) {
14075       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
14076       return -1;
14077    }
14078 
14079    callno = PTR_TO_CALLNO(chan->tech_pvt);
14080    ast_mutex_lock(&iaxsl[callno]);
14081    if (!(pvt = iaxs[callno])) {
14082       ast_mutex_unlock(&iaxsl[callno]);
14083       return -1;
14084    }
14085 
14086    if (!strcasecmp(args, "osptoken")) {
14087       ast_copy_string(buf, pvt->osptoken, buflen);
14088    } else if (!strcasecmp(args, "peerip")) {
14089       ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
14090    } else if (!strcasecmp(args, "peername")) {
14091       ast_copy_string(buf, pvt->username, buflen);
14092    } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
14093       snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
14094    } else {
14095       res = -1;
14096    }
14097 
14098    ast_mutex_unlock(&iaxsl[callno]);
14099 
14100    return res;
14101 }

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

Definition at line 9843 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, iax2_variable_datastore_info, ast_var_t::name, ast_var_t::value, and var.

09844 {
09845    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09846    AST_LIST_HEAD(, ast_var_t) *varlist;
09847    struct ast_var_t *var;
09848 
09849    if (!variablestore) {
09850       *buf = '\0';
09851       return 0;
09852    }
09853    varlist = variablestore->data;
09854 
09855    AST_LIST_LOCK(varlist);
09856    AST_LIST_TRAVERSE(varlist, var, entries) {
09857       if (strcmp(var->name, data) == 0) {
09858          ast_copy_string(buf, var->value, len);
09859          break;
09860       }
09861    }
09862    AST_LIST_UNLOCK(varlist);
09863    return 0;
09864 }

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

Definition at line 9866 of file chan_iax2.c.

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

09867 {
09868    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09869    AST_LIST_HEAD(, ast_var_t) *varlist;
09870    struct ast_var_t *var;
09871 
09872    if (!variablestore) {
09873       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09874       if (!variablestore) {
09875          ast_log(LOG_ERROR, "Memory allocation error\n");
09876          return -1;
09877       }
09878       varlist = ast_calloc(1, sizeof(*varlist));
09879       if (!varlist) {
09880          ast_datastore_free(variablestore);
09881          ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09882          return -1;
09883       }
09884 
09885       AST_LIST_HEAD_INIT(varlist);
09886       variablestore->data = varlist;
09887       variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09888       ast_channel_datastore_add(chan, variablestore);
09889    } else
09890       varlist = variablestore->data;
09891 
09892    AST_LIST_LOCK(varlist);
09893    AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09894       if (strcmp(var->name, data) == 0) {
09895          AST_LIST_REMOVE_CURRENT(entries);
09896          ast_var_delete(var);
09897          break;
09898       }
09899    }
09900    AST_LIST_TRAVERSE_SAFE_END;
09901    var = ast_var_assign(data, value);
09902    if (var)
09903       AST_LIST_INSERT_TAIL(varlist, var, entries);
09904    else
09905       ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09906    AST_LIST_UNLOCK(varlist);
09907    return 0;
09908 }

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

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

02515 {
02516    struct addr_range tmp;
02517    struct addr_range *addr_range = NULL;
02518    struct ast_ha *ha = NULL;
02519    int error = 0;
02520 
02521    if (ast_strlen_zero(addr)) {
02522       ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02523       return -1;
02524    }
02525 
02526    ha = ast_append_ha("permit", addr, NULL, &error);
02527 
02528    /* check for valid config information */
02529    if (error) {
02530       ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02531       return -1;
02532    }
02533 
02534    ast_copy_ha(ha, &tmp.ha);
02535    /* find or create the addr_range */
02536    if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02537       ao2_lock(addr_range);
02538       addr_range->delme = 0;
02539       ao2_unlock(addr_range);
02540    } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02541       /* copy over config data into addr_range object */
02542       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
02543       ao2_link(calltoken_ignores, addr_range);
02544    } else {
02545       ast_free_ha(ha);
02546       return -1;
02547    }
02548 
02549    ast_free_ha(ha);
02550    ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02551 
02552    return 0;
02553 }

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

Definition at line 4751 of file chan_iax2.c.

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

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

04752 {
04753    /* first make sure their are two empty bytes left in ied->buf */
04754    if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04755       ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;  /* type */
04756       ied->buf[ied->pos++] = 0;   /* data size,  ZERO in this case */
04757       pvt->calltoken_ie_len = 2;
04758    }
04759 }

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

Definition at line 2165 of file chan_iax2.c.

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

Referenced by load_objects().

02166 {
02167    struct addr_range *lim1 = obj, *lim2 = arg;
02168    return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
02169          !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
02170          CMP_MATCH | CMP_STOP : 0;
02171 }

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

Definition at line 2150 of file chan_iax2.c.

References addr_range::delme.

Referenced by set_config_destroy().

02151 {
02152    struct addr_range *lim = obj;
02153    lim->delme = 1;
02154    return 0;
02155 }

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

Definition at line 2157 of file chan_iax2.c.

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

Referenced by load_objects().

02158 {
02159    const struct addr_range *lim = obj;
02160    struct sockaddr_in sin;
02161    ast_sockaddr_to_sin(&lim->ha.addr, &sin);
02162    return abs((int) sin.sin_addr.s_addr);
02163 }

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

Definition at line 2185 of file chan_iax2.c.

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

Referenced by calltoken_required(), and set_peercnt_limit().

02186 {
02187    struct addr_range *addr_range = obj;
02188    struct sockaddr_in *sin = arg;
02189    struct sockaddr_in ha_netmask_sin;
02190    struct sockaddr_in ha_addr_sin;
02191 
02192    ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin);
02193    ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin);
02194 
02195    if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) {
02196       return CMP_MATCH | CMP_STOP;
02197    }
02198    return 0;
02199 }

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

Definition at line 7557 of file chan_iax2.c.

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

Referenced by check_access().

07558 {
07559    while(con) {
07560       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07561          return -1;
07562       con = con->next;
07563    }
07564    return 0;
07565 }

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

Definition at line 7258 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_show_netstats(), and manager_iax2_show_netstats().

07259 {
07260    int x;
07261    int numchans = 0;
07262    char first_message[10] = { 0, };
07263    char last_message[10] = { 0, };
07264 #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"
07265 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07266    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07267       ast_mutex_lock(&iaxsl[x]);
07268       if (iaxs[x]) {
07269          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07270          jb_info jbinfo;
07271          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07272          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07273 
07274          if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07275             jb_getinfo(iaxs[x]->jb, &jbinfo);
07276             localjitter = jbinfo.jitter;
07277             localdelay = jbinfo.current - jbinfo.min;
07278             locallost = jbinfo.frames_lost;
07279             locallosspct = jbinfo.losspct/1000;
07280             localdropped = jbinfo.frames_dropped;
07281             localooo = jbinfo.frames_ooo;
07282          } else {
07283             localjitter = -1;
07284             localdelay = 0;
07285             locallost = -1;
07286             locallosspct = -1;
07287             localdropped = 0;
07288             localooo = -1;
07289          }
07290          if (s)
07291             astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07292                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07293                iaxs[x]->pingtime,
07294                localjitter,
07295                localdelay,
07296                locallost,
07297                locallosspct,
07298                localdropped,
07299                localooo,
07300                iaxs[x]->frames_received/1000,
07301                iaxs[x]->remote_rr.jitter,
07302                iaxs[x]->remote_rr.delay,
07303                iaxs[x]->remote_rr.losscnt,
07304                iaxs[x]->remote_rr.losspct,
07305                iaxs[x]->remote_rr.dropped,
07306                iaxs[x]->remote_rr.ooo,
07307                iaxs[x]->remote_rr.packets/1000,
07308                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07309                first_message,
07310                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07311                last_message);
07312          else
07313             ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07314                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07315                iaxs[x]->pingtime,
07316                localjitter,
07317                localdelay,
07318                locallost,
07319                locallosspct,
07320                localdropped,
07321                localooo,
07322                iaxs[x]->frames_received/1000,
07323                iaxs[x]->remote_rr.jitter,
07324                iaxs[x]->remote_rr.delay,
07325                iaxs[x]->remote_rr.losscnt,
07326                iaxs[x]->remote_rr.losspct,
07327                iaxs[x]->remote_rr.dropped,
07328                iaxs[x]->remote_rr.ooo,
07329                iaxs[x]->remote_rr.packets/1000,
07330                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07331                first_message,
07332                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07333                last_message);
07334          numchans++;
07335       }
07336       ast_mutex_unlock(&iaxsl[x]);
07337    }
07338 
07339    return numchans;
07340 }

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

Create new call, interface with the PBX core.

Definition at line 5750 of file chan_iax2.c.

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

Referenced by iax2_request(), and socket_process().

05751 {
05752    struct ast_channel *tmp;
05753    struct chan_iax2_pvt *i;
05754    struct ast_variable *v = NULL;
05755 
05756    if (!(i = iaxs[callno])) {
05757       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05758       return NULL;
05759    }
05760 
05761    /* Don't hold call lock */
05762    ast_mutex_unlock(&iaxsl[callno]);
05763    tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
05764    ast_mutex_lock(&iaxsl[callno]);
05765    if (i != iaxs[callno]) {
05766       if (tmp) {
05767          /* unlock and relock iaxsl[callno] to preserve locking order */
05768          ast_mutex_unlock(&iaxsl[callno]);
05769          tmp = ast_channel_release(tmp);
05770          ast_mutex_lock(&iaxsl[callno]);
05771       }
05772       return NULL;
05773    }
05774    iax2_ami_channelupdate(i);
05775    if (!tmp)
05776       return NULL;
05777    tmp->tech = &iax2_tech;
05778    /* We can support any format by default, until we get restricted */
05779    tmp->nativeformats = capability;
05780    tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05781    tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05782    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05783 
05784    if (!ast_strlen_zero(i->parkinglot))
05785       ast_string_field_set(tmp, parkinglot, i->parkinglot);
05786    /* Don't use ast_set_callerid() here because it will
05787     * generate a NewCallerID event before the NewChannel event */
05788    if (!ast_strlen_zero(i->ani)) {
05789       tmp->caller.ani.number.valid = 1;
05790       tmp->caller.ani.number.str = ast_strdup(i->ani);
05791    } else if (!ast_strlen_zero(i->cid_num)) {
05792       tmp->caller.ani.number.valid = 1;
05793       tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05794    }
05795    tmp->dialed.number.str = ast_strdup(i->dnid);
05796    if (!ast_strlen_zero(i->rdnis)) {
05797       tmp->redirecting.from.number.valid = 1;
05798       tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05799    }
05800    tmp->caller.id.name.presentation = i->calling_pres;
05801    tmp->caller.id.number.presentation = i->calling_pres;
05802    tmp->caller.id.number.plan = i->calling_ton;
05803    tmp->dialed.transit_network_select = i->calling_tns;
05804    if (!ast_strlen_zero(i->language))
05805       ast_string_field_set(tmp, language, i->language);
05806    if (!ast_strlen_zero(i->accountcode))
05807       ast_string_field_set(tmp, accountcode, i->accountcode);
05808    if (i->amaflags)
05809       tmp->amaflags = i->amaflags;
05810    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05811    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05812    if (i->adsi)
05813       tmp->adsicpe = i->peeradsicpe;
05814    else
05815       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05816    i->owner = tmp;
05817    i->capability = capability;
05818 
05819    if (!cachable) {
05820       tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
05821    }
05822 
05823    /* Set inherited variables */
05824    if (i->vars) {
05825       for (v = i->vars ; v ; v = v->next)
05826          pbx_builtin_setvar_helper(tmp, v->name, v->value);
05827    }
05828    if (i->iaxvars) {
05829       struct ast_datastore *variablestore;
05830       struct ast_variable *var, *prev = NULL;
05831       AST_LIST_HEAD(, ast_var_t) *varlist;
05832       ast_debug(1, "Loading up the channel with IAXVARs\n");
05833       varlist = ast_calloc(1, sizeof(*varlist));
05834       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05835       if (variablestore && varlist) {
05836          variablestore->data = varlist;
05837          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05838          AST_LIST_HEAD_INIT(varlist);
05839          for (var = i->iaxvars; var; var = var->next) {
05840             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05841             if (prev)
05842                ast_free(prev);
05843             prev = var;
05844             if (!newvar) {
05845                /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
05846                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05847             } else {
05848                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05849             }
05850          }
05851          if (prev)
05852             ast_free(prev);
05853          i->iaxvars = NULL;
05854          ast_channel_datastore_add(i->owner, variablestore);
05855       } else {
05856          if (variablestore) {
05857             ast_datastore_free(variablestore);
05858          }
05859          if (varlist) {
05860             ast_free(varlist);
05861          }
05862       }
05863    }
05864 
05865    if (state != AST_STATE_DOWN) {
05866       if (ast_pbx_start(tmp)) {
05867          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05868          ast_hangup(tmp);
05869          i->owner = NULL;
05870          return NULL;
05871       }
05872    }
05873 
05874    ast_module_ref(ast_module_info->self);
05875    return tmp;
05876 }

static AST_LIST_HEAD_NOLOCK ( iax_frame   )  [static]

a list of frames that may need to be retransmitted

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

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

ip address consuming call numbers

Number of call numbers currently used by this ip address

Max call numbers allowed for this ip address

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

Definition at line 865 of file chan_iax2.c.

References iax2_trunk_peer::addr.

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

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

Definition at line 3568 of file chan_iax2.c.

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and transmit_frame().

03569 {
03570 #ifdef SCHED_MULTITHREADED
03571    if (schedule_action(__attempt_transmit, data))
03572 #endif      
03573       __attempt_transmit(data);
03574    return 0;
03575 }

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

Definition at line 9046 of file chan_iax2.c.

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

Referenced by socket_process().

09047 {
09048    /* Schedule sending the authentication failure in one second, to prevent
09049       guessing */
09050    if (iaxs[callno]) {
09051       iaxs[callno]->authfail = failcode;
09052       if (delayreject) {
09053          iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 
09054             sched, 1000, auth_reject, (void *)(long)callno);
09055       } else
09056          auth_reject((void *)(long)callno);
09057    }
09058    return 0;
09059 }

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

Definition at line 9032 of file chan_iax2.c.

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

Referenced by auth_fail().

09033 {
09034    int callno = (int)(long)(data);
09035    ast_mutex_lock(&iaxsl[callno]);
09036    if (iaxs[callno])
09037       iaxs[callno]->authid = -1;
09038    ast_mutex_unlock(&iaxsl[callno]);
09039 #ifdef SCHED_MULTITHREADED
09040    if (schedule_action(__auth_reject, data))
09041 #endif      
09042       __auth_reject(data);
09043    return 0;
09044 }

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

08131 {
08132    int res = -1;
08133    int x;
08134    if (!ast_strlen_zero(keyn)) {
08135       if (!(authmethods & IAX_AUTH_RSA)) {
08136          if (ast_strlen_zero(secret)) 
08137             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));
08138       } else if (ast_strlen_zero(challenge)) {
08139          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08140       } else {
08141          char sig[256];
08142          struct ast_key *key;
08143          key = ast_key_get(keyn, AST_KEY_PRIVATE);
08144          if (!key) {
08145             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08146          } else {
08147             if (ast_sign(key, (char*)challenge, sig)) {
08148                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08149                res = -1;
08150             } else {
08151                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08152                res = 0;
08153             }
08154          }
08155       }
08156    } 
08157    /* Fall back */
08158    if (res && !ast_strlen_zero(secret)) {
08159       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08160          struct MD5Context md5;
08161          unsigned char digest[16];
08162          char digres[128];
08163          MD5Init(&md5);
08164          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08165          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08166          MD5Final(digest, &md5);
08167          /* If they support md5, authenticate with it.  */
08168          for (x=0;x<16;x++)
08169             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
08170          if (pvt) {
08171             build_encryption_keys(digest, pvt);
08172          }
08173          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08174          res = 0;
08175       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08176          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08177          res = 0;
08178       } else
08179          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08180    }
08181    return res;
08182 }

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

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

Referenced by socket_process().

08189 {
08190    struct iax2_peer *peer = NULL;
08191    /* Start pessimistic */
08192    int res = -1;
08193    int authmethods = 0;
08194    struct iax_ie_data ied;
08195    uint16_t callno = p->callno;
08196 
08197    memset(&ied, 0, sizeof(ied));
08198    
08199    if (ies->username)
08200       ast_string_field_set(p, username, ies->username);
08201    if (ies->challenge)
08202       ast_string_field_set(p, challenge, ies->challenge);
08203    if (ies->authmethods)
08204       authmethods = ies->authmethods;
08205    if (authmethods & IAX_AUTH_MD5)
08206       merge_encryption(p, ies->encmethods);
08207    else
08208       p->encmethods = 0;
08209 
08210    /* Check for override RSA authentication first */
08211    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08212       /* Normal password authentication */
08213       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08214    } else {
08215       struct ao2_iterator i = ao2_iterator_init(peers, 0);
08216       while ((peer = ao2_iterator_next(&i))) {
08217          struct sockaddr_in peer_addr;
08218 
08219          ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08220 
08221          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
08222              /* No peer specified at our end, or this is the peer */
08223              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08224              /* No username specified in peer rule, or this is the right username */
08225              && (!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)))
08226              /* No specified host, or this is our host */
08227             ) {
08228             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08229             if (!res) {
08230                peer_unref(peer);
08231                break;
08232             }
08233          }
08234          peer_unref(peer);
08235       }
08236       ao2_iterator_destroy(&i);
08237       if (!peer) {
08238          /* We checked our list and didn't find one.  It's unlikely, but possible, 
08239             that we're trying to authenticate *to* a realtime peer */
08240          const char *peer_name = ast_strdupa(p->peer);
08241          ast_mutex_unlock(&iaxsl[callno]);
08242          if ((peer = realtime_peer(peer_name, NULL))) {
08243             ast_mutex_lock(&iaxsl[callno]);
08244             if (!(p = iaxs[callno])) {
08245                peer_unref(peer);
08246                return -1;
08247             }
08248             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08249             peer_unref(peer);
08250          }
08251          if (!peer) {
08252             ast_mutex_lock(&iaxsl[callno]);
08253             if (!(p = iaxs[callno]))
08254                return -1;
08255          }
08256       }
08257    }
08258 
08259    if (ies->encmethods) {
08260       ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08261    } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08262       ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n");
08263       return -1;             /* if force encryption is yes, and no encryption methods, then return -1 to hangup */
08264    }
08265    if (!res) {
08266       struct ast_datastore *variablestore;
08267       struct ast_variable *var, *prev = NULL;
08268       AST_LIST_HEAD(, ast_var_t) *varlist;
08269       varlist = ast_calloc(1, sizeof(*varlist));
08270       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08271       if (variablestore && varlist && p->owner) {
08272          variablestore->data = varlist;
08273          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08274          AST_LIST_HEAD_INIT(varlist);
08275          for (var = ies->vars; var; var = var->next) {
08276             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08277             if (prev)
08278                ast_free(prev);
08279             prev = var;
08280             if (!newvar) {
08281                /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */
08282                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08283             } else {
08284                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08285             }
08286          }
08287          if (prev)
08288             ast_free(prev);
08289          ies->vars = NULL;
08290          ast_channel_datastore_add(p->owner, variablestore);
08291       } else {
08292          if (p->owner)
08293             ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08294          if (variablestore)
08295             ast_datastore_free(variablestore);
08296          if (varlist)
08297             ast_free(varlist);
08298       }
08299    }
08300 
08301    if (!res)
08302       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08303    return res;
08304 }

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

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

Referenced by socket_process().

07837 {
07838    struct iax_ie_data ied;
07839    int res = -1, authreq_restrict = 0;
07840    char challenge[10];
07841    struct chan_iax2_pvt *p = iaxs[call_num];
07842 
07843    memset(&ied, 0, sizeof(ied));
07844 
07845    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
07846    if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07847       struct iax2_user *user, tmp_user = {
07848          .name = p->username, 
07849       };
07850 
07851       user = ao2_find(users, &tmp_user, OBJ_POINTER);
07852       if (user) {
07853          if (user->curauthreq == user->maxauthreq)
07854             authreq_restrict = 1;
07855          else
07856             user->curauthreq++;
07857          user = user_unref(user);
07858       }
07859    }
07860 
07861    /* If the AUTHREQ limit test failed, send back an error */
07862    if (authreq_restrict) {
07863       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07864       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07865       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07866       return 0;
07867    }
07868 
07869    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07870    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07871       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07872       ast_string_field_set(p, challenge, challenge);
07873       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
07874       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07875    }
07876    if (p->encmethods)
07877       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07878 
07879    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07880 
07881    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07882 
07883    if (p->encmethods)
07884       ast_set_flag64(p, IAX_ENCRYPTED);
07885 
07886    return res;
07887 }

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

Definition at line 7889 of file chan_iax2.c.

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

Referenced by socket_process().

07890 {
07891    char requeststr[256];
07892    char md5secret[256] = "";
07893    char secret[256] = "";
07894    char rsasecret[256] = "";
07895    int res = -1; 
07896    int x;
07897    struct iax2_user *user, tmp_user = {
07898       .name = p->username, 
07899    };
07900 
07901    if (p->authrej) {
07902       return res;
07903    }
07904    user = ao2_find(users, &tmp_user, OBJ_POINTER);
07905    if (user) {
07906       if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07907          ast_atomic_fetchadd_int(&user->curauthreq, -1);
07908          ast_clear_flag64(p, IAX_MAXAUTHREQ);
07909       }
07910       ast_string_field_set(p, host, user->name);
07911       user = user_unref(user);
07912    }
07913    if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 
07914       ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.\n");
07915       return res;
07916    }
07917    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07918       return res;
07919    if (ies->password)
07920       ast_copy_string(secret, ies->password, sizeof(secret));
07921    if (ies->md5_result)
07922       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07923    if (ies->rsa_result)
07924       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07925    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07926       struct ast_key *key;
07927       char *keyn;
07928       char tmpkey[256];
07929       char *stringp=NULL;
07930       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07931       stringp=tmpkey;
07932       keyn = strsep(&stringp, ":");
07933       while(keyn) {
07934          key = ast_key_get(keyn, AST_KEY_PUBLIC);
07935          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07936             res = 0;
07937             break;
07938          } else if (!key)
07939             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07940          keyn = strsep(&stringp, ":");
07941       }
07942    } else if (p->authmethods & IAX_AUTH_MD5) {
07943       struct MD5Context md5;
07944       unsigned char digest[16];
07945       char *tmppw, *stringp;
07946       
07947       tmppw = ast_strdupa(p->secret);
07948       stringp = tmppw;
07949       while((tmppw = strsep(&stringp, ";"))) {
07950          MD5Init(&md5);
07951          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07952          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07953          MD5Final(digest, &md5);
07954          /* If they support md5, authenticate with it.  */
07955          for (x=0;x<16;x++)
07956             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
07957          if (!strcasecmp(requeststr, md5secret)) {
07958             res = 0;
07959             break;
07960          }
07961       }
07962    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07963       if (!strcmp(secret, p->secret))
07964          res = 0;
07965    }
07966    return res;
07967 }

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

Definition at line 4688 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

Referenced by iax2_call().

04689 {
04690 #ifdef SCHED_MULTITHREADED
04691    if (schedule_action(__auto_congest, data))
04692 #endif      
04693       __auto_congest(data);
04694    return 0;
04695 }

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

Definition at line 9076 of file chan_iax2.c.

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

Referenced by iax2_dprequest(), and iax2_provision().

09077 {
09078    int callno = (int)(long)(data);
09079    ast_mutex_lock(&iaxsl[callno]);
09080    if (iaxs[callno]) {
09081       iaxs[callno]->autoid = -1;
09082    }
09083    ast_mutex_unlock(&iaxsl[callno]);
09084 #ifdef SCHED_MULTITHREADED
09085    if (schedule_action(__auto_hangup, data))
09086 #endif      
09087       __auto_hangup(data);
09088    return 0;
09089 }

static void build_callno_limits ( struct ast_variable v  )  [static]

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

02460 {
02461    struct addr_range *addr_range = NULL;
02462    struct addr_range tmp;
02463    struct ast_ha *ha;
02464    int limit;
02465    int error;
02466    int found;
02467 
02468    for (; v; v = v->next) {
02469       limit = -1;
02470       error = 0;
02471       found = 0;
02472       ha = ast_append_ha("permit", v->name, NULL, &error);
02473 
02474       /* check for valid config information */
02475       if (error) {
02476          ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02477          continue;
02478       } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02479          ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02480          ast_free_ha(ha);
02481          continue;
02482       }
02483 
02484       ast_copy_ha(ha, &tmp.ha);
02485       /* find or create the addr_range */
02486       if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02487          ao2_lock(addr_range);
02488          found = 1;
02489       } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02490          ast_free_ha(ha);
02491          return; /* out of memory */
02492       }
02493 
02494       /* copy over config data into addr_range object */
02495       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
02496       ast_free_ha(ha); /* cleanup the tmp ha */
02497       addr_range->limit = limit;
02498       addr_range->delme = 0;
02499 
02500       /* cleanup */
02501       if (found) {
02502          ao2_unlock(addr_range);
02503       } else {
02504          ao2_link(callno_limits, addr_range);
02505       }
02506       ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02507    }
02508 }

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

Definition at line 12329 of file chan_iax2.c.

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

Referenced by build_user().

12330 {
12331    struct iax2_context *con;
12332 
12333    if ((con = ast_calloc(1, sizeof(*con))))
12334       ast_copy_string(con->context, context, sizeof(con->context));
12335    
12336    return con;
12337 }

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

Definition at line 6217 of file chan_iax2.c.

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

Referenced by build_encryption_keys(), and iax2_key_rotate().

06218 {
06219    /* it is required to hold the corresponding decrypt key to our encrypt key
06220     * in the pvt struct because queued frames occasionally need to be decrypted and
06221     * re-encrypted when updated for a retransmission */
06222    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06223    ast_aes_set_encrypt_key(digest, &pvt->ecx);
06224    ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06225 }

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

Definition at line 6211 of file chan_iax2.c.

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

Referenced by authenticate(), and decrypt_frame().

06212 {
06213    build_ecx_key(digest, pvt);
06214    ast_aes_set_decrypt_key(digest, &pvt->dcx);
06215 }

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

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

Referenced by realtime_peer(), and set_config().

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

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

Definition at line 6201 of file chan_iax2.c.

References ast_random().

Referenced by build_ecx_key(), and update_packet().

06202 {
06203    long tmp;
06204    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06205       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06206       buf += sizeof(tmp);
06207       len -= sizeof(tmp);
06208    }
06209 }

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

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

Referenced by realtime_user(), and set_config().

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

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

Definition at line 13669 of file chan_iax2.c.

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

Referenced by find_cache().

13670 {
13671    struct sockaddr_in sin;
13672    int x;
13673    int callno;
13674    struct iax_ie_data ied;
13675    struct create_addr_info cai;
13676    struct parsed_dial_string pds;
13677    char *tmpstr;
13678 
13679    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13680       /* Look for an *exact match* call.  Once a call is negotiated, it can only
13681          look up entries for a single context */
13682       if (!ast_mutex_trylock(&iaxsl[x])) {
13683          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13684             return x;
13685          ast_mutex_unlock(&iaxsl[x]);
13686       }
13687    }
13688 
13689    /* No match found, we need to create a new one */
13690 
13691    memset(&cai, 0, sizeof(cai));
13692    memset(&ied, 0, sizeof(ied));
13693    memset(&pds, 0, sizeof(pds));
13694 
13695    tmpstr = ast_strdupa(data);
13696    parse_dial_string(tmpstr, &pds);
13697 
13698    if (ast_strlen_zero(pds.peer)) {
13699       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13700       return -1;
13701    }
13702 
13703    /* Populate our address from the given */
13704    if (create_addr(pds.peer, NULL, &sin, &cai))
13705       return -1;
13706 
13707    ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13708       pds.peer, pds.username, pds.password, pds.context);
13709 
13710    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13711    if (callno < 1) {
13712       ast_log(LOG_WARNING, "Unable to create call\n");
13713       return -1;
13714    }
13715 
13716    ast_string_field_set(iaxs[callno], dproot, data);
13717    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13718 
13719    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13720    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13721    /* the string format is slightly different from a standard dial string,
13722       because the context appears in the 'exten' position
13723    */
13724    if (pds.exten)
13725       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13726    if (pds.username)
13727       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13728    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13729    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13730    /* Keep password handy */
13731    if (pds.password)
13732       ast_string_field_set(iaxs[callno], secret, pds.password);
13733    if (pds.key)
13734       ast_string_field_set(iaxs[callno], outkey, pds.key);
13735    /* Start the call going */
13736    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
13737    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13738 
13739    return callno;
13740 }

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

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

06055 {
06056    /* Returns where in "receive time" we are.  That is, how many ms
06057       since we received (or would have received) the frame with timestamp 0 */
06058    int ms;
06059 #ifdef IAXTESTS
06060    int jit;
06061 #endif /* IAXTESTS */
06062    /* Setup rxcore if necessary */
06063    if (ast_tvzero(p->rxcore)) {
06064       p->rxcore = ast_tvnow();
06065       if (iaxdebug)
06066          ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
06067                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06068       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06069 #if 1
06070       if (iaxdebug)
06071          ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06072                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06073 #endif
06074    }
06075 
06076    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06077 #ifdef IAXTESTS
06078    if (test_jit) {
06079       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06080          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06081          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06082             jit = -jit;
06083          ms += jit;
06084       }
06085    }
06086    if (test_late) {
06087       ms += test_late;
06088       test_late = 0;
06089    }
06090 #endif /* IAXTESTS */
06091    return ms;
06092 }

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

Definition at line 5922 of file chan_iax2.c.

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

Referenced by iax2_send(), and socket_process().

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

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

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

05879 {
05880    unsigned long int mssincetx; /* unsigned to handle overflows */
05881    long int ms, pred;
05882 
05883    tpeer->trunkact = *now;
05884    mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05885    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05886       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
05887       tpeer->txtrunktime = *now;
05888       tpeer->lastsent = 999999;
05889    }
05890    /* Update last transmit time now */
05891    tpeer->lasttxtime = *now;
05892    
05893    /* Calculate ms offset */
05894    ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05895    /* Predict from last value */
05896    pred = tpeer->lastsent + sampms;
05897    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05898       ms = pred;
05899    
05900    /* We never send the same timestamp twice, so fudge a little if we must */
05901    if (ms == tpeer->lastsent)
05902       ms = tpeer->lastsent + 1;
05903    tpeer->lastsent = ms;
05904    return ms;
05905 }

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

Definition at line 2682 of file chan_iax2.c.

References ast_random().

Referenced by create_callno_pools().

02683 {
02684    return abs(ast_random());
02685 }

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

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

02207 {
02208    struct addr_range *addr_range;
02209    struct iax2_peer *peer = NULL;
02210    struct iax2_user *user = NULL;
02211    /* if no username is given, check for guest accounts */
02212    const char *find = S_OR(name, "guest");
02213    int res = 1;  /* required by default */
02214    int optional = 0;
02215    enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02216    /* There are only two cases in which calltoken validation is not required.
02217     * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
02218     *         the peer definition has not set the requirecalltoken option.
02219     * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
02220     */
02221 
02222    /* ----- Case 1 ----- */
02223    if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02224       ao2_ref(addr_range, -1);
02225       optional = 1;
02226    }
02227 
02228    /* ----- Case 2 ----- */
02229    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02230       calltoken_required = user->calltoken_required;
02231    } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02232       calltoken_required = user->calltoken_required;
02233    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02234       calltoken_required = peer->calltoken_required;
02235    } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02236       calltoken_required = peer->calltoken_required;
02237    }
02238 
02239    if (peer) {
02240       peer_unref(peer);
02241    }
02242    if (user) {
02243       user_unref(user);
02244    }
02245 
02246    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);
02247    if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02248       (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02249       res = 0;
02250    }
02251 
02252    return res;
02253 }

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

Definition at line 7568 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

Definition at line 9446 of file chan_iax2.c.

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

Referenced by socket_process().

09447 {
09448    unsigned int ourver;
09449    char rsi[80];
09450    snprintf(rsi, sizeof(rsi), "si-%s", si);
09451    if (iax_provision_version(&ourver, rsi, 1))
09452       return 0;
09453    ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09454    if (ourver != ver) 
09455       iax2_provision(sin, sockfd, NULL, rsi, 1);
09456    return 0;
09457 }

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

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

Referenced by peer_set_srcaddr().

12356 {
12357    int sd;
12358    int res;
12359    
12360    sd = socket(AF_INET, SOCK_DGRAM, 0);
12361    if (sd < 0) {
12362       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12363       return -1;
12364    }
12365 
12366    res = bind(sd, sa, salen);
12367    if (res < 0) {
12368       ast_debug(1, "Can't bind: %s\n", strerror(errno));
12369       close(sd);
12370       return 1;
12371    }
12372 
12373    close(sd);
12374    return 0;
12375 }

static void cleanup_thread_list ( void *  head  )  [static]

Definition at line 14408 of file chan_iax2.c.

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

Referenced by __unload_module().

14409 {
14410    AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14411    struct iax2_thread_list *list_head = head;
14412    struct iax2_thread *thread;
14413 
14414    AST_LIST_LOCK(list_head);
14415    while ((thread = AST_LIST_REMOVE_HEAD(list_head, list))) {
14416       pthread_t thread_id = thread->threadid;
14417 
14418       thread->stop = 1;
14419       signal_condition(&thread->lock, &thread->cond);
14420 
14421       AST_LIST_UNLOCK(list_head);
14422       pthread_join(thread_id, NULL);
14423       AST_LIST_LOCK(list_head);
14424    }
14425    AST_LIST_UNLOCK(list_head);
14426 }

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

Definition at line 8358 of file chan_iax2.c.

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

Referenced by socket_process().

08359 {
08360    char exten[256] = "";
08361    int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08362    struct iax2_dpcache *dp = NULL;
08363    
08364    if (ies->called_number)
08365       ast_copy_string(exten, ies->called_number, sizeof(exten));
08366    
08367    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08368       status = CACHE_FLAG_EXISTS;
08369    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08370       status = CACHE_FLAG_CANEXIST;
08371    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08372       status = CACHE_FLAG_NONEXISTENT;
08373 
08374    if (ies->refresh)
08375       expiry = ies->refresh;
08376    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08377       matchmore = CACHE_FLAG_MATCHMORE;
08378    
08379    AST_LIST_LOCK(&dpcache);
08380    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08381       if (strcmp(dp->exten, exten))
08382          continue;
08383       AST_LIST_REMOVE_CURRENT(peer_list);
08384       dp->callno = 0;
08385       dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08386       if (dp->flags & CACHE_FLAG_PENDING) {
08387          dp->flags &= ~CACHE_FLAG_PENDING;
08388          dp->flags |= status;
08389          dp->flags |= matchmore;
08390       }
08391       /* Wake up waiters */
08392       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08393          if (dp->waiters[x] > -1) {
08394             if (write(dp->waiters[x], "asdf", 4) < 0) {
08395             }
08396          }
08397       }
08398    }
08399    AST_LIST_TRAVERSE_SAFE_END;
08400    AST_LIST_UNLOCK(&dpcache);
08401 
08402    return 0;
08403 }

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

Definition at line 3835 of file chan_iax2.c.

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

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

03836 {
03837    int which = 0;
03838    struct iax2_peer *peer;
03839    char *res = NULL;
03840    int wordlen = strlen(word);
03841    struct ao2_iterator i;
03842 
03843    i = ao2_iterator_init(peers, 0);
03844    while ((peer = ao2_iterator_next(&i))) {
03845       if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03846          && (!flags || ast_test_flag64(peer, flags))) {
03847          res = ast_strdup(peer->name);
03848          peer_unref(peer);
03849          break;
03850       }
03851       peer_unref(peer);
03852    }
03853    ao2_iterator_destroy(&i);
03854 
03855    return res;
03856 }

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

Definition at line 6921 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_unregister().

06922 {
06923    int which = 0;
06924    struct iax2_peer *p = NULL;
06925    char *res = NULL;
06926    int wordlen = strlen(word);
06927 
06928    /* 0 - iax2; 1 - unregister; 2 - <peername> */
06929    if (pos == 2) {
06930       struct ao2_iterator i = ao2_iterator_init(peers, 0);
06931       while ((p = ao2_iterator_next(&i))) {
06932          if (!strncasecmp(p->name, word, wordlen) && 
06933             ++which > state && p->expire > 0) {
06934             res = ast_strdup(p->name);
06935             peer_unref(p);
06936             break;
06937          }
06938          peer_unref(p);
06939       }
06940       ao2_iterator_destroy(&i);
06941    }
06942 
06943    return res;
06944 }

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

Definition at line 8405 of file chan_iax2.c.

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

Referenced by socket_process().

08406 {
08407    int peercallno = 0;
08408    struct chan_iax2_pvt *pvt = iaxs[callno];
08409    struct iax_frame *cur;
08410    jb_frame frame;
08411 
08412    if (ies->callno)
08413       peercallno = ies->callno;
08414 
08415    if (peercallno < 1) {
08416       ast_log(LOG_WARNING, "Invalid transfer request\n");
08417       return -1;
08418    }
08419    remove_by_transfercallno(pvt);
08420    /* since a transfer has taken place, the address will change.
08421     * This must be accounted for in the peercnts table.  Remove
08422     * the old address and add the new one */
08423    peercnt_remove_by_addr(&pvt->addr);
08424    peercnt_add(&pvt->transfer);
08425    /* now copy over the new address */
08426    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08427    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08428    /* Reset sequence numbers */
08429    pvt->oseqno = 0;
08430    pvt->rseqno = 0;
08431    pvt->iseqno = 0;
08432    pvt->aseqno = 0;
08433 
08434    if (pvt->peercallno) {
08435       remove_by_peercallno(pvt);
08436    }
08437    pvt->peercallno = peercallno;
08438    /*this is where the transfering call swiches hash tables */
08439    store_by_peercallno(pvt);
08440    pvt->transferring = TRANSFER_NONE;
08441    pvt->svoiceformat = -1;
08442    pvt->voiceformat = 0;
08443    pvt->svideoformat = -1;
08444    pvt->videoformat = 0;
08445    pvt->transfercallno = 0;
08446    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08447    memset(&pvt->offset, 0, sizeof(pvt->offset));
08448    /* reset jitterbuffer */
08449    while(jb_getall(pvt->jb,&frame) == JB_OK)
08450       iax2_frame_free(frame.data);
08451    jb_reset(pvt->jb);
08452    pvt->lag = 0;
08453    pvt->last = 0;
08454    pvt->lastsent = 0;
08455    pvt->nextpred = 0;
08456    pvt->pingtime = DEFAULT_RETRY_TIME;
08457    AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08458       /* We must cancel any packets that would have been transmitted
08459          because now we're talking to someone new.  It's okay, they
08460          were transmitted to someone that didn't care anyway. */
08461       cur->retries = -1;
08462    }
08463    return 0;
08464 }

static unsigned char compress_subclass ( format_t  subclass  )  [static]

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

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

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

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

09460 {
09461    jb_info stats;
09462    jb_getinfo(pvt->jb, &stats);
09463    
09464    memset(iep, 0, sizeof(*iep));
09465 
09466    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09467    if(stats.frames_in == 0) stats.frames_in = 1;
09468    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09469    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09470    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09471    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09472    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09473 }

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

Definition at line 4574 of file chan_iax2.c.

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

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

04575 {
04576    struct iax2_peer *peer;
04577    int res = -1;
04578    struct ast_codec_pref ourprefs;
04579    struct sockaddr_in peer_addr;
04580 
04581    ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04582    cai->sockfd = defaultsockfd;
04583    cai->maxtime = 0;
04584    sin->sin_family = AF_INET;
04585 
04586    if (!(peer = find_peer(peername, 1))) {
04587       struct ast_sockaddr sin_tmp;
04588 
04589       cai->found = 0;
04590       sin_tmp.ss.ss_family = AF_INET;
04591       if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
04592          ast_log(LOG_WARNING, "No such host: %s\n", peername);
04593          return -1;
04594       }
04595       ast_sockaddr_to_sin(&sin_tmp, sin);
04596       if (sin->sin_port == 0) {
04597          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04598       }
04599       /* use global iax prefs for unknown peer/user */
04600       /* But move the calling channel's native codec to the top of the preference list */
04601       memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04602       if (c)
04603          ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04604       ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04605       return 0;
04606    }
04607 
04608    cai->found = 1;
04609 
04610    ast_sockaddr_to_sin(&peer->addr, &peer_addr);
04611 
04612    /* if the peer has no address (current or default), return failure */
04613    if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
04614       goto return_unref;
04615    }
04616 
04617    /* if the peer is being monitored and is currently unreachable, return failure */
04618    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04619       goto return_unref;
04620 
04621    ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04622    cai->maxtime = peer->maxms;
04623    cai->capability = peer->capability;
04624    cai->encmethods = peer->encmethods;
04625    cai->sockfd = peer->sockfd;
04626    cai->adsi = peer->adsi;
04627    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04628    /* Move the calling channel's native codec to the top of the preference list */
04629    if (c) {
04630       ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
04631       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04632    }
04633    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04634    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04635    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04636    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04637    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04638    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04639    ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04640    ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04641    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04642    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04643    if (ast_strlen_zero(peer->dbsecret)) {
04644       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04645    } else {
04646       char *family;
04647       char *key = NULL;
04648 
04649       family = ast_strdupa(peer->dbsecret);
04650       key = strchr(family, '/');
04651       if (key)
04652          *key++ = '\0';
04653       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04654          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04655          goto return_unref;
04656       }
04657    }
04658 
04659    if (peer_addr.sin_addr.s_addr) {
04660       sin->sin_addr = peer_addr.sin_addr;
04661       sin->sin_port = peer_addr.sin_port;
04662    } else {
04663       sin->sin_addr = peer->defaddr.sin_addr;
04664       sin->sin_port = peer->defaddr.sin_port;
04665    }
04666 
04667    res = 0;
04668 
04669 return_unref:
04670    peer_unref(peer);
04671 
04672    return res;
04673 }

static int create_callno_pools ( void   )  [static]

Definition at line 2687 of file chan_iax2.c.

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

Referenced by load_objects().

02688 {
02689    uint16_t i;
02690 
02691    if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02692       return -1;
02693    }
02694 
02695    if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02696       return -1;
02697    }
02698 
02699    /* start at 2, 0 and 1 are reserved */
02700    for (i = 2; i < IAX_MAX_CALLS; i++) {
02701       struct callno_entry *callno_entry;
02702 
02703       if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02704          return -1;
02705       }
02706 
02707       callno_entry->callno = i;
02708 
02709       if (i < TRUNK_CALL_START) {
02710          ao2_link(callno_pool, callno_entry);
02711       } else {
02712          ao2_link(callno_pool_trunk, callno_entry);
02713       }
02714 
02715       ao2_ref(callno_entry, -1);
02716    }
02717 
02718    return 0;
02719 }

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

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

Referenced by decrypt_frame(), and update_packet().

06276 {
06277    int padding;
06278    unsigned char *workspace;
06279 
06280    workspace = ast_alloca(*datalen);
06281    memset(f, 0, sizeof(*f));
06282    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06283       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06284       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06285          return -1;
06286       /* Decrypt */
06287       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06288 
06289       padding = 16 + (workspace[15] & 0x0f);
06290       if (iaxdebug)
06291          ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06292       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06293          return -1;
06294 
06295       *datalen -= padding;
06296       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06297       f->frametype = fh->type;
06298       if (f->frametype == AST_FRAME_VIDEO) {
06299          f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06300       } else if (f->frametype == AST_FRAME_VOICE) {
06301          f->subclass.codec = uncompress_subclass(fh->csub);
06302       } else {
06303          f->subclass.integer = uncompress_subclass(fh->csub);
06304       }
06305    } else {
06306       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06307       if (iaxdebug)
06308          ast_debug(1, "Decoding mini with length %d\n", *datalen);
06309       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06310          return -1;
06311       /* Decrypt */
06312       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06313       padding = 16 + (workspace[15] & 0x0f);
06314       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06315          return -1;
06316       *datalen -= padding;
06317       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06318    }
06319    return 0;
06320 }

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

Definition at line 6361 of file chan_iax2.c.

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

Referenced by socket_process().

06362 {
06363    int res=-1;
06364    if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06365       /* Search for possible keys, given secrets */
06366       struct MD5Context md5;
06367       unsigned char digest[16];
06368       char *tmppw, *stringp;
06369       
06370       tmppw = ast_strdupa(iaxs[callno]->secret);
06371       stringp = tmppw;
06372       while ((tmppw = strsep(&stringp, ";"))) {
06373          MD5Init(&md5);
06374          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06375          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06376          MD5Final(digest, &md5);
06377          build_encryption_keys(digest, iaxs[callno]);
06378          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06379          if (!res) {
06380             ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06381             break;
06382          }
06383       }
06384    } else 
06385       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06386    return res;
06387 }

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

References ast_calloc, ast_cond_signal, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock, ast_mutex_unlock, IAX_IOSTATE_READY, and ast_iax2_full_hdr::oseqno.

Referenced by socket_read().

09607 {
09608    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09609    struct ast_iax2_full_hdr *fh, *cur_fh;
09610 
09611    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09612       return;
09613 
09614    pkt_buf->len = from_here->buf_len;
09615    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09616 
09617    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09618    ast_mutex_lock(&to_here->lock);
09619    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09620       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09621       if (fh->oseqno < cur_fh->oseqno) {
09622          AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09623          break;
09624       }
09625    }
09626    AST_LIST_TRAVERSE_SAFE_END
09627 
09628    if (!cur_pkt_buf)
09629       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09630 
09631    to_here->iostate = IAX_IOSTATE_READY;
09632    ast_cond_signal(&to_here->cond);
09633    
09634    ast_mutex_unlock(&to_here->lock);
09635 }

static void delete_users ( void   )  [static]

Definition at line 13042 of file chan_iax2.c.

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

Referenced by __unload_module(), and set_config_destroy().

13043 {
13044    struct iax2_registry *reg;
13045 
13046    ao2_callback(users, 0, user_delme_cb, NULL);
13047 
13048    AST_LIST_LOCK(&registrations);
13049    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
13050       if (sched) {
13051          ast_sched_thread_del(sched, reg->expire);
13052       }
13053       if (reg->callno) {
13054          int callno = reg->callno;
13055          ast_mutex_lock(&iaxsl[callno]);
13056          if (iaxs[callno]) {
13057             iaxs[callno]->reg = NULL;
13058             iax2_destroy(callno);
13059          }
13060          ast_mutex_unlock(&iaxsl[callno]);
13061       }
13062       if (reg->dnsmgr)
13063          ast_dnsmgr_release(reg->dnsmgr);
13064       ast_free(reg);
13065    }
13066    AST_LIST_UNLOCK(&registrations);
13067 
13068    ao2_callback(peers, 0, peer_delme_cb, NULL);
13069 }

static void destroy_firmware ( struct iax_firmware cur  )  [static]

Definition at line 3017 of file chan_iax2.c.

References ast_free.

Referenced by reload_firmware().

03018 {
03019    /* Close firmware */
03020    if (cur->fwh) {
03021       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
03022    }
03023    close(cur->fd);
03024    ast_free(cur);
03025 }

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

Definition at line 9261 of file chan_iax2.c.

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

Referenced by dp_lookup_thread(), and socket_process().

09262 {
09263    unsigned short dpstatus = 0;
09264    struct iax_ie_data ied1;
09265    int mm;
09266 
09267    memset(&ied1, 0, sizeof(ied1));
09268    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09269    /* Must be started */
09270    if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09271       dpstatus = IAX_DPSTATUS_EXISTS;
09272    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09273       dpstatus = IAX_DPSTATUS_CANEXIST;
09274    } else {
09275       dpstatus = IAX_DPSTATUS_NONEXISTENT;
09276    }
09277    if (ast_ignore_pattern(context, callednum))
09278       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09279    if (mm)
09280       dpstatus |= IAX_DPSTATUS_MATCHMORE;
09281    if (!skiplock)
09282       ast_mutex_lock(&iaxsl[callno]);
09283    if (iaxs[callno]) {
09284       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09285       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09286       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09287       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09288    }
09289    if (!skiplock)
09290       ast_mutex_unlock(&iaxsl[callno]);
09291 }

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

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

09294 {
09295    /* Look up for dpreq */
09296    struct dpreq_data *dpr = data;
09297    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09298    if (dpr->callerid)
09299       ast_free(dpr->callerid);
09300    ast_free(dpr);
09301    return NULL;
09302 }

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

Definition at line 1542 of file chan_iax2.c.

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

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

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

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

Definition at line 6322 of file chan_iax2.c.

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

Referenced by iax2_send(), and update_packet().

06323 {
06324    int padding;
06325    unsigned char *workspace;
06326    workspace = ast_alloca(*datalen + 32);
06327    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06328       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06329       if (iaxdebug)
06330          ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06331       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06332       padding = 16 + (padding & 0xf);
06333       memcpy(workspace, poo, padding);
06334       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06335       workspace[15] &= 0xf0;
06336       workspace[15] |= (padding & 0xf);
06337       if (iaxdebug)
06338          ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06339       *datalen += padding;
06340       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06341       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06342          memcpy(poo, workspace + *datalen - 32, 32);
06343    } else {
06344       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06345       if (iaxdebug)
06346          ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06347       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06348       padding = 16 + (padding & 0xf);
06349       memcpy(workspace, poo, padding);
06350       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06351       workspace[15] &= 0xf0;
06352       workspace[15] |= (padding & 0x0f);
06353       *datalen += padding;
06354       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06355       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06356          memcpy(poo, workspace + *datalen - 32, 32);
06357    }
06358    return 0;
06359 }

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

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

08674 {
08675 #ifdef SCHED_MULTITHREADED
08676    if (schedule_action(__expire_registry, data))
08677 #endif      
08678       __expire_registry(data);
08679    return 0;
08680 }

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

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

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

13743 {
13744    struct iax2_dpcache *dp = NULL;
13745    struct timeval now = ast_tvnow();
13746    int x, com[2], timeout, old = 0, outfd, doabort, callno;
13747    struct ast_channel *c = NULL;
13748    struct ast_frame *f = NULL;
13749 
13750    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13751       if (ast_tvcmp(now, dp->expiry) > 0) {
13752          AST_LIST_REMOVE_CURRENT(cache_list);
13753          if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13754             ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13755          else
13756             ast_free(dp);
13757          continue;
13758       }
13759       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13760          break;
13761    }
13762    AST_LIST_TRAVERSE_SAFE_END;
13763 
13764    if (!dp) {
13765       /* No matching entry.  Create a new one. */
13766       /* First, can we make a callno? */
13767       if ((callno = cache_get_callno_locked(data)) < 0) {
13768          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13769          return NULL;
13770       }
13771       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13772          ast_mutex_unlock(&iaxsl[callno]);
13773          return NULL;
13774       }
13775       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13776       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13777       dp->expiry = ast_tvnow();
13778       dp->orig = dp->expiry;
13779       /* Expires in 30 mins by default */
13780       dp->expiry.tv_sec += iaxdefaultdpcache;
13781       dp->flags = CACHE_FLAG_PENDING;
13782       for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13783          dp->waiters[x] = -1;
13784       /* Insert into the lists */
13785       AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13786       AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13787       /* Send the request if we're already up */
13788       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13789          iax2_dprequest(dp, callno);
13790       ast_mutex_unlock(&iaxsl[callno]);
13791    }
13792 
13793    /* By here we must have a dp */
13794    if (dp->flags & CACHE_FLAG_PENDING) {
13795       struct timeval start;
13796       int ms;
13797       /* Okay, here it starts to get nasty.  We need a pipe now to wait
13798          for a reply to come back so long as it's pending */
13799       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13800          /* Find an empty slot */
13801          if (dp->waiters[x] < 0)
13802             break;
13803       }
13804       if (x >= ARRAY_LEN(dp->waiters)) {
13805          ast_log(LOG_WARNING, "No more waiter positions available\n");
13806          return NULL;
13807       }
13808       if (pipe(com)) {
13809          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13810          return NULL;
13811       }
13812       dp->waiters[x] = com[1];
13813       /* Okay, now we wait */
13814       timeout = iaxdefaulttimeout * 1000;
13815       /* Temporarily unlock */
13816       AST_LIST_UNLOCK(&dpcache);
13817       /* Defer any dtmf */
13818       if (chan)
13819          old = ast_channel_defer_dtmf(chan);
13820       doabort = 0;
13821       start = ast_tvnow();
13822       while ((ms = ast_remaining_ms(start, timeout))) {
13823          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &ms);
13824          if (outfd > -1)
13825             break;
13826          if (!c)
13827             continue;
13828          if (!(f = ast_read(c))) {
13829             doabort = 1;
13830             break;
13831          }
13832          ast_frfree(f);
13833       }
13834       if (!ms) {
13835          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13836       }
13837       AST_LIST_LOCK(&dpcache);
13838       dp->waiters[x] = -1;
13839       close(com[1]);
13840       close(com[0]);
13841       if (doabort) {
13842          /* Don't interpret anything, just abort.  Not sure what th epoint
13843            of undeferring dtmf on a hung up channel is but hey whatever */
13844          if (!old && chan)
13845             ast_channel_undefer_dtmf(chan);
13846          return NULL;
13847       }
13848       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13849          /* Now to do non-independent analysis the results of our wait */
13850          if (dp->flags & CACHE_FLAG_PENDING) {
13851             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
13852                pending.  Don't let it take as long to timeout. */
13853             dp->flags &= ~CACHE_FLAG_PENDING;
13854             dp->flags |= CACHE_FLAG_TIMEOUT;
13855             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
13856                systems without leaving it unavailable once the server comes back online */
13857             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13858             for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13859                if (dp->waiters[x] > -1) {
13860                   if (write(dp->waiters[x], "asdf", 4) < 0) {
13861                      ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13862                   }
13863                }
13864             }
13865          }
13866       }
13867       /* Our caller will obtain the rest */
13868       if (!old && chan)
13869          ast_channel_undefer_dtmf(chan);
13870    }
13871    return dp;  
13872 }

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

References __find_callno().

Referenced by iax2_poke_peer(), and socket_process().

02942                                                                                                                                     { 
02943    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02944 }

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

02946                                                                                                                                            {
02947 
02948    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02949 }

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

Definition at line 1394 of file chan_iax2.c.

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

Referenced by __schedule_action(), and socket_read().

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

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

References ao2_find, OBJ_POINTER, and realtime_peer().

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

01687 {
01688    struct iax2_peer *peer = NULL;
01689    struct iax2_peer tmp_peer = {
01690       .name = name,
01691    };
01692 
01693    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01694 
01695    /* Now go for realtime if applicable */
01696    if(!peer && realtime)
01697       peer = realtime_peer(name, NULL);
01698 
01699    return peer;
01700 }

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

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

06095 {
06096    struct iax2_trunk_peer *tpeer = NULL;
06097    
06098    /* Finds and locks trunk peer */
06099    AST_LIST_LOCK(&tpeers);
06100 
06101    AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06102       if (!inaddrcmp(&tpeer->addr, sin)) {
06103          ast_mutex_lock(&tpeer->lock);
06104          break;
06105       }
06106    }
06107 
06108    if (!tpeer) {
06109       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06110          ast_mutex_init(&tpeer->lock);
06111          tpeer->lastsent = 9999;
06112          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06113          tpeer->trunkact = ast_tvnow();
06114          ast_mutex_lock(&tpeer->lock);
06115          tpeer->sockfd = fd;
06116 #ifdef SO_NO_CHECK
06117          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06118 #endif
06119          ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06120          AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06121       }
06122    }
06123 
06124    AST_LIST_UNLOCK(&tpeers);
06125 
06126    return tpeer;
06127 }

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

Definition at line 1714 of file chan_iax2.c.

References ao2_find, and OBJ_POINTER.

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

01715 {
01716    struct iax2_user tmp_user = {
01717       .name = name,
01718    };
01719 
01720    return ao2_find(users, &tmp_user, OBJ_POINTER);
01721 }

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

Definition at line 5907 of file chan_iax2.c.

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

Referenced by socket_process_meta().

05908 {
05909    long ms; /* NOT unsigned */
05910    if (ast_tvzero(iaxs[callno]->rxcore)) {
05911       /* Initialize rxcore time if appropriate */
05912       iaxs[callno]->rxcore = ast_tvnow();
05913       /* Round to nearest 20ms so traces look pretty */
05914       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05915    }
05916    /* Calculate difference between trunk and channel */
05917    ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05918    /* Return as the sum of trunk time and the difference between trunk and real time */
05919    return ms + ts;
05920 }

static void free_context ( struct iax2_context con  )  [static]

Definition at line 12174 of file chan_iax2.c.

References ast_free, and iax2_context::next.

Referenced by build_user(), and user_destructor().

12175 {
12176    struct iax2_context *conl;
12177    while(con) {
12178       conl = con;
12179       con = con->next;
12180       ast_free(conl);
12181    }
12182 }

static void free_signaling_queue_entry ( struct signaling_queue_entry s  )  [static]

Definition at line 1820 of file chan_iax2.c.

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

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

01821 {
01822    if (s->f.datalen) {
01823       ast_free(s->f.data.ptr);
01824    }
01825    ast_free(s);
01826 }

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

Definition at line 13995 of file chan_iax2.c.

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

13996 {
13997    struct iax2_peer *peer;
13998    char *peername, *colname;
13999 
14000    peername = ast_strdupa(data);
14001 
14002    /* if our channel, return the IP address of the endpoint of current channel */
14003    if (!strcmp(peername,"CURRENTCHANNEL")) {
14004            unsigned short callno;
14005       if (chan->tech != &iax2_tech)
14006          return -1;
14007       callno = PTR_TO_CALLNO(chan->tech_pvt);   
14008       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
14009       return 0;
14010    }
14011 
14012    if ((colname = strchr(peername, ',')))
14013       *colname++ = '\0';
14014    else
14015       colname = "ip";
14016 
14017    if (!(peer = find_peer(peername, 1)))
14018       return -1;
14019 
14020    if (!strcasecmp(colname, "ip")) {
14021       ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
14022    } else  if (!strcasecmp(colname, "status")) {
14023       peer_status(peer, buf, len); 
14024    } else  if (!strcasecmp(colname, "mailbox")) {
14025       ast_copy_string(buf, peer->mailbox, len);
14026    } else  if (!strcasecmp(colname, "context")) {
14027       ast_copy_string(buf, peer->context, len);
14028    } else  if (!strcasecmp(colname, "expire")) {
14029       snprintf(buf, len, "%d", peer->expire);
14030    } else  if (!strcasecmp(colname, "dynamic")) {
14031       ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
14032    } else  if (!strcasecmp(colname, "callerid_name")) {
14033       ast_copy_string(buf, peer->cid_name, len);
14034    } else  if (!strcasecmp(colname, "callerid_num")) {
14035       ast_copy_string(buf, peer->cid_num, len);
14036    } else  if (!strcasecmp(colname, "codecs")) {
14037       ast_getformatname_multiple(buf, len -1, peer->capability);
14038    } else  if (!strncasecmp(colname, "codec[", 6)) {
14039       char *codecnum, *ptr;
14040       int codec = 0;
14041 
14042       /* skip over "codec" to the '[' */
14043       codecnum = colname + 5;
14044       *codecnum = '\0';
14045       codecnum++;
14046       if ((ptr = strchr(codecnum, ']'))) {
14047          *ptr = '\0';
14048       }
14049       if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
14050          ast_copy_string(buf, ast_getformatname(codec), len);
14051       } else {
14052          buf[0] = '\0';
14053       }
14054    } else {
14055       buf[0] = '\0';
14056    }
14057 
14058    peer_unref(peer);
14059 
14060    return 0;
14061 }

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

Definition at line 12339 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

12340 {
12341    int methods = 0;
12342    if (strstr(value, "rsa"))
12343       methods |= IAX_AUTH_RSA;
12344    if (strstr(value, "md5"))
12345       methods |= IAX_AUTH_MD5;
12346    if (strstr(value, "plaintext"))
12347       methods |= IAX_AUTH_PLAINTEXT;
12348    return methods;
12349 }

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

Definition at line 1558 of file chan_iax2.c.

References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.

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

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

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

Definition at line 4145 of file chan_iax2.c.

References __get_from_jb(), and schedule_action.

Referenced by update_jbsched().

04146 {
04147 #ifdef SCHED_MULTITHREADED
04148    if (schedule_action(__get_from_jb, data))
04149 #endif      
04150       __get_from_jb(data);
04151    return 0;
04152 }

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

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

02621 {
02622    struct callno_entry *callno_entry = NULL;
02623    if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02624       ast_log(LOG_WARNING, "Out of CallNumbers\n");
02625       /* Minor optimization for the extreme case. */
02626       return NULL;
02627    }
02628 
02629    /* the callno_pool container is locked here primarily to ensure thread
02630     * safety of the total_nonval_callno_used check and increment */
02631    ao2_lock(callno_pool);
02632 
02633    /* only a certain number of nonvalidated call numbers should be allocated.
02634     * If there ever is an attack, this separates the calltoken validating
02635     * users from the non calltoken validating users. */
02636    if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02637       ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02638       ao2_unlock(callno_pool);
02639       return NULL;
02640    }
02641 
02642    /* unlink the object from the container, taking over ownership
02643     * of the reference the container had to the object */
02644    callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02645 
02646    if (callno_entry) {
02647       callno_entry->validated = validated;
02648       if (!validated) {
02649          total_nonval_callno_used++;
02650       }
02651    }
02652 
02653    ao2_unlock(callno_pool);
02654    return callno_entry;
02655 }

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

04885 {
04886 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"  /* address + port + ts + randomcalldata */
04887 #define CALLTOKEN_IE_FORMAT   "%u?%s"     /* time + ? + (40 char hash) */
04888    struct ast_str *buf = ast_str_alloca(256);
04889    time_t t = time(NULL);
04890    char hash[41]; /* 40 char sha1 hash */
04891    int subclass = uncompress_subclass(fh->csub);
04892 
04893    /* ----- Case 1 ----- */
04894    if (ies->calltoken && !ies->calltokendata) {  /* empty calltoken is provided, client supports calltokens */
04895       struct iax_ie_data ied = {
04896          .buf = { 0 },
04897          .pos = 0,
04898       };
04899 
04900       /* create the hash with their address data and our timestamp */
04901       ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04902       ast_sha1_hash(hash, ast_str_buffer(buf));
04903 
04904       ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04905       iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04906       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04907 
04908       return 1;
04909 
04910    /* ----- Case 2 ----- */
04911    } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */
04912       char *rec_hash = NULL;    /* the received hash, make sure it matches with ours. */
04913       char *rec_ts = NULL;      /* received timestamp */
04914       unsigned int rec_time;  /* received time_t */
04915 
04916       /* split the timestamp from the hash data */
04917       rec_hash = strchr((char *) ies->calltokendata, '?');
04918       if (rec_hash) {
04919          *rec_hash++ = '\0';
04920          rec_ts = (char *) ies->calltokendata;
04921       }
04922 
04923       /* check that we have valid data before we do any comparisons */
04924       if (!rec_hash || !rec_ts) {
04925          goto reject;
04926       } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04927          goto reject;
04928       }
04929 
04930       /* create a hash with their address and the _TOKEN'S_ timestamp */
04931       ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04932       ast_sha1_hash(hash, ast_str_buffer(buf));
04933 
04934       /* compare hashes and then check timestamp delay */
04935       if (strcmp(hash, rec_hash)) {
04936          ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04937          goto reject; /* received hash does not match ours, reject */
04938       } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04939          ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04940          goto reject; /* too much delay, reject */
04941       }
04942 
04943       /* at this point the call token is valid, returning 0 
04944        * will allow socket_process to continue as usual */
04945       requirecalltoken_mark_auto(ies->username, subclass);
04946       return 0;
04947 
04948    /* ----- Case 3 ----- */
04949    } else { /* calltokens are not supported for this client, how do we respond? */
04950       if (calltoken_required(sin, ies->username, subclass)) {
04951          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"));
04952          goto reject;
04953       }
04954       return 0; /* calltoken is not required for this addr, so permit it. */
04955    }
04956 
04957 reject:
04958    /* received frame has failed calltoken inspection, send apathetic reject messages */
04959    if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04960       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04961    } else {
04962       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04963    }
04964 
04965    return 1;
04966 }

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

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

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

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

Definition at line 3577 of file chan_iax2.c.

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

03578 {
03579    struct iax2_peer *peer = NULL;
03580    struct iax2_user *user = NULL;
03581    static const char * const choices[] = { "all", NULL };
03582    char *cmplt;
03583 
03584    switch (cmd) {
03585    case CLI_INIT:
03586       e->command = "iax2 prune realtime";
03587       e->usage =
03588          "Usage: iax2 prune realtime [<peername>|all]\n"
03589          "       Prunes object(s) from the cache\n";
03590       return NULL;
03591    case CLI_GENERATE:
03592       if (a->pos == 3) {
03593          cmplt = ast_cli_complete(a->word, choices, a->n);
03594          if (!cmplt)
03595             cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03596          return cmplt;
03597       }
03598       return NULL;
03599    }
03600    if (a->argc != 4)
03601       return CLI_SHOWUSAGE;
03602    if (!strcmp(a->argv[3], "all")) {
03603       prune_users();
03604       prune_peers();
03605       ast_cli(a->fd, "Cache flushed successfully.\n");
03606       return CLI_SUCCESS;
03607    }
03608    peer = find_peer(a->argv[3], 0);
03609    user = find_user(a->argv[3]);
03610    if (peer || user) {
03611       if (peer) {
03612          if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
03613             ast_set_flag64(peer, IAX_RTAUTOCLEAR);
03614             expire_registry(peer_ref(peer));
03615             ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03616          } else {
03617             ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03618          }
03619          peer_unref(peer);
03620       }
03621       if (user) {
03622          if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
03623             ast_set_flag64(user, IAX_RTAUTOCLEAR);
03624             ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03625          } else {
03626             ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03627          }
03628          ao2_unlink(users,user);
03629          user_unref(user);
03630       }
03631    } else {
03632       ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03633    }
03634 
03635    return CLI_SUCCESS;
03636 }

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

Definition at line 13646 of file chan_iax2.c.

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

13647 {
13648    switch (cmd) {
13649    case CLI_INIT:
13650       e->command = "iax2 reload";
13651       e->usage =
13652          "Usage: iax2 reload\n"
13653          "       Reloads IAX configuration from iax.conf\n";
13654       return NULL;
13655    case CLI_GENERATE:
13656       return NULL;
13657    }
13658 
13659    reload_config();
13660 
13661    return CLI_SUCCESS;
13662 }

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

Definition at line 7365 of file chan_iax2.c.

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

07366 {
07367    switch (cmd) {
07368    case CLI_INIT:
07369       e->command = "iax2 set debug {on|off|peer}";
07370       e->usage =
07371          "Usage: iax2 set debug {on|off|peer peername}\n"
07372          "       Enables/Disables dumping of IAX packets for debugging purposes.\n";
07373       return NULL;
07374    case CLI_GENERATE:
07375       if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07376          return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07377       return NULL;
07378    }
07379 
07380    if (a->argc < e->args  || a->argc > e->args + 1)
07381       return CLI_SHOWUSAGE;
07382 
07383    if (!strcasecmp(a->argv[3], "peer")) {
07384       struct iax2_peer *peer;
07385       struct sockaddr_in peer_addr;
07386 
07387 
07388       if (a->argc != e->args + 1)
07389          return CLI_SHOWUSAGE;
07390 
07391       peer = find_peer(a->argv[4], 1);
07392 
07393       if (!peer) {
07394          ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07395          return CLI_FAILURE;
07396       }
07397 
07398       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07399 
07400       debugaddr.sin_addr = peer_addr.sin_addr;
07401       debugaddr.sin_port = peer_addr.sin_port;
07402 
07403       ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07404          ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07405 
07406       ao2_ref(peer, -1);
07407    } else if (!strncasecmp(a->argv[3], "on", 2)) {
07408       iaxdebug = 1;
07409       ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07410    } else {
07411       iaxdebug = 0;
07412       memset(&debugaddr, 0, sizeof(debugaddr));
07413       ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07414    }
07415    return CLI_SUCCESS;
07416 }

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

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

07445 {
07446    switch (cmd) {
07447    case CLI_INIT:
07448       e->command = "iax2 set debug jb {on|off}";
07449       e->usage =
07450          "Usage: iax2 set debug jb {on|off}\n"
07451          "       Enables/Disables jitterbuffer debugging information\n";
07452       return NULL;
07453    case CLI_GENERATE:
07454       return NULL;
07455    }
07456 
07457    if (a->argc != e->args)
07458       return CLI_SHOWUSAGE;
07459    
07460    if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07461       jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07462       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07463    } else {
07464       jb_setoutput(jb_error_output, jb_warning_output, NULL);
07465       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07466    }
07467    return CLI_SUCCESS;
07468 }

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

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

07419 {
07420    switch (cmd) {
07421    case CLI_INIT:
07422       e->command = "iax2 set debug trunk {on|off}";
07423       e->usage =
07424          "Usage: iax2 set debug trunk {on|off}\n"
07425          "       Enables/Disables debugging of IAX trunking\n";
07426       return NULL;
07427    case CLI_GENERATE:
07428       return NULL;
07429    }
07430 
07431    if (a->argc != e->args)
07432       return CLI_SHOWUSAGE;
07433 
07434    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07435       iaxtrunkdebug = 1;
07436       ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07437    } else {
07438       iaxtrunkdebug = 0;
07439       ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07440    }
07441    return CLI_SUCCESS;
07442 }

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

03905 {
03906    int mtuv;
03907 
03908    switch (cmd) {
03909    case CLI_INIT:
03910       e->command = "iax2 set mtu";
03911       e->usage =
03912          "Usage: iax2 set mtu <value>\n"
03913          "       Set the system-wide IAX IP mtu to <value> bytes net or\n"
03914          "       zero to disable. Disabling means that the operating system\n"
03915          "       must handle fragmentation of UDP packets when the IAX2 trunk\n"
03916          "       packet exceeds the UDP payload size. This is substantially\n"
03917          "       below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03918          "       greater for G.711 samples.\n";
03919       return NULL;
03920    case CLI_GENERATE:
03921       return NULL;
03922    }
03923 
03924    if (a->argc != 4)
03925       return CLI_SHOWUSAGE; 
03926    if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03927       mtuv = MAX_TRUNK_MTU;
03928    else
03929       mtuv = atoi(a->argv[3]);
03930 
03931    if (mtuv == 0) {
03932       ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 
03933       global_max_trunk_mtu = 0; 
03934       return CLI_SUCCESS; 
03935    }
03936    if (mtuv < 172 || mtuv > 4000) {
03937       ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 
03938       return CLI_SHOWUSAGE; 
03939    }
03940    ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 
03941    global_max_trunk_mtu = mtuv; 
03942    return CLI_SUCCESS;
03943 }

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

Definition at line 3945 of file chan_iax2.c.

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

03946 {
03947    struct iax2_dpcache *dp = NULL;
03948    char tmp[1024], *pc = NULL;
03949    int s, x, y;
03950    struct timeval now = ast_tvnow();
03951 
03952    switch (cmd) {
03953    case CLI_INIT:
03954       e->command = "iax2 show cache";
03955       e->usage =
03956          "Usage: iax2 show cache\n"
03957          "       Display currently cached IAX Dialplan results.\n";
03958       return NULL;
03959    case CLI_GENERATE:
03960       return NULL;
03961    }
03962 
03963    AST_LIST_LOCK(&dpcache);
03964 
03965    ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03966 
03967    AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03968       s = dp->expiry.tv_sec - now.tv_sec;
03969       tmp[0] = '\0';
03970       if (dp->flags & CACHE_FLAG_EXISTS)
03971          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03972       if (dp->flags & CACHE_FLAG_NONEXISTENT)
03973          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03974       if (dp->flags & CACHE_FLAG_CANEXIST)
03975          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03976       if (dp->flags & CACHE_FLAG_PENDING)
03977          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03978       if (dp->flags & CACHE_FLAG_TIMEOUT)
03979          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03980       if (dp->flags & CACHE_FLAG_TRANSMITTED)
03981          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03982       if (dp->flags & CACHE_FLAG_MATCHMORE)
03983          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03984       if (dp->flags & CACHE_FLAG_UNKNOWN)
03985          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03986       /* Trim trailing pipe */
03987       if (!ast_strlen_zero(tmp)) {
03988          tmp[strlen(tmp) - 1] = '\0';
03989       } else {
03990          ast_copy_string(tmp, "(none)", sizeof(tmp));
03991       }
03992       y = 0;
03993       pc = strchr(dp->peercontext, '@');
03994       if (!pc) {
03995          pc = dp->peercontext;
03996       } else {
03997          pc++;
03998       }
03999       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
04000          if (dp->waiters[x] > -1)
04001             y++;
04002       }
04003       if (s > 0) {
04004          ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
04005       } else {
04006          ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
04007       }
04008    }
04009 
04010    AST_LIST_UNLOCK(&dpcache);
04011 
04012    return CLI_SUCCESS;
04013 }

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

Definition at line 2555 of file chan_iax2.c.

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

02556 {
02557    struct ao2_iterator i;
02558    struct peercnt *peercnt;
02559    struct sockaddr_in sin;
02560    int found = 0;
02561 
02562    switch (cmd) {
02563    case CLI_INIT:
02564       e->command = "iax2 show callnumber usage";
02565       e->usage =
02566          "Usage: iax2 show callnumber usage [IP address]\n"
02567          "       Shows current IP addresses which are consuming iax2 call numbers\n";
02568       return NULL;
02569    case CLI_GENERATE:
02570       return NULL;
02571    case CLI_HANDLER:
02572       if (a->argc < 4 || a->argc > 5)
02573          return CLI_SHOWUSAGE;
02574 
02575       if (a->argc == 4) {
02576          ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02577       }
02578 
02579       i = ao2_iterator_init(peercnts, 0);
02580       while ((peercnt = ao2_iterator_next(&i))) {
02581          sin.sin_addr.s_addr = peercnt->addr;
02582          if (a->argc == 5) {
02583             if (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr))) {
02584                ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02585                ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02586                ao2_ref(peercnt, -1);
02587                found = 1;
02588                break;
02589             }
02590          } else {
02591             ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02592          }
02593          ao2_ref(peercnt, -1);
02594       }
02595       ao2_iterator_destroy(&i);
02596 
02597       if (a->argc == 4) {
02598          ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
02599                           "Non-CallToken Validated Callno Used:   %d\n",
02600             global_maxcallno_nonval,
02601             total_nonval_callno_used);
02602 
02603          ast_cli(a->fd,   "Total Available Callno:                %d\n"
02604                           "Regular Callno Available:              %d\n"
02605                           "Trunk Callno Available:                %d\n",
02606             ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk),
02607             ao2_container_count(callno_pool),
02608             ao2_container_count(callno_pool_trunk));
02609       } else if (a->argc == 5 && !found) {
02610          ast_cli(a->fd, "No call number table entries for %s found\n", a->argv[4] );
02611       }
02612 
02613 
02614       return CLI_SUCCESS;
02615    default:
02616       return NULL;
02617    }
02618 }

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

Definition at line 7192 of file chan_iax2.c.

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

07193 {
07194 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s  %s  %9s\n"
07195 #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"
07196 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
07197    int x;
07198    int numchans = 0;
07199    char first_message[10] = { 0, };
07200    char last_message[10] = { 0, };
07201 
07202    switch (cmd) {
07203    case CLI_INIT:
07204       e->command = "iax2 show channels";
07205       e->usage =
07206          "Usage: iax2 show channels\n"
07207          "       Lists all currently active IAX channels.\n";
07208       return NULL;
07209    case CLI_GENERATE:
07210       return NULL;
07211    }
07212 
07213    if (a->argc != 3)
07214       return CLI_SHOWUSAGE;
07215    ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07216    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07217       ast_mutex_lock(&iaxsl[x]);
07218       if (iaxs[x]) {
07219          int lag, jitter, localdelay;
07220          jb_info jbinfo;
07221          if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07222             jb_getinfo(iaxs[x]->jb, &jbinfo);
07223             jitter = jbinfo.jitter;
07224             localdelay = jbinfo.current - jbinfo.min;
07225          } else {
07226             jitter = -1;
07227             localdelay = 0;
07228          }
07229 
07230          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07231          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07232          lag = iaxs[x]->remote_rr.delay;
07233          ast_cli(a->fd, FORMAT,
07234             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07235             ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07236             S_OR(iaxs[x]->username, "(None)"),
07237             iaxs[x]->callno, iaxs[x]->peercallno,
07238             iaxs[x]->oseqno, iaxs[x]->iseqno,
07239             lag,
07240             jitter,
07241             localdelay,
07242             ast_getformatname(iaxs[x]->voiceformat),
07243             (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07244             first_message,
07245             (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07246             last_message);
07247          numchans++;
07248       }
07249       ast_mutex_unlock(&iaxsl[x]);
07250    }
07251    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07252    return CLI_SUCCESS;
07253 #undef FORMAT
07254 #undef FORMAT2
07255 #undef FORMATB
07256 }

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

Definition at line 6978 of file chan_iax2.c.

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

06979 {
06980    struct iax_firmware *cur = NULL;
06981 
06982    switch (cmd) {
06983    case CLI_INIT:
06984       e->command = "iax2 show firmware";
06985       e->usage =
06986          "Usage: iax2 show firmware\n"
06987          "       Lists all known IAX firmware images.\n";
06988       return NULL;
06989    case CLI_GENERATE:
06990       return NULL;
06991    }
06992 
06993    if (a->argc != 3 && a->argc != 4)
06994       return CLI_SHOWUSAGE;
06995 
06996    ast_cli(a->fd, "%-15.15s  %-15.15s %-15.15s\n", "Device", "Version", "Size");
06997    AST_LIST_LOCK(&firmwares);
06998    AST_LIST_TRAVERSE(&firmwares, cur, list) {
06999       if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname)))  {
07000          ast_cli(a->fd, "%-15.15s  %-15d %-15d\n", cur->fwh->devname, 
07001             ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
07002       }
07003    }
07004    AST_LIST_UNLOCK(&firmwares);
07005 
07006    return CLI_SUCCESS;
07007 }

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

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

07343 {
07344    int numchans = 0;
07345 
07346    switch (cmd) {
07347    case CLI_INIT:
07348       e->command = "iax2 show netstats";
07349       e->usage =
07350          "Usage: iax2 show netstats\n"
07351          "       Lists network status for all currently active IAX channels.\n";
07352       return NULL;
07353    case CLI_GENERATE:
07354       return NULL;
07355    }
07356    if (a->argc != 3)
07357       return CLI_SHOWUSAGE;
07358    ast_cli(a->fd, "                           -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
07359    ast_cli(a->fd, "Channel               RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts FirstMsg    LastMsg\n");
07360    numchans = ast_cli_netstats(NULL, a->fd, 1);
07361    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07362    return CLI_SUCCESS;
07363 }

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

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

03753 {
03754    char status[30];
03755    char cbuf[256];
03756    struct iax2_peer *peer;
03757    char codec_buf[512];
03758    struct ast_str *encmethods = ast_str_alloca(256);
03759    int x = 0, codec = 0, load_realtime = 0;
03760 
03761    switch (cmd) {
03762    case CLI_INIT:
03763       e->command = "iax2 show peer";
03764       e->usage =
03765          "Usage: iax2 show peer <name>\n"
03766          "       Display details on specific IAX peer\n";
03767       return NULL;
03768    case CLI_GENERATE:
03769       if (a->pos == 3)
03770          return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03771       return NULL;
03772    }
03773 
03774    if (a->argc < 4)
03775       return CLI_SHOWUSAGE;
03776 
03777    load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03778 
03779    peer = find_peer(a->argv[3], load_realtime);
03780    if (peer) {
03781       struct sockaddr_in peer_addr;
03782 
03783       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
03784 
03785       encmethods_to_str(peer->encmethods, &encmethods);
03786       ast_cli(a->fd, "\n\n");
03787       ast_cli(a->fd, "  * Name       : %s\n", peer->name);
03788       ast_cli(a->fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03789       ast_cli(a->fd, "  Context      : %s\n", peer->context);
03790       ast_cli(a->fd, "  Parking lot  : %s\n", peer->parkinglot);
03791       ast_cli(a->fd, "  Mailbox      : %s\n", peer->mailbox);
03792       ast_cli(a->fd, "  Dynamic      : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
03793       ast_cli(a->fd, "  Callnum limit: %d\n", peer->maxcallno);
03794       ast_cli(a->fd, "  Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03795       ast_cli(a->fd, "  Trunk        : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
03796       ast_cli(a->fd, "  Encryption   : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03797       ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03798       ast_cli(a->fd, "  Expire       : %d\n", peer->expire);
03799       ast_cli(a->fd, "  ACL          : %s\n", (peer->ha ? "Yes" : "No"));
03800       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));
03801       ast_cli(a->fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03802       ast_cli(a->fd, "  Username     : %s\n", peer->username);
03803       ast_cli(a->fd, "  Codecs       : ");
03804       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03805       ast_cli(a->fd, "%s\n", codec_buf);
03806 
03807       ast_cli(a->fd, "  Codec Order  : (");
03808       for(x = 0; x < 32 ; x++) {
03809          codec = ast_codec_pref_index(&peer->prefs,x);
03810          if(!codec)
03811             break;
03812          ast_cli(a->fd, "%s", ast_getformatname(codec));
03813          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03814             ast_cli(a->fd, "|");
03815       }
03816 
03817       if (!x)
03818          ast_cli(a->fd, "none");
03819       ast_cli(a->fd, ")\n");
03820 
03821       ast_cli(a->fd, "  Status       : ");
03822       peer_status(peer, status, sizeof(status));   
03823       ast_cli(a->fd, "%s\n",status);
03824       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");
03825       ast_cli(a->fd, "\n");
03826       peer_unref(peer);
03827    } else {
03828       ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03829       ast_cli(a->fd, "\n");
03830    }
03831 
03832    return CLI_SUCCESS;
03833 }

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

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

06947 {
06948    switch (cmd) {
06949    case CLI_INIT:
06950       e->command = "iax2 show peers";
06951       e->usage =
06952          "Usage: iax2 show peers [registered] [like <pattern>]\n"
06953          "       Lists all known IAX2 peers.\n"
06954          "       Optional 'registered' argument lists only peers with known addresses.\n"
06955          "       Optional regular expression pattern is used to filter the peer list.\n";
06956       return NULL;
06957    case CLI_GENERATE:
06958       return NULL;
06959    }
06960 
06961    switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
06962    case RESULT_SHOWUSAGE:
06963       return CLI_SHOWUSAGE;
06964    case RESULT_FAILURE:
06965       return CLI_FAILURE;
06966    default:
06967       return CLI_SUCCESS;
06968    }
06969 }

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

Definition at line 7101 of file chan_iax2.c.

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

07102 {
07103 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
07104 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
07105    struct iax2_registry *reg = NULL;
07106    char host[80];
07107    char perceived[80];
07108    int counter = 0;
07109 
07110    switch (cmd) {
07111    case CLI_INIT:
07112       e->command = "iax2 show registry";
07113       e->usage =
07114          "Usage: iax2 show registry\n"
07115          "       Lists all registration requests and status.\n";
07116       return NULL;
07117    case CLI_GENERATE:
07118       return NULL;
07119    }
07120    if (a->argc != 3)
07121       return CLI_SHOWUSAGE;
07122    ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07123    AST_LIST_LOCK(&registrations);
07124    AST_LIST_TRAVERSE(&registrations, reg, entry) {
07125       snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
07126       if (reg->us.sin_addr.s_addr) 
07127          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07128       else
07129          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07130       ast_cli(a->fd, FORMAT, host, 
07131                (reg->dnsmgr) ? "Y" : "N", 
07132                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07133       counter++;
07134    }
07135    AST_LIST_UNLOCK(&registrations);
07136    ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07137    return CLI_SUCCESS;
07138 #undef FORMAT
07139 #undef FORMAT2
07140 }

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

Definition at line 3858 of file chan_iax2.c.

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

03859 {
03860    struct iax_frame *cur;
03861    int cnt = 0, dead = 0, final = 0, i = 0;
03862 
03863    switch (cmd) {
03864    case CLI_INIT:
03865       e->command = "iax2 show stats";
03866       e->usage =
03867          "Usage: iax2 show stats\n"
03868          "       Display statistics on IAX channel driver.\n";
03869       return NULL;
03870    case CLI_GENERATE:
03871       return NULL;
03872    }
03873 
03874    if (a->argc != 3)
03875       return CLI_SHOWUSAGE;
03876 
03877    for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
03878       ast_mutex_lock(&iaxsl[i]);
03879       AST_LIST_TRAVERSE(&frame_queue[i], cur, list) {
03880          if (cur->retries < 0)
03881             dead++;
03882          if (cur->final)
03883             final++;
03884          cnt++;
03885       }
03886       ast_mutex_unlock(&iaxsl[i]);
03887    }
03888 
03889    ast_cli(a->fd, "    IAX Statistics\n");
03890    ast_cli(a->fd, "---------------------\n");
03891    ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03892    ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03893       trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03894    ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03895 
03896    trunk_timed = trunk_untimed = 0;
03897    if (trunk_maxmtu > trunk_nmaxmtu)
03898       trunk_nmaxmtu = trunk_maxmtu;
03899 
03900    return CLI_SUCCESS;
03901 }

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

Definition at line 6808 of file chan_iax2.c.

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

06809 {
06810    struct iax2_thread *thread = NULL;
06811    time_t t;
06812    int threadcount = 0, dynamiccount = 0;
06813    char type;
06814 
06815    switch (cmd) {
06816    case CLI_INIT:
06817       e->command = "iax2 show threads";
06818       e->usage =
06819          "Usage: iax2 show threads\n"
06820          "       Lists status of IAX helper threads\n";
06821       return NULL;
06822    case CLI_GENERATE:
06823       return NULL;
06824    }
06825    if (a->argc != 3)
06826       return CLI_SHOWUSAGE;
06827       
06828    ast_cli(a->fd, "IAX2 Thread Information\n");
06829    time(&t);
06830    ast_cli(a->fd, "Idle Threads:\n");
06831    AST_LIST_LOCK(&idle_list);
06832    AST_LIST_TRAVERSE(&idle_list, thread, list) {
06833 #ifdef DEBUG_SCHED_MULTITHREAD
06834       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 
06835          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06836 #else
06837       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
06838          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06839 #endif
06840       threadcount++;
06841    }
06842    AST_LIST_UNLOCK(&idle_list);
06843    ast_cli(a->fd, "Active Threads:\n");
06844    AST_LIST_LOCK(&active_list);
06845    AST_LIST_TRAVERSE(&active_list, thread, list) {
06846       if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06847          type = 'D';
06848       else
06849          type = 'P';
06850 #ifdef DEBUG_SCHED_MULTITHREAD
06851       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 
06852          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06853 #else
06854       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
06855          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06856 #endif
06857       threadcount++;
06858    }
06859    AST_LIST_UNLOCK(&active_list);
06860    ast_cli(a->fd, "Dynamic Threads:\n");
06861    AST_LIST_LOCK(&dynamic_list);
06862    AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06863 #ifdef DEBUG_SCHED_MULTITHREAD
06864       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06865          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06866 #else
06867       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06868          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06869 #endif
06870       dynamiccount++;
06871    }
06872    AST_LIST_UNLOCK(&dynamic_list);
06873    ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06874    return CLI_SUCCESS;
06875 }

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

Definition at line 6599 of file chan_iax2.c.

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

06600 {
06601    regex_t regexbuf;
06602    int havepattern = 0;
06603 
06604 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
06605 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
06606 
06607    struct iax2_user *user = NULL;
06608    char auth[90];
06609    char *pstr = "";
06610    struct ao2_iterator i;
06611 
06612    switch (cmd) {
06613    case CLI_INIT:
06614       e->command = "iax2 show users [like]";
06615       e->usage =
06616          "Usage: iax2 show users [like <pattern>]\n"
06617          "       Lists all known IAX2 users.\n"
06618          "       Optional regular expression pattern is used to filter the user list.\n";
06619       return NULL;
06620    case CLI_GENERATE:
06621       return NULL;
06622    }
06623 
06624    switch (a->argc) {
06625    case 5:
06626       if (!strcasecmp(a->argv[3], "like")) {
06627          if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06628             return CLI_SHOWUSAGE;
06629          havepattern = 1;
06630       } else
06631          return CLI_SHOWUSAGE;
06632    case 3:
06633       break;
06634    default:
06635       return CLI_SHOWUSAGE;
06636    }
06637 
06638    ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06639    i = ao2_iterator_init(users, 0);
06640    for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
06641       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
06642          continue;
06643 
06644       if (!ast_strlen_zero(user->secret)) {
06645          ast_copy_string(auth,user->secret, sizeof(auth));
06646       } else if (!ast_strlen_zero(user->inkeys)) {
06647          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06648       } else
06649          ast_copy_string(auth, "-no secret-", sizeof(auth));
06650 
06651       if(ast_test_flag64(user, IAX_CODEC_NOCAP))
06652          pstr = "REQ Only";
06653       else if(ast_test_flag64(user, IAX_CODEC_NOPREFS))
06654          pstr = "Disabled";
06655       else
06656          pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06657 
06658       ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 
06659          user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06660          user->ha ? "Yes" : "No", pstr);
06661    }
06662    ao2_iterator_destroy(&i);
06663 
06664    if (havepattern)
06665       regfree(&regexbuf);
06666 
06667    return CLI_SUCCESS;
06668 #undef FORMAT
06669 #undef FORMAT2
06670 }

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

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

03639 {
03640    switch (cmd) {
03641    case CLI_INIT:
03642       e->command = "iax2 test losspct";
03643       e->usage =
03644          "Usage: iax2 test losspct <percentage>\n"
03645          "       For testing, throws away <percentage> percent of incoming packets\n";
03646       return NULL;
03647    case CLI_GENERATE:
03648       return NULL;
03649    }
03650    if (a->argc != 4)
03651       return CLI_SHOWUSAGE;
03652 
03653    test_losspct = atoi(a->argv[3]);
03654 
03655    return CLI_SUCCESS;
03656 }

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

Definition at line 6877 of file chan_iax2.c.

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

06878 {
06879    struct iax2_peer *p;
06880 
06881    switch (cmd) {
06882    case CLI_INIT:
06883       e->command = "iax2 unregister";
06884       e->usage =
06885          "Usage: iax2 unregister <peername>\n"
06886          "       Unregister (force expiration) an IAX2 peer from the registry.\n";
06887       return NULL;
06888    case CLI_GENERATE:
06889       return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06890    }
06891 
06892    if (a->argc != 3)
06893       return CLI_SHOWUSAGE;
06894 
06895    p = find_peer(a->argv[2], 1);
06896    if (p) {
06897       if (p->expire > 0) {
06898          struct iax2_peer tmp_peer = {
06899             .name = a->argv[2],
06900          };
06901          struct iax2_peer *peer;
06902 
06903          peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06904          if (peer) {
06905             expire_registry(peer_ref(peer)); /* will release its own reference when done */
06906             peer_unref(peer); /* ref from ao2_find() */
06907             ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06908          } else {
06909             ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06910          }
06911       } else {
06912          ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06913       }
06914       peer_unref(p);
06915    } else {
06916       ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06917    }
06918    return CLI_SUCCESS;
06919 }

static void handle_deferred_full_frames ( struct iax2_thread thread  )  [static]

Handle any deferred full frames for this thread.

Definition at line 9576 of file chan_iax2.c.

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

Referenced by iax2_process_thread().

09577 {
09578    struct iax2_pkt_buf *pkt_buf;
09579 
09580    ast_mutex_lock(&thread->lock);
09581 
09582    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09583       ast_mutex_unlock(&thread->lock);
09584 
09585       thread->buf = pkt_buf->buf;
09586       thread->buf_len = pkt_buf->len;
09587       thread->buf_size = pkt_buf->len + 1;
09588       
09589       socket_process(thread);
09590 
09591       thread->buf = NULL;
09592       ast_free(pkt_buf);
09593 
09594       ast_mutex_lock(&thread->lock);
09595    }
09596 
09597    ast_mutex_unlock(&thread->lock);
09598 }

static int handle_error ( void   )  [static]

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

03289 {
03290    /* XXX Ideally we should figure out why an error occurred and then abort those
03291       rather than continuing to try.  Unfortunately, the published interface does
03292       not seem to work XXX */
03293 #if 0
03294    struct sockaddr_in *sin;
03295    int res;
03296    struct msghdr m;
03297    struct sock_extended_err e;
03298    m.msg_name = NULL;
03299    m.msg_namelen = 0;
03300    m.msg_iov = NULL;
03301    m.msg_control = &e;
03302    m.msg_controllen = sizeof(e);
03303    m.msg_flags = 0;
03304    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03305    if (res < 0)
03306       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03307    else {
03308       if (m.msg_controllen) {
03309          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03310          if (sin) 
03311             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03312          else
03313             ast_log(LOG_WARNING, "No address detected??\n");
03314       } else {
03315          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03316       }
03317    }
03318 #endif
03319    return 0;
03320 }

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

Acknowledgment received for OUR registration.

Definition at line 8467 of file chan_iax2.c.

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

Referenced by socket_process().

08468 {
08469    struct iax2_registry *reg;
08470    /* Start pessimistic */
08471    char peer[256] = "";
08472    char msgstatus[60];
08473    int refresh = 60;
08474    char ourip[256] = "<Unspecified>";
08475    struct sockaddr_in oldus;
08476    struct sockaddr_in us;
08477    int oldmsgs;
08478    struct sockaddr_in reg_addr;
08479 
08480    memset(&us, 0, sizeof(us));
08481    if (ies->apparent_addr) {
08482       memmove(&us, ies->apparent_addr, sizeof(us));
08483    }
08484    if (ies->username) {
08485       ast_copy_string(peer, ies->username, sizeof(peer));
08486    }
08487    if (ies->refresh) {
08488       refresh = ies->refresh;
08489    }
08490    if (ies->calling_number) {
08491       /* We don't do anything with it really, but maybe we should */
08492    }
08493    reg = iaxs[callno]->reg;
08494    if (!reg) {
08495       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08496       return -1;
08497    }
08498    memcpy(&oldus, &reg->us, sizeof(oldus));
08499    oldmsgs = reg->messages;
08500    ast_sockaddr_to_sin(&reg->addr, &reg_addr);
08501    if (inaddrcmp(&reg_addr, sin)) {
08502       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08503       return -1;
08504    }
08505    memcpy(&reg->us, &us, sizeof(reg->us));
08506    if (ies->msgcount >= 0) {
08507       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
08508    }
08509    /* always refresh the registration at the interval requested by the server
08510       we are registering to
08511    */
08512    reg->refresh = refresh;
08513    reg->expire = iax2_sched_replace(reg->expire, sched,
08514       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08515    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
08516       if (reg->messages > 255) {
08517          snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08518       } else if (reg->messages > 1) {
08519          snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
08520       } else if (reg->messages > 0) {
08521          ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
08522       } else {
08523          ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
08524       }
08525       snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08526       ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08527       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08528    }
08529    reg->regstate = REG_STATE_REGISTERED;
08530    return 0;
08531 }

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

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

02757 {
02758    if (frametype != AST_FRAME_IAX) {
02759       return 0;
02760    }
02761    switch (subclass) {
02762    case IAX_COMMAND_NEW:
02763    case IAX_COMMAND_REGREQ:
02764    case IAX_COMMAND_FWDOWNL:
02765    case IAX_COMMAND_REGREL:
02766       return 1;
02767    case IAX_COMMAND_POKE:
02768       if (!inbound) {
02769          return 1;
02770       }
02771       break;
02772    }
02773    return 0;
02774 }

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

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

Referenced by ast_iax2_new(), and iax2_answer().

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

static int iax2_answer ( struct ast_channel c  )  [static]

Definition at line 5649 of file chan_iax2.c.

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

05650 {
05651    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05652    ast_debug(1, "Answering IAX2 call\n");
05653    ast_mutex_lock(&iaxsl[callno]);
05654    if (iaxs[callno])
05655       iax2_ami_channelupdate(iaxs[callno]);
05656    ast_mutex_unlock(&iaxsl[callno]);
05657    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05658 }

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

Definition at line 8533 of file chan_iax2.c.

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

Referenced by iax2_register().

08535 {
08536    struct iax2_registry *reg;
08537 
08538    if (!(reg = ast_calloc(1, sizeof(*reg))))
08539       return -1;
08540 
08541    reg->addr.ss.ss_family = AF_INET;
08542    if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08543       ast_free(reg);
08544       return -1;
08545    }
08546 
08547    ast_copy_string(reg->username, username, sizeof(reg->username));
08548 
08549    if (secret)
08550       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08551 
08552    reg->expire = -1;
08553    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08554    ast_sockaddr_set_port(&reg->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08555 
08556    AST_LIST_LOCK(&registrations);
08557    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
08558    AST_LIST_UNLOCK(&registrations);
08559    
08560    return 0;
08561 }

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

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

05479 {
05480    struct ast_channel *cs[3];
05481    struct ast_channel *who, *other;
05482    int to = -1;
05483    int res = -1;
05484    int transferstarted=0;
05485    struct ast_frame *f;
05486    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05487    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05488    struct timeval waittimer = {0, 0};
05489 
05490    /* We currently do not support native bridging if a timeoutms value has been provided */
05491    if (timeoutms > 0) {
05492       return AST_BRIDGE_FAILED;
05493    }
05494 
05495    timeoutms = -1;
05496 
05497    lock_both(callno0, callno1);
05498    if (!iaxs[callno0] || !iaxs[callno1]) {
05499       unlock_both(callno0, callno1);
05500       return AST_BRIDGE_FAILED;
05501    }
05502    /* Put them in native bridge mode */
05503    if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05504       iaxs[callno0]->bridgecallno = callno1;
05505       iaxs[callno1]->bridgecallno = callno0;
05506    }
05507    unlock_both(callno0, callno1);
05508 
05509    /* If not, try to bridge until we can execute a transfer, if we can */
05510    cs[0] = c0;
05511    cs[1] = c1;
05512    for (/* ever */;;) {
05513       /* Check in case we got masqueraded into */
05514       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05515          ast_verb(3, "Can't masquerade, we're different...\n");
05516          /* Remove from native mode */
05517          if (c0->tech == &iax2_tech) {
05518             ast_mutex_lock(&iaxsl[callno0]);
05519             iaxs[callno0]->bridgecallno = 0;
05520             ast_mutex_unlock(&iaxsl[callno0]);
05521          }
05522          if (c1->tech == &iax2_tech) {
05523             ast_mutex_lock(&iaxsl[callno1]);
05524             iaxs[callno1]->bridgecallno = 0;
05525             ast_mutex_unlock(&iaxsl[callno1]);
05526          }
05527          return AST_BRIDGE_FAILED_NOWARN;
05528       }
05529       if (c0->nativeformats != c1->nativeformats) {
05530          char buf0[256];
05531          char buf1[256];
05532          ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05533          ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05534          ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05535          /* Remove from native mode */
05536          lock_both(callno0, callno1);
05537          if (iaxs[callno0])
05538             iaxs[callno0]->bridgecallno = 0;
05539          if (iaxs[callno1])
05540             iaxs[callno1]->bridgecallno = 0;
05541          unlock_both(callno0, callno1);
05542          return AST_BRIDGE_FAILED_NOWARN;
05543       }
05544       /* check if transfered and if we really want native bridging */
05545       if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05546          /* Try the transfer */
05547          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05548                      ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05549             ast_log(LOG_WARNING, "Unable to start the transfer\n");
05550          transferstarted = 1;
05551       }
05552       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05553          /* Call has been transferred.  We're no longer involved */
05554          struct timeval now = ast_tvnow();
05555          if (ast_tvzero(waittimer)) {
05556             waittimer = now;
05557          } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05558             c0->_softhangup |= AST_SOFTHANGUP_DEV;
05559             c1->_softhangup |= AST_SOFTHANGUP_DEV;
05560             *fo = NULL;
05561             *rc = c0;
05562             res = AST_BRIDGE_COMPLETE;
05563             break;
05564          }
05565       }
05566       to = 1000;
05567       who = ast_waitfor_n(cs, 2, &to);
05568       /* XXX This will need to be updated to calculate
05569        * timeout correctly once timeoutms is allowed to be
05570        * > 0. Right now, this can go badly if the waitfor
05571        * times out in less than a millisecond
05572        */
05573       if (timeoutms > -1) {
05574          timeoutms -= (1000 - to);
05575          if (timeoutms < 0)
05576             timeoutms = 0;
05577       }
05578       if (!who) {
05579          if (!timeoutms) {
05580             res = AST_BRIDGE_RETRY;
05581             break;
05582          }
05583          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05584             res = AST_BRIDGE_FAILED;
05585             break;
05586          }
05587          continue;
05588       }
05589       f = ast_read(who);
05590       if (!f) {
05591          *fo = NULL;
05592          *rc = who;
05593          res = AST_BRIDGE_COMPLETE;
05594          break;
05595       }
05596       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
05597       if (f->frametype == AST_FRAME_CONTROL && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
05598          switch (f->subclass.integer) {
05599          case AST_CONTROL_VIDUPDATE:
05600          case AST_CONTROL_SRCUPDATE:
05601          case AST_CONTROL_SRCCHANGE:
05602          case AST_CONTROL_T38_PARAMETERS:
05603             ast_write(other, f);
05604             break;
05605          default:
05606             *fo = f;
05607             *rc = who;
05608             res = AST_BRIDGE_COMPLETE;
05609             break;
05610          }
05611          if (res == AST_BRIDGE_COMPLETE) {
05612             break;
05613          }
05614       } else if (f->frametype == AST_FRAME_VOICE
05615          || f->frametype == AST_FRAME_TEXT
05616          || f->frametype == AST_FRAME_VIDEO
05617          || f->frametype == AST_FRAME_IMAGE) {
05618          ast_write(other, f);
05619       } else if (f->frametype == AST_FRAME_DTMF) {
05620          /* monitored dtmf take out of the bridge.
05621           * check if we monitor the specific source.
05622           */
05623          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05624 
05625          if (flags & monitored_source) {
05626             *rc = who;
05627             *fo = f;
05628             res = AST_BRIDGE_COMPLETE;
05629             /* Remove from native mode */
05630             break;
05631          }
05632          ast_write(other, f);
05633       }
05634       ast_frfree(f);
05635       /* Swap who gets priority */
05636       cs[2] = cs[0];
05637       cs[0] = cs[1];
05638       cs[1] = cs[2];
05639    }
05640    lock_both(callno0, callno1);
05641    if(iaxs[callno0])
05642       iaxs[callno0]->bridgecallno = 0;
05643    if(iaxs[callno1])
05644       iaxs[callno1]->bridgecallno = 0;
05645    unlock_both(callno0, callno1);
05646    return res;
05647 }

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

Definition at line 5026 of file chan_iax2.c.

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

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

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

13899 {
13900    int res = 0;
13901    struct iax2_dpcache *dp = NULL;
13902 #if 0
13903    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13904 #endif
13905    if ((priority != 1) && (priority != 2))
13906       return 0;
13907 
13908    AST_LIST_LOCK(&dpcache);
13909    if ((dp = find_cache(chan, data, context, exten, priority))) {
13910       if (dp->flags & CACHE_FLAG_CANEXIST)
13911          res = 1;
13912    } else {
13913       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13914    }
13915    AST_LIST_UNLOCK(&dpcache);
13916 
13917    return res;
13918 }

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

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

04698 {
04699    struct timeval t = ast_tvnow();
04700    struct ast_tm tm;
04701    unsigned int tmp;
04702    ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04703    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
04704    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
04705    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
04706    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
04707    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
04708    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
04709    return tmp;
04710 }

static void iax2_destroy ( int  callno  )  [static]

Definition at line 3392 of file chan_iax2.c.

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

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

03393 {
03394    struct chan_iax2_pvt *pvt = NULL;
03395    struct ast_channel *owner = NULL;
03396 
03397 retry:
03398    if ((pvt = iaxs[callno])) {
03399 #if 0
03400       /* iax2_destroy_helper gets called from this function later on.  When
03401        * called twice, we get the (previously) familiar FRACK! errors in
03402        * devmode, from the scheduler.  An alternative to this approach is to
03403        * reset the scheduler entries to -1 when they're deleted in
03404        * iax2_destroy_helper().  That approach was previously decided to be
03405        * "wrong" because "the memory is going to be deallocated anyway.  Why
03406        * should we be resetting those values?" */
03407       iax2_destroy_helper(pvt);
03408 #endif
03409    }
03410 
03411    owner = pvt ? pvt->owner : NULL;
03412 
03413    if (owner) {
03414       if (ast_channel_trylock(owner)) {
03415          ast_debug(3, "Avoiding IAX destroy deadlock\n");
03416          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03417          goto retry;
03418       }
03419    }
03420 
03421    if (!owner) {
03422       iaxs[callno] = NULL;
03423    }
03424 
03425    if (pvt) {
03426       if (!owner) {
03427          pvt->owner = NULL;
03428       } else {
03429          /* If there's an owner, prod it to give up */
03430          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
03431           * because we already hold the owner channel lock. */
03432          ast_queue_hangup(owner);
03433       }
03434 
03435       if (pvt->peercallno) {
03436          remove_by_peercallno(pvt);
03437       }
03438 
03439       if (pvt->transfercallno) {
03440          remove_by_transfercallno(pvt);
03441       }
03442 
03443       if (!owner) {
03444          ao2_ref(pvt, -1);
03445          pvt = NULL;
03446       }
03447    }
03448 
03449    if (owner) {
03450       ast_channel_unlock(owner);
03451    }
03452 
03453    if (callno & TRUNK_CALL_START) {
03454       update_max_trunk();
03455    }
03456 }

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

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

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

01772 {
01773    /* Decrement AUTHREQ count if needed */
01774    if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) {
01775       struct iax2_user *user;
01776       struct iax2_user tmp_user = {
01777          .name = pvt->username,
01778       };
01779 
01780       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01781       if (user) {
01782          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01783          user_unref(user);
01784       }
01785 
01786       ast_clear_flag64(pvt, IAX_MAXAUTHREQ);
01787    }
01788    /* No more pings or lagrq's */
01789    AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]);
01790    pvt->pingid = DONT_RESCHEDULE;
01791    AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]);
01792    pvt->lagid = DONT_RESCHEDULE;
01793    ast_sched_thread_del(sched, pvt->autoid);
01794    ast_sched_thread_del(sched, pvt->authid);
01795    ast_sched_thread_del(sched, pvt->initid);
01796    ast_sched_thread_del(sched, pvt->jbid);
01797    ast_sched_thread_del(sched, pvt->keyrotateid);
01798 }

static int iax2_devicestate ( void *  data  )  [static]

Part of the device state notification system ---.

Definition at line 14104 of file chan_iax2.c.

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

14105 {
14106    struct parsed_dial_string pds;
14107    char *tmp = ast_strdupa(data);
14108    struct iax2_peer *p;
14109    int res = AST_DEVICE_INVALID;
14110 
14111    memset(&pds, 0, sizeof(pds));
14112    parse_dial_string(tmp, &pds);
14113 
14114    if (ast_strlen_zero(pds.peer)) {
14115       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
14116       return res;
14117    }
14118    
14119    ast_debug(3, "Checking device state for device %s\n", pds.peer);
14120 
14121    /* SLD: FIXME: second call to find_peer during registration */
14122    if (!(p = find_peer(pds.peer, 1)))
14123       return res;
14124 
14125    res = AST_DEVICE_UNAVAILABLE;
14126    ast_debug(3, "Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
14127       pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
14128    
14129    if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
14130        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
14131       /* Peer is registered, or have default IP address
14132          and a valid registration */
14133       if (p->historicms == 0 || p->historicms <= p->maxms)
14134          /* let the core figure out whether it is in use or not */
14135          res = AST_DEVICE_UNKNOWN;  
14136    }
14137 
14138    peer_unref(p);
14139 
14140    return res;
14141 }

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

Definition at line 4298 of file chan_iax2.c.

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

04299 {
04300    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04301 }

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

Definition at line 4303 of file chan_iax2.c.

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

04304 {
04305    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04306 }

static int iax2_do_register ( struct iax2_registry reg  )  [static]

Definition at line 11879 of file chan_iax2.c.

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

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

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

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

Definition at line 8315 of file chan_iax2.c.

References __iax2_do_register_s(), and schedule_action.

Referenced by iax2_ack_registry(), and iax2_do_register().

08316 {
08317 #ifdef SCHED_MULTITHREADED
08318    if (schedule_action(__iax2_do_register_s, data))
08319 #endif      
08320       __iax2_do_register_s(data);
08321    return 0;
08322 }

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

Definition at line 9091 of file chan_iax2.c.

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

Referenced by find_cache(), and socket_process().

09092 {
09093    struct iax_ie_data ied;
09094    /* Auto-hangup with 30 seconds of inactivity */
09095    iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
09096       sched, 30000, auto_hangup, (void *)(long)callno);
09097    memset(&ied, 0, sizeof(ied));
09098    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09099    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09100    dp->flags |= CACHE_FLAG_TRANSMITTED;
09101 }

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

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

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

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

13945 {
13946    char odata[256];
13947    char req[256];
13948    char *ncontext;
13949    struct iax2_dpcache *dp = NULL;
13950    struct ast_app *dial = NULL;
13951 #if 0
13952    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);
13953 #endif
13954    if (priority == 2) {
13955       /* Indicate status, can be overridden in dialplan */
13956       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13957       if (dialstatus) {
13958          dial = pbx_findapp(dialstatus);
13959          if (dial) 
13960             pbx_exec(chan, dial, "");
13961       }
13962       return -1;
13963    } else if (priority != 1)
13964       return -1;
13965 
13966    AST_LIST_LOCK(&dpcache);
13967    if ((dp = find_cache(chan, data, context, exten, priority))) {
13968       if (dp->flags & CACHE_FLAG_EXISTS) {
13969          ast_copy_string(odata, data, sizeof(odata));
13970          ncontext = strchr(odata, '/');
13971          if (ncontext) {
13972             *ncontext = '\0';
13973             ncontext++;
13974             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13975          } else {
13976             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13977          }
13978          ast_verb(3, "Executing Dial('%s')\n", req);
13979       } else {
13980          AST_LIST_UNLOCK(&dpcache);
13981          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13982          return -1;
13983       }
13984    }
13985    AST_LIST_UNLOCK(&dpcache);
13986 
13987    if ((dial = pbx_findapp("Dial")))
13988       return pbx_exec(chan, dial, req);
13989    else
13990       ast_log(LOG_WARNING, "No dial application registered\n");
13991 
13992    return -1;
13993 }

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

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

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

Definition at line 4325 of file chan_iax2.c.

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

04326 {
04327    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04328    ast_mutex_lock(&iaxsl[callno]);
04329    if (iaxs[callno])
04330       iaxs[callno]->owner = newchan;
04331    else
04332       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04333    ast_mutex_unlock(&iaxsl[callno]);
04334    return 0;
04335 }

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

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

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

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

Definition at line 1734 of file chan_iax2.c.

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

Referenced by __find_callno().

01735 {
01736    struct iax2_peer *peer = NULL;
01737    int res = 0;
01738    struct ao2_iterator i;
01739 
01740    i = ao2_iterator_init(peers, 0);
01741    while ((peer = ao2_iterator_next(&i))) {
01742       struct sockaddr_in peer_addr;
01743 
01744       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
01745 
01746       if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01747           (peer_addr.sin_port == sin.sin_port)) {
01748          ast_copy_string(host, peer->name, len);
01749          peer_unref(peer);
01750          res = 1;
01751          break;
01752       }
01753       peer_unref(peer);
01754    }
01755    ao2_iterator_destroy(&i);
01756 
01757    if (!peer) {
01758       peer = realtime_peer(NULL, &sin);
01759       if (peer) {
01760          ast_copy_string(host, peer->name, len);
01761          peer_unref(peer);
01762          res = 1;
01763       }
01764    }
01765 
01766    return res;
01767 }

static int iax2_getpeertrunk ( struct sockaddr_in  sin  )  [static]

Definition at line 5724 of file chan_iax2.c.

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

Referenced by check_access().

05725 {
05726    struct iax2_peer *peer;
05727    int res = 0;
05728    struct ao2_iterator i;
05729 
05730    i = ao2_iterator_init(peers, 0);
05731    while ((peer = ao2_iterator_next(&i))) {
05732       struct sockaddr_in peer_addr;
05733 
05734       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05735 
05736       if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05737           (peer_addr.sin_port == sin.sin_port)) {
05738          res = ast_test_flag64(peer, IAX_TRUNK);
05739          peer_unref(peer);
05740          break;
05741       }
05742       peer_unref(peer);
05743    }
05744    ao2_iterator_destroy(&i);
05745 
05746    return res;
05747 }

static int iax2_hangup ( struct ast_channel c  )  [static]

Definition at line 5234 of file chan_iax2.c.

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

05235 {
05236    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05237    struct iax_ie_data ied;
05238    int alreadygone;
05239    memset(&ied, 0, sizeof(ied));
05240    ast_mutex_lock(&iaxsl[callno]);
05241    if (callno && iaxs[callno]) {
05242       ast_debug(1, "We're hanging up %s now...\n", c->name);
05243       alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
05244       /* Send the hangup unless we have had a transmission error or are already gone */
05245       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05246       if (!iaxs[callno]->error && !alreadygone) {
05247          if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05248             ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05249          }
05250          if (!iaxs[callno]) {
05251             ast_mutex_unlock(&iaxsl[callno]);
05252             return 0;
05253          }
05254       }
05255       /* Explicitly predestroy it */
05256       iax2_predestroy(callno);
05257       /* If we were already gone to begin with, destroy us now */
05258       if (iaxs[callno] && alreadygone) {
05259          ast_debug(1, "Really destroying %s now...\n", c->name);
05260          iax2_destroy(callno);
05261       } else if (iaxs[callno]) {
05262          if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05263             ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!!  Destroying immediately.\n", callno);
05264             iax2_destroy(callno);
05265          }
05266       }
05267    } else if (c->tech_pvt) {
05268       /* If this call no longer exists, but the channel still
05269        * references it we need to set the channel's tech_pvt to null
05270        * to avoid ast_channel_free() trying to free it.
05271        */
05272       c->tech_pvt = NULL;
05273    }
05274    ast_mutex_unlock(&iaxsl[callno]);
05275    ast_verb(3, "Hungup '%s'\n", c->name);
05276    return 0;
05277 }

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

Definition at line 5660 of file chan_iax2.c.

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

05661 {
05662    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05663    struct chan_iax2_pvt *pvt;
05664    int res = 0;
05665 
05666    if (iaxdebug)
05667       ast_debug(1, "Indicating condition %d\n", condition);
05668 
05669    ast_mutex_lock(&iaxsl[callno]);
05670    pvt = iaxs[callno];
05671 
05672    if (wait_for_peercallno(pvt)) {
05673       res = -1;
05674       goto done;
05675    }
05676 
05677    switch (condition) {
05678    case AST_CONTROL_HOLD:
05679       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05680          ast_moh_start(c, data, pvt->mohinterpret);
05681          goto done;
05682       }
05683       break;
05684    case AST_CONTROL_UNHOLD:
05685       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05686          ast_moh_stop(c);
05687          goto done;
05688       }
05689       break;
05690    case AST_CONTROL_CONNECTED_LINE:
05691       if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
05692          goto done;
05693       break;
05694    }
05695 
05696    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05697 
05698 done:
05699    ast_mutex_unlock(&iaxsl[callno]);
05700 
05701    return res;
05702 }

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

Definition at line 5396 of file chan_iax2.c.

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

Referenced by iax2_send().

05397 {
05398    int res = 0;
05399    struct chan_iax2_pvt *pvt = (void *) vpvt;
05400    struct MD5Context md5;
05401    char key[17] = "";
05402    struct iax_ie_data ied = {
05403       .pos = 0,   
05404    };
05405    
05406    ast_mutex_lock(&iaxsl[pvt->callno]);
05407    pvt->keyrotateid = 
05408       ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05409 
05410    snprintf(key, sizeof(key), "%lX", ast_random());
05411 
05412    MD5Init(&md5);
05413    MD5Update(&md5, (unsigned char *) key, strlen(key));
05414    MD5Final((unsigned char *) key, &md5);
05415 
05416    IAX_DEBUGDIGEST("Sending", key);
05417 
05418    iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05419 
05420    res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05421 
05422    build_ecx_key((unsigned char *) key, pvt);
05423 
05424    ast_mutex_unlock(&iaxsl[pvt->callno]);
05425 
05426    return res;
05427 }

static void iax2_lock_owner ( int  callno  )  [static]

Definition at line 1260 of file chan_iax2.c.

References ast_channel_trylock, DEADLOCK_AVOIDANCE, iaxs, and iaxsl.

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

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

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

Part of the IAX2 Switch interface.

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

13922 {
13923    int res = 0;
13924    struct iax2_dpcache *dp = NULL;
13925 #if 0
13926    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13927 #endif
13928    if ((priority != 1) && (priority != 2))
13929       return 0;
13930 
13931    AST_LIST_LOCK(&dpcache);
13932    if ((dp = find_cache(chan, data, context, exten, priority))) {
13933       if (dp->flags & CACHE_FLAG_MATCHMORE)
13934          res = 1;
13935    } else {
13936       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13937    }
13938    AST_LIST_UNLOCK(&dpcache);
13939 
13940    return res;
13941 }

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

Definition at line 12083 of file chan_iax2.c.

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

Referenced by iax2_poke_peer().

12084 {
12085    struct iax2_peer *peer = (struct iax2_peer *)data;
12086    peer->pokeexpire = -1;
12087 #ifdef SCHED_MULTITHREADED
12088    if (schedule_action(__iax2_poke_noanswer, data))
12089 #endif      
12090       __iax2_poke_noanswer(data);
12091    peer_unref(peer);
12092    return 0;
12093 }

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

Definition at line 12104 of file chan_iax2.c.

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

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

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

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

Definition at line 12095 of file chan_iax2.c.

References iax2_poke_peer().

Referenced by load_module().

12096 {
12097    struct iax2_peer *peer = obj;
12098 
12099    iax2_poke_peer(peer, 0);
12100 
12101    return 0;
12102 }

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

Definition at line 9128 of file chan_iax2.c.

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

Referenced by __iax2_poke_noanswer(), and socket_process().

09129 {
09130    struct iax2_peer *peer = (struct iax2_peer *)data;
09131    peer->pokeexpire = -1;
09132 #ifdef SCHED_MULTITHREADED
09133    if (schedule_action(__iax2_poke_peer_s, data))
09134 #endif      
09135       __iax2_poke_peer_s(data);
09136    return 0;
09137 }

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

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

Referenced by iax2_hangup(), and send_command_final().

03370 {
03371    struct ast_channel *c = NULL;
03372    struct chan_iax2_pvt *pvt = iaxs[callno];
03373 
03374    if (!pvt)
03375       return -1;
03376 
03377    if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
03378       iax2_destroy_helper(pvt);
03379       ast_set_flag64(pvt, IAX_ALREADYGONE);
03380    }
03381 
03382    if ((c = pvt->owner)) {
03383       c->tech_pvt = NULL;
03384       iax2_queue_hangup(callno);
03385       pvt->owner = NULL;
03386       ast_module_unref(ast_module_info->self);
03387    }
03388 
03389    return 0;
03390 }

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

References ast_atomic_fetchadd_int(), ast_cond_timedwait, ast_cond_wait, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), handle_deferred_full_frames(), iax2_process_thread_cleanup(), IAX_IOSTATE_IDLE, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_READY, IAX_IOSTATE_SCHEDREADY, IAX_THREAD_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), signal_condition(), socket_process(), and thread.

Referenced by find_idle_thread(), and start_network_thread().

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

static void iax2_process_thread_cleanup ( void *  data  )  [static]

Definition at line 11721 of file chan_iax2.c.

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

Referenced by iax2_process_thread().

11722 {
11723    struct iax2_thread *thread = data;
11724    ast_mutex_destroy(&thread->lock);
11725    ast_cond_destroy(&thread->cond);
11726    ast_mutex_destroy(&thread->init_lock);
11727    ast_cond_destroy(&thread->init_cond);
11728    ast_free(thread);
11729    /* Ignore check_return warning from Coverity for ast_atomic_dec_and_test below */
11730    ast_atomic_dec_and_test(&iaxactivethreadcount);
11731 }

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

Definition at line 11940 of file chan_iax2.c.

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

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

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

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

Definition at line 5373 of file chan_iax2.c.

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

05374 {
05375    switch (option) {
05376    case AST_OPTION_SECURE_SIGNALING:
05377    case AST_OPTION_SECURE_MEDIA:
05378    {
05379       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05380       ast_mutex_lock(&iaxsl[callno]);
05381       *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05382       ast_mutex_unlock(&iaxsl[callno]);
05383       return 0;
05384    }
05385    default:
05386       return -1;
05387    }
05388 }

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

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

Referenced by socket_process().

03009 {
03010    iax2_lock_owner(callno);
03011    if (iaxs[callno] && iaxs[callno]->owner) {
03012       ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
03013       ast_channel_unlock(iaxs[callno]->owner);
03014    }
03015    return 0;
03016 }

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

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

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

02962 {
02963    iax2_lock_owner(callno);
02964    if (iaxs[callno] && iaxs[callno]->owner) {
02965       ast_queue_frame(iaxs[callno]->owner, f);
02966       ast_channel_unlock(iaxs[callno]->owner);
02967    }
02968    return 0;
02969 }

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

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

Referenced by iax2_predestroy().

02985 {
02986    iax2_lock_owner(callno);
02987    if (iaxs[callno] && iaxs[callno]->owner) {
02988       ast_queue_hangup(iaxs[callno]->owner);
02989       ast_channel_unlock(iaxs[callno]->owner);
02990    }
02991    return 0;
02992 }

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

Definition at line 5390 of file chan_iax2.c.

References ast_debug, and ast_null_frame.

05391 {
05392    ast_debug(1, "I should never be called!\n");
05393    return &ast_null_frame;
05394 }

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

Definition at line 8563 of file chan_iax2.c.

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

Referenced by set_config().

08564 {
08565    char copy[256];
08566    char *username, *hostname, *secret;
08567    char *porta;
08568    char *stringp=NULL;
08569    
08570    if (!value)
08571       return -1;
08572 
08573    ast_copy_string(copy, value, sizeof(copy));
08574    stringp = copy;
08575    username = strsep(&stringp, "@");
08576    hostname = strsep(&stringp, "@");
08577 
08578    if (!hostname) {
08579       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08580       return -1;
08581    }
08582 
08583    stringp = username;
08584    username = strsep(&stringp, ":");
08585    secret = strsep(&stringp, ":");
08586    stringp = hostname;
08587    hostname = strsep(&stringp, ":");
08588    porta = strsep(&stringp, ":");
08589    
08590    if (porta && !atoi(porta)) {
08591       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08592       return -1;
08593    }
08594 
08595    return iax2_append_register(hostname, username, secret, porta);
08596 }

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

Definition at line 12184 of file chan_iax2.c.

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

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

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

Definition at line 1489 of file chan_iax2.c.

References ast_sched_thread_add(), and ast_sched_thread_del.

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

01491 {
01492    ast_sched_thread_del(st, id);
01493 
01494    return ast_sched_thread_add(st, when, callback, data);
01495 }

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

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

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

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

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

Definition at line 4320 of file chan_iax2.c.

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

04321 {
04322    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04323 }

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

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

04309 {
04310    
04311    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04312       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04313 }

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

Definition at line 5301 of file chan_iax2.c.

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

05302 {
05303    struct ast_option_header *h;
05304    int res;
05305 
05306    switch (option) {
05307    case AST_OPTION_TXGAIN:
05308    case AST_OPTION_RXGAIN:
05309       /* these two cannot be sent, because they require a result */
05310       errno = ENOSYS;
05311       return -1;
05312    case AST_OPTION_OPRMODE:
05313       errno = EINVAL;
05314       return -1;
05315    case AST_OPTION_SECURE_SIGNALING:
05316    case AST_OPTION_SECURE_MEDIA:
05317    {
05318       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05319       ast_mutex_lock(&iaxsl[callno]);
05320       if ((*(int *) data)) {
05321          ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05322       } else {
05323          ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05324       }
05325       ast_mutex_unlock(&iaxsl[callno]);
05326       return 0;
05327    }
05328    /* These options are sent to the other side across the network where
05329     * they will be passed to whatever channel is bridged there. Don't
05330     * do anything silly like pass an option that transmits pointers to
05331     * memory on this machine to a remote machine to use */
05332    case AST_OPTION_TONE_VERIFY:
05333    case AST_OPTION_TDD:
05334    case AST_OPTION_RELAXDTMF:
05335    case AST_OPTION_AUDIO_MODE:
05336    case AST_OPTION_DIGIT_DETECT:
05337    case AST_OPTION_FAX_DETECT:
05338    {
05339       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05340       struct chan_iax2_pvt *pvt;
05341 
05342       ast_mutex_lock(&iaxsl[callno]);
05343       pvt = iaxs[callno];
05344 
05345       if (wait_for_peercallno(pvt)) {
05346          ast_mutex_unlock(&iaxsl[callno]);
05347          return -1;
05348       }
05349 
05350       ast_mutex_unlock(&iaxsl[callno]);
05351 
05352       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05353          return -1;
05354       }
05355 
05356       h->flag = AST_OPTION_FLAG_REQUEST;
05357       h->option = htons(option);
05358       memcpy(h->data, data, datalen);
05359       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05360                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
05361                  datalen + sizeof(*h), -1);
05362       ast_free(h);
05363       return res;
05364    }
05365    default:
05366       return -1;
05367    }
05368 
05369    /* Just in case someone does a break instead of a return */
05370    return -1;
05371 }

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

Definition at line 5429 of file chan_iax2.c.

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

Referenced by iax2_bridge().

05430 {
05431    int res;
05432    struct iax_ie_data ied0;
05433    struct iax_ie_data ied1;
05434    unsigned int transferid = (unsigned int)ast_random();
05435 
05436    if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05437       ast_debug(1, "transfers are not supported for encrypted calls at this time\n");
05438       ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05439       ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05440       return 0;
05441    }
05442 
05443    memset(&ied0, 0, sizeof(ied0));
05444    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05445    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05446    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05447 
05448    memset(&ied1, 0, sizeof(ied1));
05449    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05450    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05451    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05452    
05453    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05454    if (res)
05455       return -1;
05456    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05457    if (res)
05458       return -1;
05459    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05460    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05461    return 0;
05462 }

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

Definition at line 5704 of file chan_iax2.c.

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

05705 {
05706    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05707    struct iax_ie_data ied = { "", };
05708    char tmp[256], *context;
05709    enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05710    ast_copy_string(tmp, dest, sizeof(tmp));
05711    context = strchr(tmp, '@');
05712    if (context) {
05713       *context = '\0';
05714       context++;
05715    }
05716    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05717    if (context)
05718       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05719    ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05720    ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05721    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05722 }

static int iax2_transmit ( struct iax_frame fr  )  [static]

Definition at line 4291 of file chan_iax2.c.

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

Referenced by iax2_send().

04292 {
04293    fr->sentyet = 0;
04294 
04295    return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04296 }

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

Definition at line 9182 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

09183 {
09184    /* Drop when trunk is about 5 seconds idle */
09185    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
09186       return 1;
09187    return 0;
09188 }

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

Definition at line 6129 of file chan_iax2.c.

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

Referenced by iax2_send().

06130 {
06131    struct ast_frame *f;
06132    struct iax2_trunk_peer *tpeer;
06133    void *tmp, *ptr;
06134    struct timeval now;
06135    struct ast_iax2_meta_trunk_entry *met;
06136    struct ast_iax2_meta_trunk_mini *mtm;
06137 
06138    f = &fr->af;
06139    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06140    if (tpeer) {
06141       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06142          /* Need to reallocate space */
06143          if (tpeer->trunkdataalloc < trunkmaxsize) {
06144             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06145                ast_mutex_unlock(&tpeer->lock);
06146                return -1;
06147             }
06148             
06149             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06150             tpeer->trunkdata = tmp;
06151             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);
06152          } else {
06153             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));
06154             ast_mutex_unlock(&tpeer->lock);
06155             return -1;
06156          }
06157       }
06158 
06159       /* Append to meta frame */
06160       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06161       if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06162          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06163          mtm->len = htons(f->datalen);
06164          mtm->mini.callno = htons(pvt->callno);
06165          mtm->mini.ts = htons(0xffff & fr->ts);
06166          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06167          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06168       } else {
06169          met = (struct ast_iax2_meta_trunk_entry *)ptr;
06170          /* Store call number and length in meta header */
06171          met->callno = htons(pvt->callno);
06172          met->len = htons(f->datalen);
06173          /* Advance pointers/decrease length past trunk entry header */
06174          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06175          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06176       }
06177       /* Copy actual trunk data */
06178       memcpy(ptr, f->data.ptr, f->datalen);
06179       tpeer->trunkdatalen += f->datalen;
06180 
06181       tpeer->calls++;
06182 
06183       /* track the largest mtu we actually have sent */
06184       if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 
06185          trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 
06186 
06187       /* if we have enough for a full MTU, ship it now without waiting */
06188       if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06189          now = ast_tvnow();
06190          send_trunk(tpeer, &now); 
06191          trunk_untimed ++; 
06192       }
06193 
06194       ast_mutex_unlock(&tpeer->lock);
06195    }
06196    return 0;
06197 }

static int iax2_vnak ( int  callno  )  [static]

Definition at line 9103 of file chan_iax2.c.

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

Referenced by socket_process(), and socket_process_meta().

09104 {
09105    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09106 }

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

Definition at line 7470 of file chan_iax2.c.

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

07471 {
07472    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07473    int res = -1;
07474    ast_mutex_lock(&iaxsl[callno]);
07475    if (iaxs[callno]) {
07476    /* If there's an outstanding error, return failure now */
07477       if (!iaxs[callno]->error) {
07478          if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07479             res = 0;
07480             /* Don't waste bandwidth sending null frames */
07481          else if (f->frametype == AST_FRAME_NULL)
07482             res = 0;
07483          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07484             res = 0;
07485          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07486             res = 0;
07487          else
07488          /* Simple, just queue for transmission */
07489             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07490       } else {
07491          ast_debug(1, "Write error: %s\n", strerror(errno));
07492       }
07493    }
07494    /* If it's already gone, just return */
07495    ast_mutex_unlock(&iaxsl[callno]);
07496    return res;
07497 }

static int iax_check_version ( char *  dev  )  [static]

Definition at line 3163 of file chan_iax2.c.

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

Referenced by update_registry().

03164 {
03165    int res = 0;
03166    struct iax_firmware *cur = NULL;
03167 
03168    if (ast_strlen_zero(dev))
03169       return 0;
03170 
03171    AST_LIST_LOCK(&firmwares);
03172    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03173       if (!strcmp(dev, (char *)cur->fwh->devname)) {
03174          res = ntohs(cur->fwh->version);
03175          break;
03176       }
03177    }
03178    AST_LIST_UNLOCK(&firmwares);
03179 
03180    return res;
03181 }

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

Definition at line 1120 of file chan_iax2.c.

References ast_verbose.

Referenced by load_module().

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

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

Definition at line 1126 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

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

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

Definition at line 3183 of file chan_iax2.c.

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

Referenced by socket_process().

03184 {
03185    int res = -1;
03186    unsigned int bs = desc & 0xff;
03187    unsigned int start = (desc >> 8) & 0xffffff;
03188    unsigned int bytes;
03189    struct iax_firmware *cur;
03190 
03191    if (ast_strlen_zero((char *)dev) || !bs)
03192       return -1;
03193 
03194    start *= bs;
03195    
03196    AST_LIST_LOCK(&firmwares);
03197    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03198       if (strcmp((char *)dev, (char *)cur->fwh->devname))
03199          continue;
03200       iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03201       if (start < ntohl(cur->fwh->datalen)) {
03202          bytes = ntohl(cur->fwh->datalen) - start;
03203          if (bytes > bs)
03204             bytes = bs;
03205          iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03206       } else {
03207          bytes = 0;
03208          iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03209       }
03210       if (bytes == bs)
03211          res = 0;
03212       else
03213          res = 1;
03214       break;
03215    }
03216    AST_LIST_UNLOCK(&firmwares);
03217 
03218    return res;
03219 }

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

Definition at line 1103 of file chan_iax2.c.

References debugaddr, and iax_showframe().

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

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

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

DO NOT hold any locks while calling iax_park

Definition at line 9356 of file chan_iax2.c.

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

Referenced by socket_process().

09357 {
09358    struct iax_dual *d;
09359    struct ast_channel *chan1m, *chan2m;/* Chan2m: The transferer, chan1m: The transferee */
09360    pthread_t th;
09361 
09362    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09363    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09364    d = ast_calloc(1, sizeof(*d));
09365    if (!chan1m || !chan2m || !d) {
09366       if (chan1m) {
09367          ast_hangup(chan1m);
09368       }
09369       if (chan2m) {
09370          ast_hangup(chan2m);
09371       }
09372       ast_free(d);
09373       return -1;
09374    }
09375    d->park_exten = ast_strdup(park_exten);
09376    d->park_context = ast_strdup(park_context);
09377    if (!d->park_exten || !d->park_context) {
09378       ast_hangup(chan1m);
09379       ast_hangup(chan2m);
09380       ast_free(d->park_exten);
09381       ast_free(d->park_context);
09382       ast_free(d);
09383       return -1;
09384    }
09385 
09386    /* Make formats okay */
09387    chan1m->readformat = chan1->readformat;
09388    chan1m->writeformat = chan1->writeformat;
09389 
09390    /* Prepare for taking over the channel */
09391    if (ast_channel_masquerade(chan1m, chan1)) {
09392       ast_hangup(chan1m);
09393       ast_hangup(chan2m);
09394       ast_free(d->park_exten);
09395       ast_free(d->park_context);
09396       ast_free(d);
09397       return -1;
09398    }
09399 
09400    /* Setup the extensions and such */
09401    ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09402    ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09403    chan1m->priority = chan1->priority;
09404 
09405    ast_do_masquerade(chan1m);
09406 
09407    /* We make a clone of the peer channel too, so we can play
09408       back the announcement */
09409 
09410    /* Make formats okay */
09411    chan2m->readformat = chan2->readformat;
09412    chan2m->writeformat = chan2->writeformat;
09413    ast_string_field_set(chan2m, parkinglot, chan2->parkinglot);
09414 
09415    /* Prepare for taking over the channel */
09416    if (ast_channel_masquerade(chan2m, chan2)) {
09417       ast_hangup(chan1m);
09418       ast_hangup(chan2m);
09419       ast_free(d->park_exten);
09420       ast_free(d->park_context);
09421       ast_free(d);
09422       return -1;
09423    }
09424 
09425    /* Setup the extensions and such */
09426    ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09427    ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09428    chan2m->priority = chan2->priority;
09429 
09430    ast_do_masquerade(chan2m);
09431 
09432    d->chan1 = chan1m;   /* Transferee */
09433    d->chan2 = chan2m;   /* Transferer */
09434    if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) {
09435       /* Could not start thread */
09436       ast_hangup(chan1m);
09437       ast_hangup(chan2m);
09438       ast_free(d->park_exten);
09439       ast_free(d->park_context);
09440       ast_free(d);
09441       return -1;
09442    }
09443    return 0;
09444 }

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

Definition at line 9329 of file chan_iax2.c.

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

Referenced by iax_park().

09330 {
09331    struct iax_dual *d;
09332    int res;
09333    int ext = 0;
09334 
09335    d = stuff;
09336 
09337    ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n",
09338       d->chan2->name, d->chan1->name);
09339 
09340    res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext);
09341    if (res) {
09342       /* Parking failed. */
09343       ast_hangup(d->chan1);
09344    } else {
09345       ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09346    }
09347    ast_hangup(d->chan2);
09348 
09349    ast_free(d->park_exten);
09350    ast_free(d->park_context);
09351    ast_free(d);
09352    return NULL;
09353 }

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

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

01958 {
01959    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01960    if (new) {
01961       size_t afdatalen = new->afdatalen;
01962       memcpy(new, fr, sizeof(*new));
01963       iax_frame_wrap(new, &fr->af);
01964       new->afdatalen = afdatalen;
01965       new->data = NULL;
01966       new->datalen = 0;
01967       new->direction = DIRECTION_INGRESS;
01968       new->retrans = -1;
01969    }
01970    return new;
01971 }

static void insert_idle_thread ( struct iax2_thread thread  )  [static]

Definition at line 1379 of file chan_iax2.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, and IAX_THREAD_TYPE_DYNAMIC.

Referenced by iax2_process_thread().

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

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

Definition at line 1155 of file chan_iax2.c.

References args, and ast_verbose.

Referenced by handle_cli_iax2_set_debug_jb().

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

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

Definition at line 1131 of file chan_iax2.c.

References args, ast_log(), and LOG_ERROR.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

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

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

Definition at line 1143 of file chan_iax2.c.

References args, ast_log(), and LOG_WARNING.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

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

static int load_module ( void   )  [static]

Load IAX2 module, load configuraiton ---.

Definition at line 14803 of file chan_iax2.c.

References __unload_module(), ao2_callback, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_mutex_init, ast_netsock_init(), ast_netsock_list_alloc(), ast_random(), ast_realtime_require_field(), ast_register_application_xml, ast_register_switch(), ast_sched_thread_create(), ast_sched_thread_destroy(), AST_TEST_REGISTER, ast_timer_close(), ast_timer_open(), ast_timer_set_rate(), ast_verb, cli_iax2, config, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, iax2_data_providers, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxs, iaxsl, iaxvar_function, io_context_create(), io_context_destroy(), jb_error_output(), jb_setoutput(), jb_warning_output(), load_objects(), LOG_ERROR, manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), network_change_event_subscribe(), papp, peer_set_sock_cb(), reload_firmware(), RQ_CHAR, RQ_UINTEGER2, SENTINEL, set_config(), and start_network_thread().

14804 {
14805    static const char config[] = "iax.conf";
14806    int x = 0;
14807    struct iax2_registry *reg = NULL;
14808 
14809    if (load_objects()) {
14810       return AST_MODULE_LOAD_FAILURE;
14811    }
14812 
14813    memset(iaxs, 0, sizeof(iaxs));
14814 
14815    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14816       ast_mutex_init(&iaxsl[x]);
14817    }
14818 
14819    if (!(sched = ast_sched_thread_create())) {
14820       ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14821       return AST_MODULE_LOAD_FAILURE;
14822    }
14823 
14824    if (!(io = io_context_create())) {
14825       ast_log(LOG_ERROR, "Failed to create I/O context\n");
14826       sched = ast_sched_thread_destroy(sched);
14827       return AST_MODULE_LOAD_FAILURE;
14828    }
14829 
14830    if (!(netsock = ast_netsock_list_alloc())) {
14831       ast_log(LOG_ERROR, "Failed to create netsock list\n");
14832       io_context_destroy(io);
14833       sched = ast_sched_thread_destroy(sched);
14834       return AST_MODULE_LOAD_FAILURE;
14835    }
14836    ast_netsock_init(netsock);
14837    
14838    outsock = ast_netsock_list_alloc();
14839    if (!outsock) {
14840       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14841       io_context_destroy(io);
14842       sched = ast_sched_thread_destroy(sched);
14843       return AST_MODULE_LOAD_FAILURE;
14844    }
14845    ast_netsock_init(outsock);
14846 
14847    randomcalltokendata = ast_random();
14848 
14849    iax_set_output(iax_debug_output);
14850    iax_set_error(iax_error_output);
14851    jb_setoutput(jb_error_output, jb_warning_output, NULL);
14852    
14853    if ((timer = ast_timer_open())) {
14854       ast_timer_set_rate(timer, 1000 / trunkfreq);
14855    }
14856 
14857    if (set_config(config, 0) == -1) {
14858       if (timer) {
14859          ast_timer_close(timer);
14860          timer = NULL;
14861       }
14862       return AST_MODULE_LOAD_DECLINE;
14863    }
14864 
14865 #ifdef TEST_FRAMEWORK
14866    AST_TEST_REGISTER(test_iax2_peers_get);
14867    AST_TEST_REGISTER(test_iax2_users_get);
14868 #endif
14869 
14870    /* Register AstData providers */
14871    ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
14872    ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14873 
14874    ast_register_application_xml(papp, iax2_prov_app);
14875 
14876    ast_custom_function_register(&iaxpeer_function);
14877    ast_custom_function_register(&iaxvar_function);
14878 
14879    ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
14880    ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
14881    ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
14882    ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
14883 
14884    if (ast_channel_register(&iax2_tech)) {
14885       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
14886       __unload_module();
14887       return AST_MODULE_LOAD_FAILURE;
14888    }
14889 
14890    if (ast_register_switch(&iax2_switch)) {
14891       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
14892    }
14893 
14894    if (start_network_thread()) {
14895       ast_log(LOG_ERROR, "Unable to start network thread\n");
14896       __unload_module();
14897       return AST_MODULE_LOAD_FAILURE;
14898    } else {
14899       ast_verb(2, "IAX Ready and Listening\n");
14900    }
14901 
14902    AST_LIST_LOCK(&registrations);
14903    AST_LIST_TRAVERSE(&registrations, reg, entry)
14904       iax2_do_register(reg);
14905    AST_LIST_UNLOCK(&registrations); 
14906    
14907    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
14908    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
14909 
14910 
14911    reload_firmware(0);
14912    iax_provision_reload(0);
14913 
14914    ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
14915 
14916    network_change_event_subscribe();
14917 
14918    return AST_MODULE_LOAD_SUCCESS;
14919 }

static int load_objects ( void   )  [static]

Definition at line 14565 of file chan_iax2.c.

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

Referenced by load_module().

14566 {
14567    peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14568    peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14569 
14570    if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14571       goto container_fail;
14572    } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14573       goto container_fail;
14574    } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14575       goto container_fail;
14576    } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14577       goto container_fail;
14578    } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14579       goto container_fail;
14580    } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14581       goto container_fail;
14582    } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14583       goto container_fail;
14584    } else if (create_callno_pools()) {
14585       goto container_fail;
14586    } else if  (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14587       goto container_fail;
14588    }
14589 
14590    return 0;
14591 
14592 container_fail:
14593    if (peers) {
14594       ao2_ref(peers, -1);
14595    }
14596    if (users) {
14597       ao2_ref(users, -1);
14598    }
14599    if (iax_peercallno_pvts) {
14600       ao2_ref(iax_peercallno_pvts, -1);
14601    }
14602    if (iax_transfercallno_pvts) {
14603       ao2_ref(iax_transfercallno_pvts, -1);
14604    }
14605    if (peercnts) {
14606       ao2_ref(peercnts, -1);
14607    }
14608    if (callno_limits) {
14609       ao2_ref(callno_limits, -1);
14610    }
14611    if (calltoken_ignores) {
14612       ao2_ref(calltoken_ignores, -1);
14613    }
14614    if (callno_pool) {
14615       ao2_ref(callno_pool, -1);
14616    }
14617    if (callno_pool_trunk) {
14618       ao2_ref(callno_pool_trunk, -1);
14619    }
14620    return AST_MODULE_LOAD_FAILURE;
14621 }

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

Definition at line 5464 of file chan_iax2.c.

References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.

Referenced by iax2_bridge().

05465 {
05466    ast_mutex_lock(&iaxsl[callno0]);
05467    while (ast_mutex_trylock(&iaxsl[callno1])) {
05468       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05469    }
05470 }

static void log_jitterstats ( unsigned short  callno  )  [static]

Definition at line 9516 of file chan_iax2.c.

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

Referenced by socket_process().

09517 {
09518    int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09519    jb_info jbinfo;
09520 
09521    ast_mutex_lock(&iaxsl[callno]);
09522    if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09523       if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09524          jb_getinfo(iaxs[callno]->jb, &jbinfo);
09525          localjitter = jbinfo.jitter;
09526          localdelay = jbinfo.current - jbinfo.min;
09527          locallost = jbinfo.frames_lost;
09528          locallosspct = jbinfo.losspct/1000;
09529          localdropped = jbinfo.frames_dropped;
09530          localooo = jbinfo.frames_ooo;
09531          localpackets = jbinfo.frames_in;
09532       }
09533       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",
09534          iaxs[callno]->owner->name,
09535          iaxs[callno]->pingtime,
09536          localjitter,
09537          localdelay,
09538          locallost,
09539          locallosspct,
09540          localdropped,
09541          localooo,
09542          localpackets,
09543          iaxs[callno]->remote_rr.jitter,
09544          iaxs[callno]->remote_rr.delay,
09545          iaxs[callno]->remote_rr.losscnt,
09546          iaxs[callno]->remote_rr.losspct/1000,
09547          iaxs[callno]->remote_rr.dropped,
09548          iaxs[callno]->remote_rr.ooo,
09549          iaxs[callno]->remote_rr.packets);
09550       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",
09551          iaxs[callno]->owner->name,
09552          iaxs[callno]->pingtime,
09553          localjitter,
09554          localdelay,
09555          locallost,
09556          locallosspct,
09557          localdropped,
09558          localooo,
09559          localpackets,
09560          iaxs[callno]->remote_rr.jitter,
09561          iaxs[callno]->remote_rr.delay,
09562          iaxs[callno]->remote_rr.losscnt,
09563          iaxs[callno]->remote_rr.losspct/1000,
09564          iaxs[callno]->remote_rr.dropped,
09565          iaxs[callno]->remote_rr.ooo,
09566          iaxs[callno]->remote_rr.packets);
09567    }
09568    ast_mutex_unlock(&iaxsl[callno]);
09569 }

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

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

Referenced by iax2_request(), and socket_process().

02053 {
02054    int x;
02055    int res= 0;
02056    struct callno_entry *callno_entry;
02057    if (iaxs[callno]->oseqno) {
02058       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
02059       return -1;
02060    }
02061    if (callno >= TRUNK_CALL_START) {
02062       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
02063       return -1;
02064    }
02065 
02066    if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
02067       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
02068       return -1;
02069    }
02070 
02071    x = callno_entry->callno;
02072    ast_mutex_lock(&iaxsl[x]);
02073 
02074    /*!
02075     * \note We delete these before switching the slot, because if
02076     * they fire in the meantime, they will generate a warning.
02077     */
02078    ast_sched_thread_del(sched, iaxs[callno]->pingid);
02079    ast_sched_thread_del(sched, iaxs[callno]->lagid);
02080    iaxs[callno]->lagid = iaxs[callno]->pingid = -1;
02081    iaxs[x] = iaxs[callno];
02082    iaxs[x]->callno = x;
02083 
02084    /* since we copied over the pvt from a different callno, make sure the old entry is replaced
02085     * before assigning the new one */
02086    if (iaxs[x]->callno_entry) {
02087       iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
02088    }
02089    iaxs[x]->callno_entry = callno_entry;
02090 
02091    iaxs[callno] = NULL;
02092    /* Update the two timers that should have been started */
02093    iaxs[x]->pingid = iax2_sched_add(sched, 
02094       ping_time * 1000, send_ping, (void *)(long)x);
02095    iaxs[x]->lagid = iax2_sched_add(sched, 
02096       lagrq_time * 1000, send_lagrq, (void *)(long)x);
02097 
02098    if (locked)
02099       ast_mutex_unlock(&iaxsl[callno]);
02100    res = x;
02101    if (!locked)
02102       ast_mutex_unlock(&iaxsl[x]);
02103 
02104    ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
02105    /* We move this call from a non-trunked to a trunked call */
02106    update_max_trunk();
02107    update_max_nontrunk();
02108    return res;
02109 }

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

Definition at line 6971 of file chan_iax2.c.

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

Referenced by load_module().

06972 {
06973    ast_cli_netstats(s, -1, 0);
06974    astman_append(s, "\r\n");
06975    return RESULT_SUCCESS;
06976 }

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

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

Referenced by load_module().

07035 {
07036    struct iax2_peer *peer = NULL;
07037    int peer_count = 0;
07038    char nm[20];
07039    char status[20];
07040    const char *id = astman_get_header(m,"ActionID");
07041    char idtext[256] = "";
07042    struct ast_str *encmethods = ast_str_alloca(256);
07043    struct ao2_iterator i;
07044 
07045    if (!ast_strlen_zero(id))
07046       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07047 
07048    astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
07049 
07050 
07051    i = ao2_iterator_init(peers, 0);
07052    for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
07053       encmethods_to_str(peer->encmethods, &encmethods);
07054       astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
07055       if (!ast_strlen_zero(peer->username)) {
07056          astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
07057       } else {
07058          astman_append(s, "ObjectName: %s\r\n", peer->name);
07059       }
07060       astman_append(s, "ChanObjectType: peer\r\n");
07061       astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
07062       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
07063       astman_append(s, "Mask: %s\r\n", nm);
07064       astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
07065       astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
07066       astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
07067       astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
07068       peer_status(peer, status, sizeof(status));
07069       astman_append(s, "Status: %s\r\n\r\n", status);
07070       peer_count++;
07071    }
07072    ao2_iterator_destroy(&i);
07073 
07074    astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07075    return RESULT_SUCCESS;
07076 }

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

callback to display iax peers in manager

Definition at line 7010 of file chan_iax2.c.

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

Referenced by load_module().

07011 {
07012    static const char * const a[] = { "iax2", "show", "peers" };
07013    const char *id = astman_get_header(m,"ActionID");
07014    char idtext[256] = "";
07015    int total = 0;
07016 
07017    if (!ast_strlen_zero(id))
07018       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07019 
07020    astman_send_listack(s, m, "Peer status list will follow", "start");
07021         /* List the peers in separate manager events */
07022    __iax2_show_peers(-1, &total, s, 3, a);
07023         /* Send final confirmation */
07024         astman_append(s,
07025         "Event: PeerlistComplete\r\n"
07026         "EventList: Complete\r\n"
07027         "ListItems: %d\r\n"
07028         "%s"
07029         "\r\n", total, idtext);
07030         return 0;
07031 }

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

Definition at line 7142 of file chan_iax2.c.

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

Referenced by load_module().

07143 {
07144    const char *id = astman_get_header(m, "ActionID");
07145    struct iax2_registry *reg = NULL;
07146    char idtext[256] = "";
07147    char host[80] = "";
07148    char perceived[80] = "";
07149    int total = 0;
07150 
07151    if (!ast_strlen_zero(id))
07152       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07153 
07154    astman_send_listack(s, m, "Registrations will follow", "start");
07155 
07156    AST_LIST_LOCK(&registrations);
07157    AST_LIST_TRAVERSE(&registrations, reg, entry) {
07158       snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
07159       
07160       if (reg->us.sin_addr.s_addr) {
07161          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07162       } else {
07163          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07164       }
07165       
07166       astman_append(s,
07167          "Event: RegistryEntry\r\n"
07168          "%s"
07169          "Host: %s\r\n"
07170          "DNSmanager: %s\r\n"
07171          "Username: %s\r\n"
07172          "Perceived: %s\r\n"
07173          "Refresh: %d\r\n"
07174          "State: %s\r\n"
07175          "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 
07176          reg->refresh, regstate2str(reg->regstate));
07177 
07178       total++;
07179    }
07180    AST_LIST_UNLOCK(&registrations);
07181 
07182    astman_append(s,
07183       "Event: RegistrationsComplete\r\n"
07184       "EventList: Complete\r\n"
07185       "ListItems: %d\r\n"
07186       "%s"
07187       "\r\n", total, idtext);
07188    
07189    return 0;
07190 }

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

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

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

01987 {
01988    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01989       (cur->addr.sin_port == sin->sin_port)) {
01990       /* This is the main host */
01991       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01992           (check_dcallno ? dcallno == cur->callno : 1) ) {
01993          /* That's us.  Be sure we keep track of the peer call number */
01994          return 1;
01995       }
01996    }
01997    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01998        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01999       /* We're transferring */
02000       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
02001          return 1;
02002    }
02003    return 0;
02004 }

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

Definition at line 6227 of file chan_iax2.c.

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

Referenced by decode_frame().

06228 {
06229 #if 0
06230    /* Debug with "fake encryption" */
06231    int x;
06232    if (len % 16)
06233       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06234    for (x=0;x<len;x++)
06235       dst[x] = src[x] ^ 0xff;
06236 #else 
06237    unsigned char lastblock[16] = { 0 };
06238    int x;
06239    while(len > 0) {
06240       ast_aes_decrypt(src, dst, dcx);
06241       for (x=0;x<16;x++)
06242          dst[x] ^= lastblock[x];
06243       memcpy(lastblock, src, sizeof(lastblock));
06244       dst += 16;
06245       src += 16;
06246       len -= 16;
06247    }
06248 #endif
06249 }

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

Definition at line 6251 of file chan_iax2.c.

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

Referenced by encrypt_frame().

06252 {
06253 #if 0
06254    /* Debug with "fake encryption" */
06255    int x;
06256    if (len % 16)
06257       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06258    for (x=0;x<len;x++)
06259       dst[x] = src[x] ^ 0xff;
06260 #else
06261    unsigned char curblock[16] = { 0 };
06262    int x;
06263    while(len > 0) {
06264       for (x=0;x<16;x++)
06265          curblock[x] ^= src[x];
06266       ast_aes_encrypt(curblock, dst, ecx);
06267       memcpy(curblock, dst, sizeof(curblock)); 
06268       dst += 16;
06269       src += 16;
06270       len -= 16;
06271    }
06272 #endif
06273 }

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

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

07816 {
07817    /* Select exactly one common encryption if there are any */
07818    p->encmethods &= enc;
07819    if (p->encmethods) {
07820       if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */
07821          p->keyrotateid = -2;
07822       }
07823       if (p->encmethods & IAX_ENCRYPT_AES128)
07824          p->encmethods = IAX_ENCRYPT_AES128;
07825       else
07826          p->encmethods = 0;
07827    }
07828 }

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

Definition at line 1276 of file chan_iax2.c.

Referenced by build_peer().

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

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

Definition at line 1311 of file chan_iax2.c.

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

Referenced by network_change_event_subscribe().

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

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

Definition at line 1298 of file chan_iax2.c.

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

Referenced by network_change_event_cb().

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

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

Definition at line 12263 of file chan_iax2.c.

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

Referenced by start_network_thread().

12264 {
12265    if (timer) {
12266       ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12267    }
12268 
12269    for (;;) {
12270       pthread_testcancel();
12271       /* Wake up once a second just in case SIGURG was sent while
12272        * we weren't in poll(), to make sure we don't hang when trying
12273        * to unload. */
12274       if (ast_io_wait(io, 1000) <= 0) {
12275          break;
12276       }
12277    }
12278 
12279    return NULL;
12280 }

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

Definition at line 1915 of file chan_iax2.c.

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

Referenced by __find_callno().

01916 {
01917    struct chan_iax2_pvt *tmp;
01918    jb_conf jbconf;
01919 
01920    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01921       return NULL;
01922    }
01923 
01924    if (ast_string_field_init(tmp, 32)) {
01925       ao2_ref(tmp, -1);
01926       tmp = NULL;
01927       return NULL;
01928    }
01929       
01930    tmp->prefs = prefs;
01931    tmp->pingid = -1;
01932    tmp->lagid = -1;
01933    tmp->autoid = -1;
01934    tmp->authid = -1;
01935    tmp->initid = -1;
01936    tmp->keyrotateid = -1;
01937 
01938    ast_string_field_set(tmp,exten, "s");
01939    ast_string_field_set(tmp,host, host);
01940 
01941    tmp->jb = jb_new();
01942    tmp->jbid = -1;
01943    jbconf.max_jitterbuf = maxjitterbuffer;
01944    jbconf.resync_threshold = resyncthreshold;
01945    jbconf.max_contig_interp = maxjitterinterps;
01946    jbconf.target_extra = jittertargetextra;
01947    jb_setconf(tmp->jb,&jbconf);
01948 
01949    AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01950 
01951    tmp->hold_signaling = 1;
01952    AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
01953 
01954    return tmp;
01955 }

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

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

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

04987 {
04988    if (ast_strlen_zero(data))
04989       return;
04990 
04991    pds->peer = strsep(&data, "/");
04992    pds->exten = strsep(&data, "/");
04993    pds->options = data;
04994 
04995    if (pds->exten) {
04996       data = pds->exten;
04997       pds->exten = strsep(&data, "@");
04998       pds->context = data;
04999    }
05000 
05001    if (strchr(pds->peer, '@')) {
05002       data = pds->peer;
05003       pds->username = strsep(&data, "@");
05004       pds->peer = data;
05005    }
05006 
05007    if (pds->username) {
05008       data = pds->username;
05009       pds->username = strsep(&data, ":");
05010       pds->password = data;
05011    }
05012 
05013    data = pds->peer;
05014    pds->peer = strsep(&data, ":");
05015    pds->port = data;
05016 
05017    /* check for a key name wrapped in [] in the secret position, if found,
05018       move it to the key field instead
05019    */
05020    if (pds->password && (pds->password[0] == '[')) {
05021       pds->key = ast_strip_quoted(pds->password, "[", "]");
05022       pds->password = NULL;
05023    }
05024 }

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

References CMP_MATCH, and CMP_STOP.

Referenced by load_objects().

01656 {
01657    struct iax2_peer *peer = obj, *peer2 = arg;
01658 
01659    return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01660 }

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

Definition at line 13024 of file chan_iax2.c.

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

13025 {
13026    struct iax2_peer *peer = obj;
13027 
13028    ast_set_flag64(peer, IAX_DELME);
13029 
13030    return 0;
13031 }

static void peer_destructor ( void *  obj  )  [static]

Definition at line 12453 of file chan_iax2.c.

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

Referenced by build_peer().

12454 {
12455    struct iax2_peer *peer = obj;
12456    int callno = peer->callno;
12457 
12458    ast_free_ha(peer->ha);
12459 
12460    if (callno > 0) {
12461       ast_mutex_lock(&iaxsl[callno]);
12462       iax2_destroy(callno);
12463       ast_mutex_unlock(&iaxsl[callno]);
12464    }
12465 
12466    register_peer_exten(peer, 0);
12467 
12468    if (peer->dnsmgr)
12469       ast_dnsmgr_release(peer->dnsmgr);
12470 
12471    if (peer->mwi_event_sub)
12472       ast_event_unsubscribe(peer->mwi_event_sub);
12473 
12474    ast_string_field_free_memory(peer);
12475 }

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

References ast_str_hash().

Referenced by load_objects().

01646 {
01647    const struct iax2_peer *peer = obj;
01648 
01649    return ast_str_hash(peer->name);
01650 }

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

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

01703 {
01704    ao2_ref(peer, +1);
01705    return peer;
01706 }

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

Definition at line 14519 of file chan_iax2.c.

References iax2_peer::sockfd.

Referenced by load_module().

14520 {
14521    struct iax2_peer *peer = obj;
14522 
14523    if (peer->sockfd < 0)
14524       peer->sockfd = defaultsockfd;
14525 
14526    return 0;
14527 }

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

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

Referenced by build_peer().

12381 {
12382    struct sockaddr_in sin;
12383    struct ast_sockaddr sin_tmp;
12384    int nonlocal = 1;
12385    int port = IAX_DEFAULT_PORTNO;
12386    int sockfd = defaultsockfd;
12387    char *tmp;
12388    char *addr;
12389    char *portstr;
12390 
12391    tmp = ast_strdupa(srcaddr);
12392    addr = strsep(&tmp, ":");
12393    portstr = tmp;
12394 
12395    if (portstr) {
12396       port = atoi(portstr);
12397       if (port < 1)
12398          port = IAX_DEFAULT_PORTNO;
12399    }
12400 
12401    sin_tmp.ss.ss_family = AF_INET;
12402    if (!ast_get_ip(&sin_tmp, addr)) {
12403       struct ast_netsock *sock;
12404       int res;
12405 
12406       ast_sockaddr_to_sin(&sin_tmp, &sin);
12407       sin.sin_port = 0;
12408       sin.sin_family = AF_INET;
12409       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12410       if (res == 0) {
12411          /* ip address valid. */
12412          sin.sin_port = htons(port);
12413          if (!(sock = ast_netsock_find(netsock, &sin)))
12414             sock = ast_netsock_find(outsock, &sin);
12415          if (sock) {
12416             sockfd = ast_netsock_sockfd(sock);
12417             nonlocal = 0;
12418          } else {
12419             unsigned int orig_saddr = sin.sin_addr.s_addr;
12420             /* INADDR_ANY matches anyway! */
12421             sin.sin_addr.s_addr = INADDR_ANY;
12422             if (ast_netsock_find(netsock, &sin)) {
12423                sin.sin_addr.s_addr = orig_saddr;
12424                sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12425                if (sock) {
12426                   sockfd = ast_netsock_sockfd(sock);
12427                   ast_netsock_unref(sock);
12428                   nonlocal = 0;
12429                } else {
12430                   nonlocal = 2;
12431                }
12432             }
12433          }
12434       }
12435    }
12436       
12437    peer->sockfd = sockfd;
12438 
12439    if (nonlocal == 1) {
12440       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12441          srcaddr, peer->name);
12442       return -1;
12443         } else if (nonlocal == 2) {
12444       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12445          srcaddr, peer->name);
12446          return -1;
12447    } else {
12448       ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12449       return 0;
12450    }
12451 }

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

peer_status: Report Peer status in character string

Definition at line 3729 of file chan_iax2.c.

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

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

03730 {
03731    int res = 0;
03732    if (peer->maxms) {
03733       if (peer->lastms < 0) {
03734          ast_copy_string(status, "UNREACHABLE", statuslen);
03735       } else if (peer->lastms > peer->maxms) {
03736          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03737          res = 1;
03738       } else if (peer->lastms) {
03739          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03740          res = 1;
03741       } else {
03742          ast_copy_string(status, "UNKNOWN", statuslen);
03743       }
03744    } else { 
03745       ast_copy_string(status, "Unmonitored", statuslen);
03746       res = -1;
03747    }
03748    return res;
03749 }

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

Definition at line 2349 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

02350 {
02351    struct peercnt *peercnt;
02352    unsigned long addr = sin->sin_addr.s_addr;
02353    int res = 0;
02354    struct peercnt tmp = {
02355       .addr = addr,
02356    };
02357 
02358    /* Reasoning for peercnts container lock:  Two identical ip addresses
02359     * could be added by different threads at the "same time". Without the container
02360     * lock, both threads could alloc space for the same object and attempt
02361     * to link to table.  With the lock, one would create the object and link
02362     * to table while the other would find the already created peercnt object
02363     * rather than creating a new one. */
02364    ao2_lock(peercnts);
02365    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02366       ao2_lock(peercnt);
02367    } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02368       ao2_lock(peercnt);
02369       /* create and set defaults */
02370       peercnt->addr = addr;
02371       set_peercnt_limit(peercnt);
02372       /* guarantees it does not go away after unlocking table
02373        * ao2_find automatically adds this */
02374       ao2_link(peercnts, peercnt);
02375    } else {
02376       ao2_unlock(peercnts);
02377       return -1;
02378    }
02379 
02380    /* check to see if the address has hit its callno limit.  If not increment cur. */
02381    if (peercnt->limit > peercnt->cur) {
02382       peercnt->cur++;
02383       ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02384    } else { /* max num call numbers for this peer has been reached! */
02385       ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02386       res = -1;
02387    }
02388 
02389    /* clean up locks and ref count */
02390    ao2_unlock(peercnt);
02391    ao2_unlock(peercnts);
02392    ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */
02393 
02394    return res;
02395 }

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

Definition at line 2179 of file chan_iax2.c.

References CMP_MATCH, and CMP_STOP.

Referenced by load_objects().

02180 {
02181    struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02182    return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02183 }

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

Definition at line 2173 of file chan_iax2.c.

Referenced by load_objects().

02174 {
02175    const struct peercnt *peercnt = obj;
02176    return abs((int) peercnt->addr);
02177 }

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

Definition at line 2316 of file chan_iax2.c.

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

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

02317 {
02318    /* this function turns off and on custom callno limits set by peer registration */
02319    struct peercnt *peercnt;
02320    struct peercnt tmp = {
02321       .addr = 0,
02322    };
02323    struct sockaddr_in sin;
02324 
02325    ast_sockaddr_to_sin(sockaddr, &sin);
02326 
02327    tmp.addr = sin.sin_addr.s_addr;
02328 
02329    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02330       peercnt->reg = reg;
02331       if (limit) {
02332          peercnt->limit = limit;
02333       } else {
02334          set_peercnt_limit(peercnt);
02335       }
02336       ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg);
02337       ao2_ref(peercnt, -1); /* decrement ref from find */
02338    }
02339 }

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

Definition at line 2401 of file chan_iax2.c.

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

Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().

02402 {
02403    struct sockaddr_in sin = {
02404       .sin_addr.s_addr = peercnt->addr,
02405    };
02406 
02407    /*
02408     * Container locked here since peercnt may be unlinked from
02409     * list.  If left unlocked, peercnt_add could try and grab this
02410     * entry from the table and modify it at the "same time" this
02411     * thread attemps to unlink it.
02412     */
02413    ao2_lock(peercnts);
02414    peercnt->cur--;
02415    ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02416    /* if this was the last connection from the peer remove it from table */
02417    if (peercnt->cur == 0) {
02418       ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */
02419    }
02420    ao2_unlock(peercnts);
02421 }

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

Definition at line 2441 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

02442 {
02443    struct peercnt *peercnt;
02444    struct peercnt tmp = {
02445       .addr = sin->sin_addr.s_addr,
02446    };
02447 
02448    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02449       peercnt_remove(peercnt);
02450       ao2_ref(peercnt, -1); /* decrement ref from find */
02451    }
02452    return 0;
02453 }

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

Definition at line 2427 of file chan_iax2.c.

References ao2_ref, and peercnt_remove().

Referenced by sched_delay_remove().

02428 {
02429    struct peercnt *peercnt = (struct peercnt *) obj;
02430 
02431    peercnt_remove(peercnt);
02432    ao2_ref(peercnt, -1); /* decrement ref from scheduler */
02433 
02434    return 0;
02435 }

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

Definition at line 14653 of file chan_iax2.c.

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

14655 {
14656    struct ast_data *data_peer;
14657    struct iax2_peer *peer;
14658    struct ao2_iterator i;
14659    char status[20];
14660    struct ast_str *encmethods = ast_str_alloca(256);
14661 
14662    i = ao2_iterator_init(peers, 0);
14663    while ((peer = ao2_iterator_next(&i))) {
14664       data_peer = ast_data_add_node(data_root, "peer");
14665       if (!data_peer) {
14666          peer_unref(peer);
14667          continue;
14668       }
14669 
14670       ast_data_add_structure(iax2_peer, data_peer, peer);
14671 
14672       ast_data_add_codecs(data_peer, "codecs", peer->capability);
14673 
14674       peer_status(peer, status, sizeof(status));
14675       ast_data_add_str(data_peer, "status", status);
14676 
14677       ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14678 
14679       ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14680 
14681       ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14682 
14683       ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14684 
14685       ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14686 
14687       encmethods_to_str(peer->encmethods, &encmethods);
14688       ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14689 
14690       peer_unref(peer);
14691 
14692       if (!ast_data_search_match(search, data_peer)) {
14693          ast_data_remove_node(data_root, data_peer);
14694       }
14695    }
14696    ao2_iterator_destroy(&i);
14697 
14698    return 0;
14699 }

static void poke_all_peers ( void   )  [static]

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

13604 {
13605    struct ao2_iterator i;
13606    struct iax2_peer *peer;
13607 
13608    i = ao2_iterator_init(peers, 0);
13609    while ((peer = ao2_iterator_next(&i))) {
13610       iax2_poke_peer(peer, 0);
13611       peer_unref(peer);
13612    }
13613    ao2_iterator_destroy(&i);
13614 }

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

Definition at line 2305 of file chan_iax2.c.

References CMP_MATCH, and addr_range::delme.

Referenced by reload_config().

02306 {
02307    struct addr_range *addr_range = obj;
02308 
02309    return addr_range->delme ? CMP_MATCH : 0;
02310 }

static void prune_peers ( void   )  [static]

Definition at line 13087 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_prune_realtime(), and reload_config().

13088 {
13089    struct iax2_peer *peer;
13090    struct ao2_iterator i;
13091 
13092    i = ao2_iterator_init(peers, 0);
13093    while ((peer = ao2_iterator_next(&i))) {
13094       if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
13095          unlink_peer(peer);
13096       }
13097       peer_unref(peer);
13098    }
13099    ao2_iterator_destroy(&i);
13100 }

static void prune_users ( void   )  [static]

Definition at line 13071 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_prune_realtime(), and reload_config().

13072 {
13073    struct iax2_user *user;
13074    struct ao2_iterator i;
13075 
13076    i = ao2_iterator_init(users, 0);
13077    while ((user = ao2_iterator_next(&i))) {
13078       if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
13079          ao2_unlink(users, user);
13080       }
13081       user_unref(user);
13082    }
13083    ao2_iterator_destroy(&i);
13084 }

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

Definition at line 14536 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, and match().

Referenced by load_objects().

14537 {
14538    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14539 
14540    /* The frames_received field is used to hold whether we're matching
14541     * against a full frame or not ... */
14542 
14543    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
14544       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14545 }

static void pvt_destructor ( void *  obj  )  [static]

Definition at line 1868 of file chan_iax2.c.

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

Referenced by new_iax().

01869 {
01870    struct chan_iax2_pvt *pvt = obj;
01871    struct iax_frame *cur = NULL;
01872    struct signaling_queue_entry *s = NULL;
01873 
01874    ast_mutex_lock(&iaxsl[pvt->callno]);
01875 
01876    iax2_destroy_helper(pvt);
01877 
01878    sched_delay_remove(&pvt->addr, pvt->callno_entry);
01879    pvt->callno_entry = NULL;
01880 
01881    /* Already gone */
01882    ast_set_flag64(pvt, IAX_ALREADYGONE);
01883 
01884    AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) {
01885       /* Cancel any pending transmissions */
01886       cur->retries = -1;
01887    }
01888 
01889    ast_mutex_unlock(&iaxsl[pvt->callno]);
01890 
01891    while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01892       free_signaling_queue_entry(s);
01893    }
01894 
01895    if (pvt->reg) {
01896       pvt->reg->callno = 0;
01897    }
01898 
01899    if (!pvt->owner) {
01900       jb_frame frame;
01901       if (pvt->vars) {
01902           ast_variables_destroy(pvt->vars);
01903           pvt->vars = NULL;
01904       }
01905 
01906       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01907          iax2_frame_free(frame.data);
01908       }
01909 
01910       jb_destroy(pvt->jb);
01911       ast_string_field_free_memory(pvt);
01912    }
01913 }

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

Definition at line 14529 of file chan_iax2.c.

References chan_iax2_pvt::peercallno.

Referenced by load_objects().

14530 {
14531    const struct chan_iax2_pvt *pvt = obj;
14532 
14533    return pvt->peercallno;
14534 }

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

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

Referenced by __send_command().

01844 {
01845    struct signaling_queue_entry *qe;
01846 
01847    if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01848       return 1; /* do not queue this frame */
01849    } else if (!(qe = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01850       return -1;  /* out of memory */
01851    }
01852 
01853    /* copy ast_frame into our queue entry */
01854    qe->f = *f;
01855    if (qe->f.datalen) {
01856       /* if there is data in this frame copy it over as well */
01857       if (!(qe->f.data.ptr = ast_malloc(qe->f.datalen))) {
01858          free_signaling_queue_entry(qe);
01859          return -1;
01860       }
01861       memcpy(qe->f.data.ptr, f->data.ptr, qe->f.datalen);
01862    }
01863    AST_LIST_INSERT_TAIL(&pvt->signaling_queue, qe, next);
01864 
01865    return 0;
01866 }

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

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

07797 {
07798    struct ast_iax2_full_hdr fh;
07799    fh.scallno = htons(src | IAX_FLAG_FULL);
07800    fh.dcallno = htons(dst);
07801    fh.ts = 0;
07802    fh.oseqno = 0;
07803    fh.iseqno = 0;
07804    fh.type = AST_FRAME_IAX;
07805    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07806    iax_outputframe(NULL, &fh, 0, sin, 0);
07807 #if 0
07808    if (option_debug)
07809 #endif   
07810       ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07811          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07812    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07813 }

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

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

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

04342 {
04343    struct ast_variable *var = NULL;
04344    struct ast_variable *tmp;
04345    struct iax2_peer *peer=NULL;
04346    time_t regseconds = 0, nowtime;
04347    int dynamic=0;
04348 
04349    if (peername) {
04350       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04351       if (!var && sin)
04352          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04353    } else if (sin) {
04354       char porta[25];
04355       sprintf(porta, "%d", ntohs(sin->sin_port));
04356       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04357       if (var) {
04358          /* We'll need the peer name in order to build the structure! */
04359          for (tmp = var; tmp; tmp = tmp->next) {
04360             if (!strcasecmp(tmp->name, "name"))
04361                peername = tmp->value;
04362          }
04363       }
04364    }
04365    if (!var && peername) { /* Last ditch effort */
04366       var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04367       /*!\note
04368        * If this one loaded something, then we need to ensure that the host
04369        * field matched.  The only reason why we can't have this as a criteria
04370        * is because we only have the IP address and the host field might be
04371        * set as a name (and the reverse PTR might not match).
04372        */
04373       if (var && sin) {
04374          for (tmp = var; tmp; tmp = tmp->next) {
04375             if (!strcasecmp(tmp->name, "host")) {
04376                struct ast_hostent ahp;
04377                struct hostent *hp;
04378                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) {
04379                   /* No match */
04380                   ast_variables_destroy(var);
04381                   var = NULL;
04382                }
04383                break;
04384             }
04385          }
04386       }
04387    }
04388    if (!var)
04389       return NULL;
04390 
04391    peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04392 
04393    if (!peer) {
04394       ast_variables_destroy(var);
04395       return NULL;
04396    }
04397 
04398    for (tmp = var; tmp; tmp = tmp->next) {
04399       /* Make sure it's not a user only... */
04400       if (!strcasecmp(tmp->name, "type")) {
04401          if (strcasecmp(tmp->value, "friend") &&
04402              strcasecmp(tmp->value, "peer")) {
04403             /* Whoops, we weren't supposed to exist! */
04404             peer = peer_unref(peer);
04405             break;
04406          }
04407       } else if (!strcasecmp(tmp->name, "regseconds")) {
04408          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
04409       } else if (!strcasecmp(tmp->name, "ipaddr")) {
04410          if (!ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE)) {
04411             ast_log(LOG_WARNING, "Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->value, tmp->name);
04412          }
04413       } else if (!strcasecmp(tmp->name, "port")) {
04414          ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
04415       } else if (!strcasecmp(tmp->name, "host")) {
04416          if (!strcasecmp(tmp->value, "dynamic"))
04417             dynamic = 1;
04418       }
04419    }
04420 
04421    ast_variables_destroy(var);
04422 
04423    if (!peer)
04424       return NULL;
04425 
04426    if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04427       ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04428       if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
04429          if (peer->expire > -1) {
04430             if (!ast_sched_thread_del(sched, peer->expire)) {
04431                peer->expire = -1;
04432                peer_unref(peer);
04433             }
04434          }
04435          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04436          if (peer->expire == -1)
04437             peer_unref(peer);
04438       }
04439       ao2_link(peers, peer);
04440       if (ast_test_flag64(peer, IAX_DYNAMIC))
04441          reg_source_db(peer);
04442    } else {
04443       ast_set_flag64(peer, IAX_TEMPONLY);
04444    }
04445 
04446    if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04447       time(&nowtime);
04448       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04449          memset(&peer->addr, 0, sizeof(peer->addr));
04450          realtime_update_peer(peer->name, &peer->addr, 0);
04451          ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04452             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04453       }
04454       else {
04455          ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04456             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04457       }
04458    }
04459 
04460    return peer;
04461 }

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

Definition at line 4534 of file chan_iax2.c.

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

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

04535 {
04536    char port[10];
04537    char regseconds[20];
04538    const char *sysname = ast_config_AST_SYSTEM_NAME;
04539    char *syslabel = NULL;
04540 
04541    if (ast_strlen_zero(sysname)) /* No system name, disable this */
04542       sysname = NULL;
04543    else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME))
04544       syslabel = "regserver";
04545 
04546    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04547    snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
04548    ast_update_realtime("iaxpeers", "name", peername, 
04549       "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 
04550       "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */
04551 }

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

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

Referenced by calltoken_required(), and check_access().

04464 {
04465    struct ast_variable *var;
04466    struct ast_variable *tmp;
04467    struct iax2_user *user=NULL;
04468 
04469    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04470    if (!var)
04471       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04472    if (!var && sin) {
04473       char porta[6];
04474       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04475       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04476       if (!var)
04477          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04478    }
04479    if (!var) { /* Last ditch effort */
04480       var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04481       /*!\note
04482        * If this one loaded something, then we need to ensure that the host
04483        * field matched.  The only reason why we can't have this as a criteria
04484        * is because we only have the IP address and the host field might be
04485        * set as a name (and the reverse PTR might not match).
04486        */
04487       if (var) {
04488          for (tmp = var; tmp; tmp = tmp->next) {
04489             if (!strcasecmp(tmp->name, "host")) {
04490                struct ast_hostent ahp;
04491                struct hostent *hp;
04492                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) {
04493                   /* No match */
04494                   ast_variables_destroy(var);
04495                   var = NULL;
04496                }
04497                break;
04498             }
04499          }
04500       }
04501    }
04502    if (!var)
04503       return NULL;
04504 
04505    tmp = var;
04506    while(tmp) {
04507       /* Make sure it's not a peer only... */
04508       if (!strcasecmp(tmp->name, "type")) {
04509          if (strcasecmp(tmp->value, "friend") &&
04510              strcasecmp(tmp->value, "user")) {
04511             return NULL;
04512          } 
04513       }
04514       tmp = tmp->next;
04515    }
04516 
04517    user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS));
04518 
04519    ast_variables_destroy(var);
04520 
04521    if (!user)
04522       return NULL;
04523 
04524    if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04525       ast_set_flag64(user, IAX_RTCACHEFRIENDS);
04526       ao2_link(users, user);
04527    } else {
04528       ast_set_flag64(user, IAX_TEMPONLY);
04529    }
04530 
04531    return user;
04532 }

static void reg_source_db ( struct iax2_peer p  )  [static]

Definition at line 8682 of file chan_iax2.c.

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

Referenced by realtime_peer(), and set_config().

08683 {
08684    char data[80];
08685    char *expiry;
08686 
08687    if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08688       return;
08689    }
08690 
08691    expiry = strrchr(data, ':');
08692    if (!expiry) {
08693       ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08694       return;
08695    }
08696    *expiry++ = '\0';
08697 
08698    if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08699       ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08700       return;
08701    }
08702 
08703    p->expiry = atoi(expiry);
08704 
08705    ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08706       ast_sockaddr_stringify(&p->addr), p->expiry);
08707 
08708    iax2_poke_peer(p, 0);
08709    if (p->expire > -1) {
08710       if (!ast_sched_thread_del(sched, p->expire)) {
08711          p->expire = -1;
08712          peer_unref(p);
08713       }
08714    }
08715 
08716    ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
08717 
08718    p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08719    if (p->expire == -1) {
08720       peer_unref(p);
08721    }
08722 
08723    if (iax2_regfunk) {
08724       iax2_regfunk(p->name, 1);
08725    }
08726 
08727    register_peer_exten(p, 1);
08728 }

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

Definition at line 8599 of file chan_iax2.c.

References ast_add_extension(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr(), ast_strdup, ast_strlen_zero(), ext, and S_OR.

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

08600 {
08601    char multi[256];
08602    char *stringp, *ext;
08603    if (!ast_strlen_zero(regcontext)) {
08604       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08605       stringp = multi;
08606       while((ext = strsep(&stringp, "&"))) {
08607          if (onoff) {
08608             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08609                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08610                        "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08611          } else
08612             ast_context_remove_extension(regcontext, ext, 1, NULL);
08613       }
08614    }
08615 }

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

Verify inbound registration.

Definition at line 7970 of file chan_iax2.c.

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

Referenced by socket_process().

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

static int registry_authrequest ( int  callno  )  [static]

Definition at line 8907 of file chan_iax2.c.

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

Referenced by socket_process().

08908 {
08909    struct iax_ie_data ied;
08910    struct iax2_peer *p;
08911    char challenge[10];
08912    const char *peer_name;
08913    int sentauthmethod;
08914 
08915    peer_name = ast_strdupa(iaxs[callno]->peer);
08916 
08917    /* SLD: third call to find_peer in registration */
08918    ast_mutex_unlock(&iaxsl[callno]);
08919    if ((p = find_peer(peer_name, 1))) {
08920       last_authmethod = p->authmethods;
08921    }
08922 
08923    ast_mutex_lock(&iaxsl[callno]);
08924    if (!iaxs[callno])
08925       goto return_unref;
08926 
08927    memset(&ied, 0, sizeof(ied));
08928    /* The selection of which delayed reject is sent may leak information,
08929     * if it sets a static response.  For example, if a host is known to only
08930     * use MD5 authentication, then an RSA response would indicate that the
08931     * peer does not exist, and vice-versa.
08932     * Therefore, we use whatever the last peer used (which may vary over the
08933     * course of a server, which should leak minimal information). */
08934    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08935    if (!p) {
08936       iaxs[callno]->authmethods = sentauthmethod;
08937    }
08938    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08939    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08940       /* Build the challenge */
08941       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08942       ast_string_field_set(iaxs[callno], challenge, challenge);
08943       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08944    }
08945    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08946 
08947 return_unref:
08948    if (p) {
08949       peer_unref(p);
08950    }
08951 
08952    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08953 }

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

Definition at line 8955 of file chan_iax2.c.

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

Referenced by socket_process().

08956 {
08957    struct iax2_registry *reg;
08958    /* Start pessimistic */
08959    struct iax_ie_data ied;
08960    char peer[256] = "";
08961    char challenge[256] = "";
08962    int res;
08963    int authmethods = 0;
08964    if (ies->authmethods)
08965       authmethods = ies->authmethods;
08966    if (ies->username)
08967       ast_copy_string(peer, ies->username, sizeof(peer));
08968    if (ies->challenge)
08969       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08970    memset(&ied, 0, sizeof(ied));
08971    reg = iaxs[callno]->reg;
08972    if (reg) {
08973       struct sockaddr_in reg_addr;
08974 
08975       ast_sockaddr_to_sin(&reg->addr, &reg_addr);
08976 
08977       if (inaddrcmp(&reg_addr, sin)) {
08978          ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08979          return -1;
08980       }
08981       if (ast_strlen_zero(reg->secret)) {
08982          ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08983          reg->regstate = REG_STATE_NOAUTH;
08984          return -1;
08985       }
08986       iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08987       iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08988       if (reg->secret[0] == '[') {
08989          char tmpkey[256];
08990          ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08991          tmpkey[strlen(tmpkey) - 1] = '\0';
08992          res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08993       } else
08994          res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08995       if (!res) {
08996          reg->regstate = REG_STATE_AUTHSENT;
08997          add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
08998          return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08999       } else
09000          return -1;
09001       ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
09002    } else   
09003       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
09004    return -1;
09005 }

static char* regstate2str ( int  regstate  )  [static]

Definition at line 7079 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_show_registry(), and manager_iax2_show_registry().

07080 {
07081    switch(regstate) {
07082    case REG_STATE_UNREGISTERED:
07083       return "Unregistered";
07084    case REG_STATE_REGSENT:
07085       return "Request Sent";
07086    case REG_STATE_AUTHSENT:
07087       return "Auth. Sent";
07088    case REG_STATE_REGISTERED:
07089       return "Registered";
07090    case REG_STATE_REJECTED:
07091       return "Rejected";
07092    case REG_STATE_TIMEOUT:
07093       return "Timeout";
07094    case REG_STATE_NOAUTH:
07095       return "No Authentication";
07096    default:
07097       return "Unknown";
07098    }
07099 }

static int reload ( void   )  [static]

Definition at line 13664 of file chan_iax2.c.

References reload_config().

13665 {
13666    return reload_config();
13667 }

static int reload_config ( void   )  [static]

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

13616 {
13617    static const char config[] = "iax.conf";
13618    struct iax2_registry *reg;
13619 
13620    if (set_config(config, 1) > 0) {
13621       prune_peers();
13622       prune_users();
13623       ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13624       ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13625       ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13626       trunk_timed = trunk_untimed = 0; 
13627       trunk_nmaxmtu = trunk_maxmtu = 0;
13628       memset(&debugaddr, '\0', sizeof(debugaddr));
13629 
13630       AST_LIST_LOCK(&registrations);
13631       AST_LIST_TRAVERSE(&registrations, reg, entry)
13632          iax2_do_register(reg);
13633       AST_LIST_UNLOCK(&registrations);
13634 
13635       /* Qualify hosts, too */
13636       poke_all_peers();
13637    }
13638    
13639    reload_firmware(0);
13640    iax_provision_reload(1);
13641    ast_unload_realtime("iaxpeers");
13642 
13643    return 0;
13644 }

static void reload_firmware ( int  unload  )  [static]

Definition at line 3222 of file chan_iax2.c.

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

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

03223 {
03224    struct iax_firmware *cur = NULL;
03225    DIR *fwd;
03226    struct dirent *de;
03227    char dir[256], fn[256];
03228 
03229    AST_LIST_LOCK(&firmwares);
03230 
03231    /* Mark all as dead */
03232    AST_LIST_TRAVERSE(&firmwares, cur, list)
03233       cur->dead = 1;
03234 
03235    /* Now that we have marked them dead... load new ones */
03236    if (!unload) {
03237       snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03238       fwd = opendir(dir);
03239       if (fwd) {
03240          while((de = readdir(fwd))) {
03241             if (de->d_name[0] != '.') {
03242                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03243                if (!try_firmware(fn)) {
03244                   ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03245                }
03246             }
03247          }
03248          closedir(fwd);
03249       } else 
03250          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03251    }
03252 
03253    /* Clean up leftovers */
03254    AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03255       if (!cur->dead)
03256          continue;
03257       AST_LIST_REMOVE_CURRENT(list);
03258       destroy_firmware(cur);
03259    }
03260    AST_LIST_TRAVERSE_SAFE_END;
03261 
03262    AST_LIST_UNLOCK(&firmwares);
03263 }

static void remove_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2140 of file chan_iax2.c.

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

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

02141 {
02142    if (!pvt->peercallno) {
02143       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02144       return;
02145    }
02146 
02147    ao2_unlink(iax_peercallno_pvts, pvt);
02148 }

static void remove_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2121 of file chan_iax2.c.

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

Referenced by complete_transfer(), and iax2_destroy().

02122 {
02123    if (!pvt->transfercallno) {
02124       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02125       return;
02126    }
02127 
02128    ao2_unlink(iax_transfercallno_pvts, pvt);
02129 }

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

Definition at line 2657 of file chan_iax2.c.

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

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

02658 {
02659    struct callno_entry *callno_entry = (struct callno_entry *) obj;
02660 
02661    /* the callno_pool container is locked here primarily to ensure thread
02662     * safety of the total_nonval_callno_used check and decrement */
02663    ao2_lock(callno_pool);
02664 
02665    if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02666       total_nonval_callno_used--;
02667    } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02668       ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02669    }
02670 
02671    if (callno_entry->callno < TRUNK_CALL_START) {
02672       ao2_link(callno_pool, callno_entry);
02673    } else {
02674       ao2_link(callno_pool_trunk, callno_entry);
02675    }
02676    ao2_ref(callno_entry, -1); /* only container ref remains */
02677 
02678    ao2_unlock(callno_pool);
02679    return 0;
02680 }

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

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

04844 {
04845    struct iax2_user *user = NULL;
04846    struct iax2_peer *peer = NULL;
04847 
04848    if (ast_strlen_zero(name)) {
04849       return; /* no username given */
04850    }
04851 
04852    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04853       user->calltoken_required = CALLTOKEN_YES;
04854    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04855       peer->calltoken_required = CALLTOKEN_YES;
04856    }
04857 
04858    if (peer) {
04859       peer_unref(peer);
04860    }
04861    if (user) {
04862       user_unref(user);
04863    }
04864 }

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

Definition at line 4761 of file chan_iax2.c.

References iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_LIST_REMOVE, iax_ie_data::buf, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, iax_frame::encmethods, ast_frame::frametype, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, iaxs, ast_frame_subclass::integer, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, remove_by_peercallno(), chan_iax2_pvt::rseqno, send_command(), and ast_frame::subclass.

Referenced by socket_process().

04762 {
04763    struct chan_iax2_pvt *pvt = iaxs[callno];
04764    int frametype = f->af.frametype;
04765    int subclass = f->af.subclass.integer;
04766    struct {
04767       struct ast_iax2_full_hdr fh;
04768       struct iax_ie_data ied;
04769    } data = {
04770       .ied.buf = { 0 },
04771       .ied.pos = 0,
04772    };
04773    /* total len - header len gives us the frame's IE len */
04774    int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04775 
04776    if (!pvt) {
04777       return;  /* this should not be possible if called from socket_process() */
04778    }
04779 
04780    /* 
04781     * Check to make sure last frame sent is valid for call token resend
04782     * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 
04783     * 2. Frame should _NOT_ already have a destination callno
04784     * 3. Frame must be a valid iax_frame subclass capable of starting dialog
04785     * 4. Pvt must have a calltoken_ie_len which represents the number of
04786     *    bytes at the end of the frame used for the previous calltoken ie.
04787     * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length
04788     * 6. Total length of f->data must be _LESS_ than size of our data struct
04789     *    because f->data must be able to fit within data. 
04790     */
04791    if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04792       || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04793       (f->datalen > sizeof(data))) {
04794 
04795       return;  /* ignore resend, token was not valid for the dialog */
04796    }
04797 
04798    /* token is valid
04799     * 1. Copy frame data over
04800     * 2. Redo calltoken IE, it will always be the last ie in the frame.
04801     *    NOTE: Having the ie always be last is not protocol specified,
04802     *    it is only an implementation choice.  Since we only expect the ie to
04803     *    be last for frames we have sent, this can no way be affected by
04804     *    another end point.
04805     * 3. Remove frame from queue
04806     * 4. Free old frame
04807     * 5. Clear previous seqnos
04808     * 6. Resend with CALLTOKEN ie.
04809     */
04810 
04811    /* ---1.--- */
04812    memcpy(&data, f->data, f->datalen);
04813    data.ied.pos = ie_data_pos;
04814 
04815    /* ---2.--- */
04816    /* move to the beginning of the calltoken ie so we can write over it */
04817    data.ied.pos -= pvt->calltoken_ie_len;
04818    iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04819 
04820    /* make sure to update token length incase it ever has to be stripped off again */
04821    pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */
04822 
04823    /* ---3.--- */
04824    AST_LIST_REMOVE(&frame_queue[callno], f, list);
04825 
04826    /* ---4.--- */
04827    iax2_frame_free(f);
04828 
04829    /* ---5.--- */
04830    pvt->oseqno = 0;
04831    pvt->rseqno = 0;
04832    pvt->iseqno = 0;
04833    pvt->aseqno = 0;
04834    if (pvt->peercallno) {
04835       remove_by_peercallno(pvt);
04836       pvt->peercallno = 0;
04837    }
04838 
04839    /* ---6.--- */
04840    send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04841 }

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

Definition at line 9486 of file chan_iax2.c.

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

Referenced by socket_process().

09487 {
09488    int i;
09489    unsigned int length, offset = 0;
09490    char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09491 
09492    for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09493       length = ies->ospblocklength[i];
09494       if (length != 0) {
09495          if (length > IAX_MAX_OSPBLOCK_SIZE) {
09496             /* OSP token block length wrong, clear buffer */
09497             offset = 0;
09498             break;
09499          } else {
09500             memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09501             offset += length;
09502          }
09503       } else {
09504          break;
09505       }
09506    }
09507    *(full_osptoken + offset) = '\0';
09508    if (strlen(full_osptoken) != offset) {
09509       /* OSP token length wrong, clear buffer */
09510       *full_osptoken = '\0';
09511    }
09512 
09513    ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09514 }

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

Definition at line 9475 of file chan_iax2.c.

References iax_frame::callno, iaxs, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, and iax_ies::rr_pkts.

Referenced by socket_process().

09476 {
09477    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09478    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09479    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09480    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09481    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09482    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09483    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09484 }

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

Definition at line 2729 of file chan_iax2.c.

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

Referenced by pvt_destructor().

02730 {
02731    int i;
02732    struct peercnt *peercnt;
02733    struct peercnt tmp = {
02734       .addr = sin->sin_addr.s_addr,
02735    };
02736 
02737    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02738       /* refcount is incremented with ao2_find.  keep that ref for the scheduler */
02739       ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02740       i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02741       if (i == -1) {
02742          ao2_ref(peercnt, -1);
02743       }
02744    }
02745 
02746    iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02747 }

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

References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_channel_unlock, ast_codec_get_samples(), ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_samp2tv(), ast_sched_thread_del, ast_test_flag64, ast_tv(), ast_tvadd(), ast_tvzero(), ast_channel::bridge, calc_rxstamp(), iax_frame::callno, ast_frame_subclass::codec, jb_frame::data, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_lock_owner(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, len(), chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, ast_frame::subclass, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().

Referenced by socket_process(), and socket_process_meta().

04161 {
04162    int type, len;
04163    int ret;
04164    int needfree = 0;
04165    struct ast_channel *owner = NULL;
04166    struct ast_channel *bridge = NULL;
04167 
04168    /*
04169     * Clear fr->af.data if there is no data in the buffer.  Things
04170     * like AST_CONTROL_HOLD without a suggested music class must
04171     * have a NULL pointer.
04172     */
04173    if (!fr->af.datalen) {
04174       memset(&fr->af.data, 0, sizeof(fr->af.data));
04175    }
04176 
04177    /* Attempt to recover wrapped timestamps */
04178    unwrap_timestamp(fr);
04179 
04180    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
04181    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04182       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04183    else {
04184 #if 0
04185       ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04186 #endif
04187       fr->af.delivery = ast_tv(0,0);
04188    }
04189 
04190    type = JB_TYPE_CONTROL;
04191    len = 0;
04192 
04193    if(fr->af.frametype == AST_FRAME_VOICE) {
04194       type = JB_TYPE_VOICE;
04195       len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000);
04196    } else if(fr->af.frametype == AST_FRAME_CNG) {
04197       type = JB_TYPE_SILENCE;
04198    }
04199 
04200    if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04201       if (tsout)
04202          *tsout = fr->ts;
04203       __do_deliver(fr);
04204       return -1;
04205    }
04206 
04207    iax2_lock_owner(fr->callno);
04208    if (!iaxs[fr->callno]) {
04209       /* The call dissappeared so discard this frame that we could not send. */
04210       iax2_frame_free(fr);
04211       return -1;
04212    }
04213    if ((owner = iaxs[fr->callno]->owner))
04214       bridge = ast_bridged_channel(owner);
04215 
04216    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
04217     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
04218    if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04219       jb_frame frame;
04220 
04221       ast_channel_unlock(owner);
04222 
04223       /* deliver any frames in the jb */
04224       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04225          __do_deliver(frame.data);
04226          /* __do_deliver() can make the call disappear */
04227          if (!iaxs[fr->callno])
04228             return -1;
04229       }
04230 
04231       jb_reset(iaxs[fr->callno]->jb);
04232 
04233       ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04234 
04235       /* deliver this frame now */
04236       if (tsout)
04237          *tsout = fr->ts;
04238       __do_deliver(fr);
04239       return -1;
04240    }
04241    if (owner) {
04242       ast_channel_unlock(owner);
04243    }
04244 
04245    /* insert into jitterbuffer */
04246    /* TODO: Perhaps we could act immediately if it's not droppable and late */
04247    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04248          calc_rxstamp(iaxs[fr->callno],fr->ts));
04249    if (ret == JB_DROP) {
04250       needfree++;
04251    } else if (ret == JB_SCHED) {
04252       update_jbsched(iaxs[fr->callno]);
04253    }
04254    if (tsout)
04255       *tsout = fr->ts;
04256    if (needfree) {
04257       /* Free our iax frame */
04258       iax2_frame_free(fr);
04259       return -1;
04260    }
04261    return 0;
04262 }

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

Definition at line 1806 of file chan_iax2.c.

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

Referenced by iax2_hangup().

01807 {
01808    unsigned short callno = PTR_TO_CALLNO(vid);
01809    ast_mutex_lock(&iaxsl[callno]);
01810    if (iaxs[callno]) {
01811       if (option_debug) {
01812          ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01813       }
01814       iax2_destroy(callno);
01815    }
01816    ast_mutex_unlock(&iaxsl[callno]);
01817    return 0;
01818 }

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

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

Referenced by handle_call_token(), and socket_process().

04726 {
04727    struct {
04728       struct ast_iax2_full_hdr f;
04729       struct iax_ie_data ied;
04730    } data;
04731    size_t size = sizeof(struct ast_iax2_full_hdr);
04732 
04733    if (ied) {
04734       size += ied->pos;
04735       memcpy(&data.ied, ied->buf, ied->pos);
04736    }
04737 
04738    data.f.scallno = htons(0x8000 | callno);
04739    data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS);
04740    data.f.ts = htonl(ts);
04741    data.f.iseqno = seqno;
04742    data.f.oseqno = 0;
04743    data.f.type = AST_FRAME_IAX;
04744    data.f.csub = compress_subclass(command);
04745 
04746    iax_outputframe(NULL, &data.f, 0, sin, size - sizeof(struct ast_iax2_full_hdr));
04747 
04748    return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04749 }

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

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

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

07538 {
07539    int call_num = i->callno;
07540    /* It is assumed that the callno has already been locked */
07541    iax2_predestroy(i->callno);
07542    if (!iaxs[call_num])
07543       return -1;
07544    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07545 }

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

References __send_command().

Referenced by iax2_vnak(), and socket_process().

07548 {
07549    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07550 }

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

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

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

07524 {
07525    int res;
07526    ast_mutex_lock(&iaxsl[callno]);
07527    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07528    ast_mutex_unlock(&iaxsl[callno]);
07529    return res;
07530 }

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

References __send_command().

Referenced by socket_process(), and try_transfer().

07553 {
07554    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07555 }

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

Definition at line 1592 of file chan_iax2.c.

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

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

01593 {
01594    int callno = (long) data;
01595    ast_mutex_lock(&iaxsl[callno]);
01596    if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) {
01597       iaxs[callno]->lagid = -1;
01598    }
01599    ast_mutex_unlock(&iaxsl[callno]);
01600 
01601 #ifdef SCHED_MULTITHREADED
01602    if (schedule_action(__send_lagrq, data))
01603 #endif
01604       __send_lagrq(data);
01605    return 0;
01606 }

static int send_packet ( struct iax_frame f  )  [static]

Definition at line 3335 of file chan_iax2.c.

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

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

03336 {
03337    int res;
03338    int callno = f->callno;
03339 
03340    /* Don't send if there was an error, but return error instead */
03341    if (!callno || !iaxs[callno] || iaxs[callno]->error)
03342        return -1;
03343    
03344    /* Called with iaxsl held */
03345    if (iaxdebug)
03346       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));
03347    
03348    if (f->transfer) {
03349       iax_outputframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03350       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03351    } else {
03352       iax_outputframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03353       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03354    }
03355    if (res < 0) {
03356       if (iaxdebug)
03357          ast_debug(1, "Received error: %s\n", strerror(errno));
03358       handle_error();
03359    } else
03360       res = 0;
03361 
03362    return res;
03363 }

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

Definition at line 1525 of file chan_iax2.c.

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

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

01526 {
01527    int callno = (long) data;
01528    ast_mutex_lock(&iaxsl[callno]);
01529    if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) {
01530       iaxs[callno]->pingid = -1;
01531    }
01532    ast_mutex_unlock(&iaxsl[callno]);
01533 
01534 #ifdef SCHED_MULTITHREADED
01535    if (schedule_action(__send_ping, data))
01536 #endif
01537       __send_ping(data);
01538 
01539    return 0;
01540 }

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

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

Referenced by socket_process().

01831 {
01832    struct signaling_queue_entry *s = NULL;
01833 
01834    while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01835       iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01836       free_signaling_queue_entry(s);
01837    }
01838    pvt->hold_signaling = 0;
01839 }

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

Definition at line 9139 of file chan_iax2.c.

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

Referenced by iax2_trunk_queue(), and timing_read().

09140 {
09141    int res = 0;
09142    struct iax_frame *fr;
09143    struct ast_iax2_meta_hdr *meta;
09144    struct ast_iax2_meta_trunk_hdr *mth;
09145    int calls = 0;
09146    
09147    /* Point to frame */
09148    fr = (struct iax_frame *)tpeer->trunkdata;
09149    /* Point to meta data */
09150    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09151    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09152    if (tpeer->trunkdatalen) {
09153       /* We're actually sending a frame, so fill the meta trunk header and meta header */
09154       meta->zeros = 0;
09155       meta->metacmd = IAX_META_TRUNK;
09156       if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09157          meta->cmddata = IAX_META_TRUNK_MINI;
09158       else
09159          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09160       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09161       /* And the rest of the ast_iax2 header */
09162       fr->direction = DIRECTION_OUTGRESS;
09163       fr->retrans = -1;
09164       fr->transfer = 0;
09165       /* Any appropriate call will do */
09166       fr->data = fr->afdata;
09167       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09168       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09169       calls = tpeer->calls;
09170 #if 0
09171       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));
09172 #endif      
09173       /* Reset transmit trunk side data */
09174       tpeer->trunkdatalen = 0;
09175       tpeer->calls = 0;
09176    }
09177    if (res < 0)
09178       return res;
09179    return calls;
09180 }

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

Load configuration.

Definition at line 13119 of file chan_iax2.c.

References add_calltoken_ignore(), ao2_link, ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_clear_flag64, ast_config_destroy(), ast_config_load, ast_context_find_or_create(), ast_copy_string(), ast_false(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_test_flag64, ast_timer_set_rate(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, build_callno_limits(), build_peer(), build_user(), capability, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTSAVE_SYSNAME, IAX_RTUPDATE, IAX_SENDCONNECTEDLINE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_TRUNK_MTU, MAX_TRUNKDATA, ast_variable::name, network_change_event_subscribe(), network_change_event_unsubscribe(), ast_variable::next, peer_unref(), prefs, qos, reg_source_db(), secret, set_config_destroy(), socket_read(), user_unref(), and ast_variable::value.

Referenced by load_module(), and reload_config().

13120 {
13121    struct ast_config *cfg, *ucfg;
13122    format_t capability = iax2_capability;
13123    struct ast_variable *v;
13124    char *cat;
13125    const char *utype;
13126    const char *tosval;
13127    int format;
13128    int portno = IAX_DEFAULT_PORTNO;
13129    int  x;
13130    int mtuv;
13131    int subscribe_network_change = 1;
13132    struct iax2_user *user;
13133    struct iax2_peer *peer;
13134    struct ast_netsock *ns;
13135    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13136 #if 0
13137    static unsigned short int last_port=0;
13138 #endif
13139 
13140    cfg = ast_config_load(config_file, config_flags);
13141 
13142    if (!cfg) {
13143       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13144       return -1;
13145    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13146       ucfg = ast_config_load("users.conf", config_flags);
13147       if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13148          return 0;
13149       /* Otherwise we need to reread both files */
13150       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13151       if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13152          ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config_file);
13153          ast_config_destroy(ucfg);
13154          return 0;
13155       }
13156       if (!cfg) {
13157          /* should have been able to load the config here */
13158          ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file);
13159          return -1;
13160       }
13161    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13162       ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config_file);
13163       return 0;
13164    } else { /* iax.conf changed, gotta reread users.conf, too */
13165       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13166       if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13167          ast_log(LOG_ERROR, "Config file users.conf is in an invalid format.  Aborting.\n");
13168          ast_config_destroy(cfg);
13169          return 0;
13170       }
13171    }
13172 
13173    if (reload) {
13174       set_config_destroy();
13175    }
13176 
13177    /* Reset global codec prefs */
13178    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
13179 
13180    /* Reset Global Flags */
13181    memset(&globalflags, 0, sizeof(globalflags));
13182    ast_set_flag64(&globalflags, IAX_RTUPDATE);
13183    ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13184 
13185 #ifdef SO_NO_CHECK
13186    nochecksums = 0;
13187 #endif
13188    /* Reset default parking lot */
13189    default_parkinglot[0] = '\0';
13190 
13191    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13192    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13193    global_max_trunk_mtu = MAX_TRUNK_MTU;
13194    global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
13195    global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
13196 
13197    maxauthreq = 3;
13198 
13199    srvlookup = 0;
13200 
13201    v = ast_variable_browse(cfg, "general");
13202 
13203    /* Seed initial tos value */
13204    tosval = ast_variable_retrieve(cfg, "general", "tos");
13205    if (tosval) {
13206       if (ast_str2tos(tosval, &qos.tos))
13207          ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13208    }
13209    /* Seed initial cos value */
13210    tosval = ast_variable_retrieve(cfg, "general", "cos");
13211    if (tosval) {
13212       if (ast_str2cos(tosval, &qos.cos))
13213          ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13214    }
13215    while(v) {
13216       if (!strcasecmp(v->name, "bindport")){ 
13217          if (reload)
13218             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13219          else
13220             portno = atoi(v->value);
13221       } else if (!strcasecmp(v->name, "pingtime")) 
13222          ping_time = atoi(v->value);
13223       else if (!strcasecmp(v->name, "iaxthreadcount")) {
13224          if (reload) {
13225             if (atoi(v->value) != iaxthreadcount)
13226                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13227          } else {
13228             iaxthreadcount = atoi(v->value);
13229             if (iaxthreadcount < 1) {
13230                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13231                iaxthreadcount = 1;
13232             } else if (iaxthreadcount > 256) {
13233                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13234                iaxthreadcount = 256;
13235             }
13236          }
13237       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13238          if (reload) {
13239             AST_LIST_LOCK(&dynamic_list);
13240             iaxmaxthreadcount = atoi(v->value);
13241             AST_LIST_UNLOCK(&dynamic_list);
13242          } else {
13243             iaxmaxthreadcount = atoi(v->value);
13244             if (iaxmaxthreadcount < 0) {
13245                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13246                iaxmaxthreadcount = 0;
13247             } else if (iaxmaxthreadcount > 256) {
13248                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13249                iaxmaxthreadcount = 256;
13250             }
13251          }
13252       } else if (!strcasecmp(v->name, "nochecksums")) {
13253 #ifdef SO_NO_CHECK
13254          if (ast_true(v->value))
13255             nochecksums = 1;
13256          else
13257             nochecksums = 0;
13258 #else
13259          if (ast_true(v->value))
13260             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13261 #endif
13262       }
13263       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
13264          maxjitterbuffer = atoi(v->value);
13265       else if (!strcasecmp(v->name, "resyncthreshold")) 
13266          resyncthreshold = atoi(v->value);
13267       else if (!strcasecmp(v->name, "maxjitterinterps")) 
13268          maxjitterinterps = atoi(v->value);
13269       else if (!strcasecmp(v->name, "jittertargetextra"))
13270          jittertargetextra = atoi(v->value);
13271       else if (!strcasecmp(v->name, "lagrqtime")) 
13272          lagrq_time = atoi(v->value);
13273       else if (!strcasecmp(v->name, "maxregexpire")) 
13274          max_reg_expire = atoi(v->value);
13275       else if (!strcasecmp(v->name, "minregexpire")) 
13276          min_reg_expire = atoi(v->value);
13277       else if (!strcasecmp(v->name, "bindaddr")) {
13278          if (reload) {
13279             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13280          } else {
13281             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13282                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13283             } else {
13284                   if (strchr(v->value, ':'))
13285                   ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13286                   else
13287                   ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13288                if (defaultsockfd < 0) 
13289                   defaultsockfd = ast_netsock_sockfd(ns);
13290                ast_netsock_unref(ns);
13291             }
13292          }
13293       } else if (!strcasecmp(v->name, "authdebug")) {
13294          authdebug = ast_true(v->value);
13295       } else if (!strcasecmp(v->name, "encryption")) {
13296             iax2_encryption |= get_encrypt_methods(v->value);
13297             if (!iax2_encryption) {
13298                ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13299             }
13300       } else if (!strcasecmp(v->name, "forceencryption")) {
13301          if (ast_false(v->value)) {
13302             ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13303          } else {
13304             iax2_encryption |= get_encrypt_methods(v->value);
13305             if (iax2_encryption) {
13306                ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13307             }
13308          }
13309       } else if (!strcasecmp(v->name, "transfer")) {
13310          if (!strcasecmp(v->value, "mediaonly")) {
13311             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13312          } else if (ast_true(v->value)) {
13313             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13314          } else
13315             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13316       } else if (!strcasecmp(v->name, "codecpriority")) {
13317          if(!strcasecmp(v->value, "caller"))
13318             ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13319          else if(!strcasecmp(v->value, "disabled"))
13320             ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13321          else if(!strcasecmp(v->value, "reqonly")) {
13322             ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13323             ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13324          }
13325       } else if (!strcasecmp(v->name, "jitterbuffer"))
13326          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13327       else if (!strcasecmp(v->name, "forcejitterbuffer"))
13328          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13329       else if (!strcasecmp(v->name, "delayreject"))
13330          delayreject = ast_true(v->value);
13331       else if (!strcasecmp(v->name, "allowfwdownload"))
13332          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13333       else if (!strcasecmp(v->name, "rtcachefriends"))
13334          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13335       else if (!strcasecmp(v->name, "rtignoreregexpire"))
13336          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13337       else if (!strcasecmp(v->name, "rtupdate"))
13338          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13339       else if (!strcasecmp(v->name, "rtsavesysname"))
13340          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13341       else if (!strcasecmp(v->name, "trunktimestamps"))
13342          ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13343       else if (!strcasecmp(v->name, "rtautoclear")) {
13344          int i = atoi(v->value);
13345          if(i > 0)
13346             global_rtautoclear = i;
13347          else
13348             i = 0;
13349          ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13350       } else if (!strcasecmp(v->name, "trunkfreq")) {
13351          trunkfreq = atoi(v->value);
13352          if (trunkfreq < 10) {
13353             ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n");
13354             trunkfreq = 10;
13355          } else if (trunkfreq > 1000) {
13356             ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n");
13357             trunkfreq = 1000;
13358          }
13359          if (timer) {
13360             ast_timer_set_rate(timer, 1000 / trunkfreq);
13361          }
13362       } else if (!strcasecmp(v->name, "trunkmtu")) {
13363          mtuv = atoi(v->value);
13364          if (mtuv  == 0 )
13365             global_max_trunk_mtu = 0;
13366          else if (mtuv >= 172 && mtuv < 4000)
13367             global_max_trunk_mtu = mtuv;
13368          else
13369             ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13370                mtuv, v->lineno);
13371       } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13372          trunkmaxsize = atoi(v->value);
13373          if (trunkmaxsize == 0)
13374             trunkmaxsize = MAX_TRUNKDATA;
13375       } else if (!strcasecmp(v->name, "autokill")) {
13376          if (sscanf(v->value, "%30d", &x) == 1) {
13377             if (x >= 0)
13378                autokill = x;
13379             else
13380                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13381          } else if (ast_true(v->value)) {
13382             autokill = DEFAULT_MAXMS;
13383          } else {
13384             autokill = 0;
13385          }
13386       } else if (!strcasecmp(v->name, "bandwidth")) {
13387          if (!strcasecmp(v->value, "low")) {
13388             capability = IAX_CAPABILITY_LOWBANDWIDTH;
13389          } else if (!strcasecmp(v->value, "medium")) {
13390             capability = IAX_CAPABILITY_MEDBANDWIDTH;
13391          } else if (!strcasecmp(v->value, "high")) {
13392             capability = IAX_CAPABILITY_FULLBANDWIDTH;
13393          } else
13394             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13395       } else if (!strcasecmp(v->name, "allow")) {
13396          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13397       } else if (!strcasecmp(v->name, "disallow")) {
13398          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13399       } else if (!strcasecmp(v->name, "register")) {
13400          iax2_register(v->value, v->lineno);
13401       } else if (!strcasecmp(v->name, "iaxcompat")) {
13402          iaxcompat = ast_true(v->value);
13403       } else if (!strcasecmp(v->name, "regcontext")) {
13404          ast_copy_string(regcontext, v->value, sizeof(regcontext));
13405          /* Create context if it doesn't exist already */
13406          ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13407       } else if (!strcasecmp(v->name, "tos")) {
13408          if (ast_str2tos(v->value, &qos.tos))
13409             ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13410       } else if (!strcasecmp(v->name, "cos")) {
13411          if (ast_str2cos(v->value, &qos.cos))
13412             ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13413       } else if (!strcasecmp(v->name, "parkinglot")) {
13414          ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13415       } else if (!strcasecmp(v->name, "accountcode")) {
13416          ast_copy_string(accountcode, v->value, sizeof(accountcode));
13417       } else if (!strcasecmp(v->name, "mohinterpret")) {
13418          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13419       } else if (!strcasecmp(v->name, "mohsuggest")) {
13420          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13421       } else if (!strcasecmp(v->name, "amaflags")) {
13422          format = ast_cdr_amaflags2int(v->value);
13423          if (format < 0) {
13424             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13425          } else {
13426             amaflags = format;
13427          }
13428       } else if (!strcasecmp(v->name, "language")) {
13429          ast_copy_string(language, v->value, sizeof(language));
13430       } else if (!strcasecmp(v->name, "maxauthreq")) {
13431          maxauthreq = atoi(v->value);
13432          if (maxauthreq < 0)
13433             maxauthreq = 0;
13434       } else if (!strcasecmp(v->name, "adsi")) {
13435          adsi = ast_true(v->value);
13436       } else if (!strcasecmp(v->name, "srvlookup")) {
13437          srvlookup = ast_true(v->value);
13438       } else if (!strcasecmp(v->name, "connectedline")) {
13439          if (ast_true(v->value)) {
13440             ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13441          } else if (!strcasecmp(v->value, "send")) {
13442             ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13443             ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13444          } else if (!strcasecmp(v->value, "receive")) {
13445             ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13446             ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13447          } else {
13448             ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13449          }
13450       } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13451          if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13452             ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number.  %s is not valid at line %d\n", v->value, v->lineno);
13453          }
13454       } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13455          if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13456             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);
13457          }
13458       } else if (!strcasecmp(v->name, "calltokenoptional")) {
13459          if (add_calltoken_ignore(v->value)) {
13460             ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13461          }
13462       } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13463          if (ast_true(v->value)) {
13464             subscribe_network_change = 1;
13465          } else if (ast_false(v->value)) {
13466             subscribe_network_change = 0;
13467          } else {
13468             ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13469          }
13470       } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13471          if (ast_true(v->value)) {
13472             ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13473          } else if (ast_false(v->value)) {
13474             ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13475          } else {
13476             ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13477          }
13478       }/*else if (strcasecmp(v->name,"type")) */
13479       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13480       v = v->next;
13481    }
13482 
13483    if (subscribe_network_change) {
13484       network_change_event_subscribe();
13485    } else {
13486       network_change_event_unsubscribe();
13487    }
13488 
13489    if (defaultsockfd < 0) {
13490       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13491          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13492       } else {
13493          ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13494          defaultsockfd = ast_netsock_sockfd(ns);
13495          ast_netsock_unref(ns);
13496       }
13497    }
13498    if (reload) {
13499       ast_netsock_release(outsock);
13500       outsock = ast_netsock_list_alloc();
13501       if (!outsock) {
13502          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13503          return -1;
13504       }
13505       ast_netsock_init(outsock);
13506    }
13507 
13508    if (min_reg_expire > max_reg_expire) {
13509       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13510          min_reg_expire, max_reg_expire, max_reg_expire);
13511       min_reg_expire = max_reg_expire;
13512    }
13513    iax2_capability = capability;
13514    
13515    if (ucfg) {
13516       struct ast_variable *gen;
13517       int genhasiax;
13518       int genregisteriax;
13519       const char *hasiax, *registeriax;
13520       
13521       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13522       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13523       gen = ast_variable_browse(ucfg, "general");
13524       cat = ast_category_browse(ucfg, NULL);
13525       while (cat) {
13526          if (strcasecmp(cat, "general")) {
13527             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13528             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13529             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13530                /* Start with general parameters, then specific parameters, user and peer */
13531                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13532                if (user) {
13533                   ao2_link(users, user);
13534                   user = user_unref(user);
13535                }
13536                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13537                if (peer) {
13538                   if (ast_test_flag64(peer, IAX_DYNAMIC))
13539                      reg_source_db(peer);
13540                   ao2_link(peers, peer);
13541                   peer = peer_unref(peer);
13542                }
13543             }
13544             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13545                char tmp[256];
13546                const char *host = ast_variable_retrieve(ucfg, cat, "host");
13547                const char *username = ast_variable_retrieve(ucfg, cat, "username");
13548                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13549                if (!host)
13550                   host = ast_variable_retrieve(ucfg, "general", "host");
13551                if (!username)
13552                   username = ast_variable_retrieve(ucfg, "general", "username");
13553                if (!secret)
13554                   secret = ast_variable_retrieve(ucfg, "general", "secret");
13555                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13556                   if (!ast_strlen_zero(secret))
13557                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13558                   else
13559                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13560                   iax2_register(tmp, 0);
13561                }
13562             }
13563          }
13564          cat = ast_category_browse(ucfg, cat);
13565       }
13566       ast_config_destroy(ucfg);
13567    }
13568    
13569    cat = ast_category_browse(cfg, NULL);
13570    while(cat) {
13571       if (strcasecmp(cat, "general")) {
13572          utype = ast_variable_retrieve(cfg, cat, "type");
13573          if (!strcasecmp(cat, "callnumberlimits")) {
13574             build_callno_limits(ast_variable_browse(cfg, cat));
13575          } else if (utype) {
13576             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13577                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13578                if (user) {
13579                   ao2_link(users, user);
13580                   user = user_unref(user);
13581                }
13582             }
13583             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13584                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13585                if (peer) {
13586                   if (ast_test_flag64(peer, IAX_DYNAMIC))
13587                      reg_source_db(peer);
13588                   ao2_link(peers, peer);
13589                   peer = peer_unref(peer);
13590                }
13591             } else if (strcasecmp(utype, "user")) {
13592                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13593             }
13594          } else
13595             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13596       }
13597       cat = ast_category_browse(cfg, cat);
13598    }
13599    ast_config_destroy(cfg);
13600    return 1;
13601 }

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

Definition at line 9916 of file chan_iax2.c.

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

Referenced by socket_process().

09917 {
09918    iax2_lock_owner(callno);
09919    if (iaxs[callno] && iaxs[callno]->owner) {
09920       struct ast_channel *owner;
09921       const char *name;
09922 
09923       owner = iaxs[callno]->owner;
09924       if (causecode) {
09925          owner->hangupcause = causecode;
09926       }
09927       name = ast_strdupa(owner->name);
09928       ast_channel_ref(owner);
09929       ast_channel_unlock(owner);
09930       ast_mutex_unlock(&iaxsl[callno]);
09931       ast_set_hangupsource(owner, name, 0);
09932       ast_channel_unref(owner);
09933       ast_mutex_lock(&iaxsl[callno]);
09934    }
09935 }

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

Definition at line 2265 of file chan_iax2.c.

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

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

02266 {
02267    uint16_t limit = global_maxcallno;
02268    struct addr_range *addr_range;
02269    struct sockaddr_in sin = {
02270       .sin_addr.s_addr = peercnt->addr,
02271    };
02272 
02273 
02274    if (peercnt->reg && peercnt->limit) {
02275       return; /* this peercnt has a custom limit set by a registration */
02276    }
02277 
02278    if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02279       limit = addr_range->limit;
02280       ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02281       ao2_ref(addr_range, -1);
02282    }
02283 
02284    peercnt->limit = limit;
02285 }

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

Definition at line 2291 of file chan_iax2.c.

References ast_debug, and set_peercnt_limit().

Referenced by reload_config().

02292 {
02293    struct peercnt *peercnt = obj;
02294 
02295    set_peercnt_limit(peercnt);
02296    ast_debug(1, "Reset limits for peercnts table\n");
02297 
02298    return 0;
02299 }

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

Definition at line 1052 of file chan_iax2.c.

References ast_cond_signal, ast_mutex_lock, and ast_mutex_unlock.

Referenced by __schedule_action(), cleanup_thread_list(), iax2_process_thread(), and socket_read().

01053 {
01054    ast_mutex_lock(lock);
01055    ast_cond_signal(cond);
01056    ast_mutex_unlock(lock);
01057 }

static int socket_process ( struct iax2_thread thread  )  [static]

Definition at line 9937 of file chan_iax2.c.

References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, ast_aes_set_decrypt_key(), ast_alloca, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_channel_datastore_add(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_clear_flag64, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), ast_connected_line_parse_data(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_free, ast_getformatname(), ast_getformatname_multiple(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_event, ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_parking_ext_valid(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_id_presentation(), ast_sched_thread_del, ast_set_callerid(), ast_set_flag, ast_set_flag64, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_var_assign(), ast_variables_destroy(), ast_verb, auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), chan_iax2_pvt::authmethods, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, iax_frame::cacheable, calc_timestamp(), iax_ies::called_number, ast_channel::caller, chan_iax2_pvt::calling_pres, iax2_peer::callno, chan_iax2_pvt::callno, iax_frame::callno, iax_ies::calltoken, iax_ies::calltokendata, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, check_access(), check_provisioning(), chan_iax2_pvt::chosenformat, cid_name, cid_num, ast_frame_subclass::codec, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), context, ast_iax2_full_hdr::csub, ast_datastore::data, ast_frame::data, ast_frame::datalen, DATASTORE_INHERIT_FOREVER, ast_iax2_full_hdr::dcallno, DEADLOCK_AVOIDANCE, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::encmethods, iax_ies::encmethods, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, format, ast_frame::frametype, iax_ies::fwdesc, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_allow_new(), iax2_destroy(), iax2_dprequest(), iax2_lock_owner(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_variable_datastore_info, iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CALLENCRYPTED, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_RTKEY, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DEBUGDIGEST, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, IAX_FORCE_ENCRYPT, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_IAX_UNKNOWN, IAX_IMMEDIATE, iax_outputframe(), iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, IAX_RECVCONNECTEDLINE, IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), iaxs, iaxsl, ast_party_caller::id, ast_party_connected_line::id, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::initid, ast_frame_subclass::integer, chan_iax2_pvt::iseqno, iax_frame::iseqno, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, ast_frame::len, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event, iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, iax_ies::musiconhold, ast_party_id::name, ast_variable::name, ast_channel::nativeformats, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, ast_variable::next, ast_party_id::number, ast_frame::offset, chan_iax2_pvt::oseqno, iax_frame::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::outoforder, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), peer_ref(), peer_unref(), chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, ast_party_name::presentation, ast_party_number::presentation, iax_ies::provver, iax_ies::provverpres, ast_frame::ptr, raw_hangup(), ast_channel::readformat, iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rprefs, chan_iax2_pvt::rseqno, S_COR, S_OR, ast_frame::samples, save_osptoken(), save_rr(), ast_iax2_full_hdr::scallno, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), send_signaling(), iax_ies::serviceident, set_hangup_source_and_cause(), iax2_peer::smoothing, socket_process_meta(), spawn_dp_lookup(), ast_frame::src, chan_iax2_pvt::state, stop_stuff(), store_by_peercallno(), ast_party_name::str, ast_party_number::str, ast_frame::subclass, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MEDIAPASS, TRANSFER_MREADY, TRANSFER_NONE, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), iax_frame::ts, ast_iax2_full_hdr::ts, ast_iax2_full_hdr::type, uncompress_subclass(), update_registry(), iax_ies::username, ast_party_name::valid, ast_party_number::valid, ast_variable::value, var, iax_ies::vars, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.

Referenced by handle_deferred_full_frames(), and iax2_process_thread().

09938 {
09939    struct sockaddr_in sin;
09940    int res;
09941    int updatehistory=1;
09942    int new = NEW_PREVENT;
09943    int dcallno = 0;
09944    char decrypted = 0;
09945    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09946    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09947    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09948    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09949    struct iax_frame *fr;
09950    struct iax_frame *cur;
09951    struct ast_frame f = { 0, };
09952    struct ast_channel *c = NULL;
09953    struct iax2_dpcache *dp;
09954    struct iax2_peer *peer;
09955    struct iax_ies ies;
09956    struct iax_ie_data ied0, ied1;
09957    format_t format;
09958    int fd;
09959    int exists;
09960    int minivid = 0;
09961    char empty[32]="";      /* Safety measure */
09962    struct iax_frame *duped_fr;
09963    char host_pref_buf[128];
09964    char caller_pref_buf[128];
09965    struct ast_codec_pref pref;
09966    char *using_prefs = "mine";
09967 
09968    /* allocate an iax_frame with 4096 bytes of data buffer */
09969    fr = ast_alloca(sizeof(*fr) + 4096);
09970    memset(fr, 0, sizeof(*fr));
09971    fr->afdatalen = 4096; /* From ast_alloca() above */
09972 
09973    /* Copy frequently used parameters to the stack */
09974    res = thread->buf_len;
09975    fd = thread->iofd;
09976    memcpy(&sin, &thread->iosin, sizeof(sin));
09977 
09978    if (res < sizeof(*mh)) {
09979       ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09980       return 1;
09981    }
09982    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09983       if (res < sizeof(*vh)) {
09984          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));
09985          return 1;
09986       }
09987 
09988       /* This is a video frame, get call number */
09989       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09990       minivid = 1;
09991    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09992       return socket_process_meta(res, meta, &sin, fd, fr);
09993 
09994 #ifdef DEBUG_SUPPORT
09995    if (res >= sizeof(*fh))
09996       iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09997 #endif
09998    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09999       if (res < sizeof(*fh)) {
10000          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));
10001          return 1;
10002       }
10003 
10004       /* Get the destination call number */
10005       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
10006 
10007 
10008       /* check to make sure this full frame isn't encrypted before we attempt
10009        * to look inside of it. If it is encrypted, decrypt it first. Its ok if the
10010        * callno is not found here, that just means one hasn't been allocated for
10011        * this connection yet. */
10012       if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
10013          ast_mutex_lock(&iaxsl[fr->callno]);
10014          if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
10015             if (decrypt_frame(fr->callno, fh, &f, &res)) {
10016                ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10017                ast_mutex_unlock(&iaxsl[fr->callno]);
10018                return 1;
10019             }
10020             decrypted = 1;
10021          }
10022          ast_mutex_unlock(&iaxsl[fr->callno]);
10023       }
10024 
10025       /* Retrieve the type and subclass */
10026       f.frametype = fh->type;
10027       if (f.frametype == AST_FRAME_VIDEO) {
10028          f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
10029       } else if (f.frametype == AST_FRAME_VOICE) {
10030          f.subclass.codec = uncompress_subclass(fh->csub);
10031       } else {
10032          f.subclass.integer = uncompress_subclass(fh->csub);
10033       }
10034 
10035       /* Deal with POKE/PONG without allocating a callno */
10036       if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
10037          /* Reply back with a PONG, but don't care about the result. */
10038          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10039          return 1;
10040       } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
10041          /* Ignore */
10042          return 1;
10043       }
10044 
10045       f.datalen = res - sizeof(*fh);
10046       if (f.datalen) {
10047          if (f.frametype == AST_FRAME_IAX) {
10048             if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
10049                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
10050                ast_variables_destroy(ies.vars);
10051                return 1;
10052             }
10053             f.data.ptr = NULL;
10054             f.datalen = 0;
10055          } else {
10056             f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
10057             memset(&ies, 0, sizeof(ies));
10058          }
10059       } else {
10060          if (f.frametype == AST_FRAME_IAX)
10061             f.data.ptr = NULL;
10062          else
10063             f.data.ptr = empty;
10064          memset(&ies, 0, sizeof(ies));
10065       }
10066 
10067       if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
10068          /* only set NEW_ALLOW if calltoken checks out */
10069          if (handle_call_token(fh, &ies, &sin, fd)) {
10070             ast_variables_destroy(ies.vars);
10071             return 1;
10072          }
10073 
10074          if (ies.calltoken && ies.calltokendata) {
10075             /* if we've gotten this far, and the calltoken ie data exists,
10076              * then calltoken validation _MUST_ have taken place.  If calltoken
10077              * data is provided, it is always validated reguardless of any
10078              * calltokenoptional or requirecalltoken options */
10079             new = NEW_ALLOW_CALLTOKEN_VALIDATED;
10080          } else {
10081             new = NEW_ALLOW;
10082          }
10083       }
10084    } else {
10085       /* Don't know anything about it yet */
10086       f.frametype = AST_FRAME_NULL;
10087       f.subclass.integer = 0;
10088       memset(&ies, 0, sizeof(ies));
10089    }
10090 
10091    if (!fr->callno) {
10092       int check_dcallno = 0;
10093 
10094       /*
10095        * We enforce accurate destination call numbers for ACKs.  This forces the other
10096        * end to know the destination call number before call setup can complete.
10097        *
10098        * Discussed in the following thread:
10099        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
10100        */
10101 
10102       if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10103          check_dcallno = 1;
10104       }
10105 
10106       if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
10107          if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
10108             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10109          } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
10110             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10111          }
10112          ast_variables_destroy(ies.vars);
10113          return 1;
10114       }
10115    }
10116 
10117    if (fr->callno > 0)
10118       ast_mutex_lock(&iaxsl[fr->callno]);
10119 
10120    if (!fr->callno || !iaxs[fr->callno]) {
10121       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
10122          frame, reply with an inval */
10123       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10124          /* We can only raw hangup control frames */
10125          if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10126              (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10127              (f.subclass.integer != IAX_COMMAND_TXACC) &&
10128              (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
10129              (f.frametype != AST_FRAME_IAX))
10130             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10131             fd);
10132       }
10133       if (fr->callno > 0) 
10134          ast_mutex_unlock(&iaxsl[fr->callno]);
10135       ast_variables_destroy(ies.vars);
10136       return 1;
10137    }
10138    if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10139       if (decrypt_frame(fr->callno, fh, &f, &res)) {
10140          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10141          ast_variables_destroy(ies.vars);
10142          ast_mutex_unlock(&iaxsl[fr->callno]);
10143          return 1;
10144       }
10145       decrypted = 1;
10146    }
10147 
10148 #ifdef DEBUG_SUPPORT
10149    if (decrypted) {
10150       iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10151    }
10152 #endif
10153 
10154 
10155    /* count this frame */
10156    iaxs[fr->callno]->frames_received++;
10157 
10158    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10159       f.subclass.integer != IAX_COMMAND_TXCNT &&      /* for attended transfer */
10160       f.subclass.integer != IAX_COMMAND_TXACC) {      /* for attended transfer */
10161       unsigned short new_peercallno;
10162       
10163       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10164       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10165          if (iaxs[fr->callno]->peercallno) {
10166             remove_by_peercallno(iaxs[fr->callno]);
10167          }
10168          iaxs[fr->callno]->peercallno = new_peercallno;
10169          store_by_peercallno(iaxs[fr->callno]);
10170       }
10171    }
10172    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10173       if (iaxdebug)
10174          ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10175       /* Check if it's out of order (and not an ACK or INVAL) */
10176       fr->oseqno = fh->oseqno;
10177       fr->iseqno = fh->iseqno;
10178       fr->ts = ntohl(fh->ts);
10179 #ifdef IAXTESTS
10180       if (test_resync) {
10181          ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10182          fr->ts += test_resync;
10183       }
10184 #endif /* IAXTESTS */
10185 #if 0
10186       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10187            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10188                         (f.subclass == IAX_COMMAND_NEW ||
10189                          f.subclass == IAX_COMMAND_AUTHREQ ||
10190                          f.subclass == IAX_COMMAND_ACCEPT ||
10191                          f.subclass == IAX_COMMAND_REJECT))      ) )
10192 #endif
10193       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10194          updatehistory = 0;
10195       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10196          (iaxs[fr->callno]->iseqno ||
10197             ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10198             (f.subclass.integer != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
10199             (f.subclass.integer != IAX_COMMAND_TXREL) &&    /* for attended transfer */
10200             (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
10201             (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10202             (f.frametype != AST_FRAME_IAX))) {
10203          if (
10204           ((f.subclass.integer != IAX_COMMAND_ACK) &&
10205            (f.subclass.integer != IAX_COMMAND_INVAL) &&
10206            (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10207            (f.subclass.integer != IAX_COMMAND_TXREADY) &&      /* for attended transfer */
10208            (f.subclass.integer != IAX_COMMAND_TXREL) &&     /* for attended transfer */
10209            (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
10210            (f.subclass.integer != IAX_COMMAND_TXACC) &&
10211            (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10212            (f.frametype != AST_FRAME_IAX)) {
10213             /* If it's not an ACK packet, it's out of order. */
10214             ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
10215                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10216             /* Check to see if we need to request retransmission,
10217              * and take sequence number wraparound into account */
10218             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10219                /* If we've already seen it, ack it XXX There's a border condition here XXX */
10220                if ((f.frametype != AST_FRAME_IAX) || 
10221                      ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10222                   ast_debug(1, "Acking anyway\n");
10223                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
10224                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
10225                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10226                }
10227             } else {
10228                /* Send a VNAK requesting retransmission */
10229                iax2_vnak(fr->callno);
10230             }
10231             ast_variables_destroy(ies.vars);
10232             ast_mutex_unlock(&iaxsl[fr->callno]);
10233             return 1;
10234          }
10235       } else {
10236          /* Increment unless it's an ACK or VNAK */
10237          if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10238              (f.subclass.integer != IAX_COMMAND_INVAL) &&
10239              (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10240              (f.subclass.integer != IAX_COMMAND_TXACC) &&
10241             (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10242              (f.frametype != AST_FRAME_IAX))
10243             iaxs[fr->callno]->iseqno++;
10244       }
10245       /* Ensure text frames are NULL-terminated */
10246       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10247          if (res < thread->buf_size)
10248             thread->buf[res++] = '\0';
10249          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
10250             thread->buf[res - 1] = '\0';
10251       }
10252 
10253       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
10254          from the real peer, not the transfer peer */
10255       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
10256           ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10257            (f.frametype != AST_FRAME_IAX))) {
10258          unsigned char x;
10259          int call_to_destroy;
10260          /* First we have to qualify that the ACKed value is within our window */
10261          if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10262             x = fr->iseqno;
10263          else 
10264             x = iaxs[fr->callno]->oseqno;
10265          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10266             /* The acknowledgement is within our window.  Time to acknowledge everything
10267                that it says to */
10268             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10269                /* Ack the packet with the given timestamp */
10270                if (iaxdebug)
10271                   ast_debug(1, "Cancelling transmission of packet %d\n", x);
10272                call_to_destroy = 0;
10273                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10274                   /* If it's our call, and our timestamp, mark -1 retries */
10275                   if (x == cur->oseqno) {
10276                      cur->retries = -1;
10277                      /* Destroy call if this is the end */
10278                      if (cur->final)
10279                         call_to_destroy = fr->callno;
10280                   }
10281                }
10282                if (call_to_destroy) {
10283                   if (iaxdebug)
10284                      ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10285                   ast_mutex_lock(&iaxsl[call_to_destroy]);
10286                   iax2_destroy(call_to_destroy);
10287                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
10288                }
10289             }
10290             /* Note how much we've received acknowledgement for */
10291             if (iaxs[fr->callno])
10292                iaxs[fr->callno]->rseqno = fr->iseqno;
10293             else {
10294                /* Stop processing now */
10295                ast_variables_destroy(ies.vars);
10296                ast_mutex_unlock(&iaxsl[fr->callno]);
10297                return 1;
10298             }
10299          } else {
10300             ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10301          }
10302       }
10303       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
10304          ((f.frametype != AST_FRAME_IAX) || 
10305           ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10306            (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10307          /* Only messages we accept from a transfer host are TXACC and TXCNT */
10308          ast_variables_destroy(ies.vars);
10309          ast_mutex_unlock(&iaxsl[fr->callno]);
10310          return 1;
10311       }
10312 
10313       /* when we receive the first full frame for a new incoming channel,
10314          it is safe to start the PBX on the channel because we have now
10315          completed a 3-way handshake with the peer */
10316       if ((f.frametype == AST_FRAME_VOICE) ||
10317           (f.frametype == AST_FRAME_VIDEO) ||
10318           (f.frametype == AST_FRAME_IAX)) {
10319          if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10320             ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10321             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL,
10322                     ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) {
10323                ast_variables_destroy(ies.vars);
10324                ast_mutex_unlock(&iaxsl[fr->callno]);
10325                return 1;
10326             }
10327          }
10328 
10329          if (ies.vars) {
10330             struct ast_datastore *variablestore = NULL;
10331             struct ast_variable *var, *prev = NULL;
10332             AST_LIST_HEAD(, ast_var_t) *varlist;
10333 
10334             iax2_lock_owner(fr->callno);
10335             if (!iaxs[fr->callno]) {
10336                ast_variables_destroy(ies.vars);
10337                ast_mutex_unlock(&iaxsl[fr->callno]);
10338                return 1;
10339             }
10340             if ((c = iaxs[fr->callno]->owner)) {
10341                varlist = ast_calloc(1, sizeof(*varlist));
10342                variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10343 
10344                if (variablestore && varlist) {
10345                   variablestore->data = varlist;
10346                   variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10347                   AST_LIST_HEAD_INIT(varlist);
10348                   ast_debug(1, "I can haz IAX vars?\n");
10349                   for (var = ies.vars; var; var = var->next) {
10350                      struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10351                      if (prev) {
10352                         ast_free(prev);
10353                      }
10354                      prev = var;
10355                      if (!newvar) {
10356                         /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
10357                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10358                      } else {
10359                         AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10360                      }
10361                   }
10362                   if (prev) {
10363                      ast_free(prev);
10364                   }
10365                   ies.vars = NULL;
10366                   ast_channel_datastore_add(c, variablestore);
10367                } else {
10368                   ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10369                   if (variablestore) {
10370                      ast_datastore_free(variablestore);
10371                   }
10372                   if (varlist) {
10373                      ast_free(varlist);
10374                   }
10375                }
10376                ast_channel_unlock(c);
10377             } else {
10378                /* No channel yet, so transfer the variables directly over to the pvt,
10379                 * for later inheritance. */
10380                ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10381                for (var = ies.vars; var && var->next; var = var->next);
10382                if (var) {
10383                   var->next = iaxs[fr->callno]->iaxvars;
10384                   iaxs[fr->callno]->iaxvars = ies.vars;
10385                   ies.vars = NULL;
10386                }
10387             }
10388          }
10389 
10390          if (ies.vars) {
10391             ast_debug(1, "I have IAX variables, but they were not processed\n");
10392          }
10393       }
10394 
10395       /* once we receive our first IAX Full Frame that is not CallToken related, send all
10396        * queued signaling frames that were being held. */
10397       if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10398          send_signaling(iaxs[fr->callno]);
10399       }
10400 
10401       if (f.frametype == AST_FRAME_VOICE) {
10402          if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10403                iaxs[fr->callno]->voiceformat = f.subclass.codec;
10404                ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10405                if (iaxs[fr->callno]->owner) {
10406                   iax2_lock_owner(fr->callno);
10407                   if (iaxs[fr->callno]) {
10408                      if (iaxs[fr->callno]->owner) {
10409                         format_t orignative;
10410 
10411                         orignative = iaxs[fr->callno]->owner->nativeformats;
10412                         iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10413                         if (iaxs[fr->callno]->owner->readformat)
10414                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10415                         iaxs[fr->callno]->owner->nativeformats = orignative;
10416                         ast_channel_unlock(iaxs[fr->callno]->owner);
10417                      }
10418                   } else {
10419                      ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10420                      /* Free remote variables (if any) */
10421                      if (ies.vars) {
10422                         ast_variables_destroy(ies.vars);
10423                         ast_debug(1, "I can haz iaxvars, but they is no good.  :-(\n");
10424                         ies.vars = NULL;
10425                      }
10426                      ast_mutex_unlock(&iaxsl[fr->callno]);
10427                      return 1;
10428                   }
10429                }
10430          }
10431       }
10432       if (f.frametype == AST_FRAME_VIDEO) {
10433          if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10434             ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10435             iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10436          }
10437       }
10438       if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10439          if (f.subclass.integer == AST_CONTROL_BUSY) {
10440             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10441          } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
10442             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10443          }
10444       }
10445       if (f.frametype == AST_FRAME_IAX) {
10446          ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10447          /* Handle the IAX pseudo frame itself */
10448          if (iaxdebug)
10449             ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10450 
10451                         /* Update last ts unless the frame's timestamp originated with us. */
10452          if (iaxs[fr->callno]->last < fr->ts &&
10453                             f.subclass.integer != IAX_COMMAND_ACK &&
10454                             f.subclass.integer != IAX_COMMAND_PONG &&
10455                             f.subclass.integer != IAX_COMMAND_LAGRP) {
10456             iaxs[fr->callno]->last = fr->ts;
10457             if (iaxdebug)
10458                ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10459          }
10460          iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10461          if (!iaxs[fr->callno]->first_iax_message) {
10462             iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10463          }
10464          switch(f.subclass.integer) {
10465          case IAX_COMMAND_ACK:
10466             /* Do nothing */
10467             break;
10468          case IAX_COMMAND_QUELCH:
10469             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10470                     /* Generate Manager Hold event, if necessary*/
10471                if (iaxs[fr->callno]->owner) {
10472                   ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10473                      "Status: On\r\n"
10474                      "Channel: %s\r\n"
10475                      "Uniqueid: %s\r\n",
10476                      iaxs[fr->callno]->owner->name,
10477                      iaxs[fr->callno]->owner->uniqueid);
10478                }
10479 
10480                ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10481                if (ies.musiconhold) {
10482                   iax2_lock_owner(fr->callno);
10483                   if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10484                      break;
10485                   }
10486                   if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10487                      const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10488 
10489                      /*
10490                       * We already hold the owner lock so we do not
10491                       * need to check iaxs[fr->callno] after it returns.
10492                       */
10493                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
10494                         S_OR(moh_suggest, NULL),
10495                         !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10496                   }
10497                   ast_channel_unlock(iaxs[fr->callno]->owner);
10498                }
10499             }
10500             break;
10501          case IAX_COMMAND_UNQUELCH:
10502             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10503                iax2_lock_owner(fr->callno);
10504                if (!iaxs[fr->callno]) {
10505                   break;
10506                }
10507                /* Generate Manager Unhold event, if necessary */
10508                if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10509                   ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10510                      "Status: Off\r\n"
10511                      "Channel: %s\r\n"
10512                      "Uniqueid: %s\r\n",
10513                      iaxs[fr->callno]->owner->name,
10514                      iaxs[fr->callno]->owner->uniqueid);
10515                }
10516 
10517                ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10518                if (!iaxs[fr->callno]->owner) {
10519                   break;
10520                }
10521                if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10522                   /*
10523                    * We already hold the owner lock so we do not
10524                    * need to check iaxs[fr->callno] after it returns.
10525                    */
10526                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10527                }
10528                ast_channel_unlock(iaxs[fr->callno]->owner);
10529             }
10530             break;
10531          case IAX_COMMAND_TXACC:
10532             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10533                /* Ack the packet with the given timestamp */
10534                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10535                   /* Cancel any outstanding txcnt's */
10536                   if (cur->transfer) {
10537                      cur->retries = -1;
10538                   }
10539                }
10540                memset(&ied1, 0, sizeof(ied1));
10541                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10542                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10543                iaxs[fr->callno]->transferring = TRANSFER_READY;
10544             }
10545             break;
10546          case IAX_COMMAND_NEW:
10547             /* Ignore if it's already up */
10548             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10549                break;
10550             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10551                ast_mutex_unlock(&iaxsl[fr->callno]);
10552                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10553                ast_mutex_lock(&iaxsl[fr->callno]);
10554                if (!iaxs[fr->callno]) {
10555                   break;
10556                }
10557             }
10558             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
10559             if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10560                int new_callno;
10561                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10562                   fr->callno = new_callno;
10563             }
10564             /* For security, always ack immediately */
10565             if (delayreject)
10566                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10567             if (check_access(fr->callno, &sin, &ies)) {
10568                /* They're not allowed on */
10569                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10570                if (authdebug)
10571                   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);
10572                break;
10573             }
10574             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10575                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10576                ast_log(LOG_WARNING, "Rejected connect attempt.  No secret present while force encrypt enabled.\n");
10577                break;
10578             }
10579             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10580                const char *context, *exten, *cid_num;
10581 
10582                context = ast_strdupa(iaxs[fr->callno]->context);
10583                exten = ast_strdupa(iaxs[fr->callno]->exten);
10584                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10585 
10586                /* This might re-enter the IAX code and need the lock */
10587                ast_mutex_unlock(&iaxsl[fr->callno]);
10588                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10589                ast_mutex_lock(&iaxsl[fr->callno]);
10590 
10591                if (!iaxs[fr->callno]) {
10592                   break;
10593                }
10594             } else
10595                exists = 0;
10596             /* Get OSP token if it does exist */
10597             save_osptoken(fr, &ies);
10598             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10599                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10600                   memset(&ied0, 0, sizeof(ied0));
10601                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10602                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10603                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10604                   if (!iaxs[fr->callno]) {
10605                      break;
10606                   }
10607                   if (authdebug)
10608                      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);
10609                } else {
10610                   /* Select an appropriate format */
10611 
10612                   if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10613                      if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10614                         using_prefs = "reqonly";
10615                      } else {
10616                         using_prefs = "disabled";
10617                      }
10618                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10619                      memset(&pref, 0, sizeof(pref));
10620                      strcpy(caller_pref_buf, "disabled");
10621                      strcpy(host_pref_buf, "disabled");
10622                   } else {
10623                      using_prefs = "mine";
10624                      /* If the information elements are in here... use them */
10625                      if (ies.codec_prefs)
10626                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10627                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10628                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
10629                         if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10630                            pref = iaxs[fr->callno]->rprefs;
10631                            using_prefs = "caller";
10632                         } else {
10633                            pref = iaxs[fr->callno]->prefs;
10634                         }
10635                      } else
10636                         pref = iaxs[fr->callno]->prefs;
10637 
10638                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10639                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10640                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10641                   }
10642                   if (!format) {
10643                      if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10644                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10645                      if (!format) {
10646                         memset(&ied0, 0, sizeof(ied0));
10647                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10648                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10649                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10650                         if (!iaxs[fr->callno]) {
10651                            break;
10652                         }
10653                         if (authdebug) {
10654                            char tmp[256], tmp2[256], tmp3[256];
10655                            if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10656                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10657                                  ast_inet_ntoa(sin.sin_addr),
10658                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10659                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10660                            } else {
10661                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10662                                  ast_inet_ntoa(sin.sin_addr),
10663                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10664                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10665                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10666                            }
10667                         }
10668                      } else {
10669                         /* Pick one... */
10670                         if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10671                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10672                               format = 0;
10673                         } else {
10674                            if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10675                               using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10676                               memset(&pref, 0, sizeof(pref));
10677                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10678                               strcpy(caller_pref_buf,"disabled");
10679                               strcpy(host_pref_buf,"disabled");
10680                            } else {
10681                               using_prefs = "mine";
10682                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10683                                  /* Do the opposite of what we tried above. */
10684                                  if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10685                                     pref = iaxs[fr->callno]->prefs;
10686                                  } else {
10687                                     pref = iaxs[fr->callno]->rprefs;
10688                                     using_prefs = "caller";
10689                                  }
10690                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10691                               } else /* if no codec_prefs IE do it the old way */
10692                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10693                            }
10694                         }
10695 
10696                         if (!format) {
10697                            char tmp[256], tmp2[256], tmp3[256];
10698                            memset(&ied0, 0, sizeof(ied0));
10699                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10700                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10701                            ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10702                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10703                            if (!iaxs[fr->callno]) {
10704                               break;
10705                            }
10706                            if (authdebug) {
10707                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10708                                  ast_inet_ntoa(sin.sin_addr),
10709                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10710                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10711                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10712                            }
10713                            ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10714                            break;
10715                         }
10716                      }
10717                   }
10718                   if (format) {
10719                      /* No authentication required, let them in */
10720                      memset(&ied1, 0, sizeof(ied1));
10721                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10722                      iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10723                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10724                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10725                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10726                         ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10727                                     "%srequested format = %s,\n"
10728                                     "%srequested prefs = %s,\n"
10729                                     "%sactual format = %s,\n"
10730                                     "%shost prefs = %s,\n"
10731                                     "%spriority = %s\n",
10732                                     ast_inet_ntoa(sin.sin_addr), 
10733                                     VERBOSE_PREFIX_4,
10734                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
10735                                     VERBOSE_PREFIX_4,
10736                                     caller_pref_buf,
10737                                     VERBOSE_PREFIX_4,
10738                                     ast_getformatname(format), 
10739                                     VERBOSE_PREFIX_4,
10740                                     host_pref_buf, 
10741                                     VERBOSE_PREFIX_4,
10742                                     using_prefs);
10743 
10744                         iaxs[fr->callno]->chosenformat = format;
10745                         ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10746                      } else {
10747                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10748                         /* If this is a TBD call, we're ready but now what...  */
10749                         ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10750                      }
10751                   }
10752                }
10753                break;
10754             }
10755             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10756                merge_encryption(iaxs[fr->callno],ies.encmethods);
10757             else
10758                iaxs[fr->callno]->encmethods = 0;
10759             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10760                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10761             break;
10762          case IAX_COMMAND_DPREQ:
10763             /* Request status in the dialplan */
10764             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10765                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10766                if (iaxcompat) {
10767                   /* Spawn a thread for the lookup */
10768                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10769                } else {
10770                   /* Just look it up */
10771                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10772                }
10773             }
10774             break;
10775          case IAX_COMMAND_HANGUP:
10776             ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10777             ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10778             /* Set hangup cause according to remote and hangupsource */
10779             if (iaxs[fr->callno]->owner) {
10780                set_hangup_source_and_cause(fr->callno, ies.causecode);
10781                if (!iaxs[fr->callno]) {
10782                   break;
10783                }
10784             }
10785 
10786             /* Send ack immediately, before we destroy */
10787             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10788             iax2_destroy(fr->callno);
10789             break;
10790          case IAX_COMMAND_REJECT:
10791             /* Set hangup cause according to remote and hangup source */
10792             if (iaxs[fr->callno]->owner) {
10793                set_hangup_source_and_cause(fr->callno, ies.causecode);
10794                if (!iaxs[fr->callno]) {
10795                   break;
10796                }
10797             }
10798 
10799             if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10800                if (iaxs[fr->callno]->owner && authdebug)
10801                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10802                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10803                      ies.cause ? ies.cause : "<Unknown>");
10804                ast_debug(1, "Immediately destroying %d, having received reject\n",
10805                   fr->callno);
10806             }
10807             /* Send ack immediately, before we destroy */
10808             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10809                          fr->ts, NULL, 0, fr->iseqno);
10810             if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10811                iaxs[fr->callno]->error = EPERM;
10812             iax2_destroy(fr->callno);
10813             break;
10814          case IAX_COMMAND_TRANSFER:
10815          {
10816             struct ast_channel *bridged_chan;
10817             struct ast_channel *owner;
10818 
10819             iax2_lock_owner(fr->callno);
10820             if (!iaxs[fr->callno]) {
10821                /* Initiating call went away before we could transfer. */
10822                break;
10823             }
10824             owner = iaxs[fr->callno]->owner;
10825             bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10826             if (bridged_chan && ies.called_number) {
10827                const char *context;
10828 
10829                context = ast_strdupa(iaxs[fr->callno]->context);
10830 
10831                ast_channel_ref(owner);
10832                ast_channel_ref(bridged_chan);
10833                ast_channel_unlock(owner);
10834                ast_mutex_unlock(&iaxsl[fr->callno]);
10835 
10836                /* Set BLINDTRANSFER channel variables */
10837                pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10838                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10839 
10840                /* DO NOT hold any locks while calling ast_parking_ext_valid() */
10841                if (ast_parking_ext_valid(ies.called_number, owner, context)) {
10842                   ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10843                   if (iax_park(bridged_chan, owner, ies.called_number, context)) {
10844                      ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10845                         bridged_chan->name);
10846                   }
10847                } else {
10848                   if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) {
10849                      ast_log(LOG_WARNING,
10850                         "Async goto of '%s' to '%s@%s' failed\n",
10851                         bridged_chan->name, ies.called_number, context);
10852                   } else {
10853                      ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10854                         bridged_chan->name, ies.called_number, context);
10855                   }
10856                }
10857                ast_channel_unref(owner);
10858                ast_channel_unref(bridged_chan);
10859 
10860                ast_mutex_lock(&iaxsl[fr->callno]);
10861             } else {
10862                ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10863                if (owner) {
10864                   ast_channel_unlock(owner);
10865                }
10866             }
10867 
10868             break;
10869          }
10870          case IAX_COMMAND_ACCEPT:
10871             /* Ignore if call is already up or needs authentication or is a TBD */
10872             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10873                break;
10874             if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10875                /* Send ack immediately, before we destroy */
10876                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10877                iax2_destroy(fr->callno);
10878                break;
10879             }
10880             if (ies.format) {
10881                iaxs[fr->callno]->peerformat = ies.format;
10882             } else {
10883                if (iaxs[fr->callno]->owner)
10884                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10885                else
10886                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10887             }
10888             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));
10889             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10890                memset(&ied0, 0, sizeof(ied0));
10891                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10892                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10893                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10894                if (!iaxs[fr->callno]) {
10895                   break;
10896                }
10897                if (authdebug) {
10898                   char tmp1[256], tmp2[256];
10899                   ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
10900                      ast_inet_ntoa(sin.sin_addr),
10901                      ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10902                      ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10903                }
10904             } else {
10905                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10906                iax2_lock_owner(fr->callno);
10907                if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10908                   /* Switch us to use a compatible format */
10909                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10910                   ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10911 
10912                   /* Setup read/write formats properly. */
10913                   if (iaxs[fr->callno]->owner->writeformat)
10914                      ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
10915                   if (iaxs[fr->callno]->owner->readformat)
10916                      ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
10917                   ast_channel_unlock(iaxs[fr->callno]->owner);
10918                }
10919             }
10920             if (iaxs[fr->callno]) {
10921                AST_LIST_LOCK(&dpcache);
10922                AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10923                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10924                      iax2_dprequest(dp, fr->callno);
10925                AST_LIST_UNLOCK(&dpcache);
10926             }
10927             break;
10928          case IAX_COMMAND_POKE:
10929             /* Send back a pong packet with the original timestamp */
10930             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10931             break;
10932          case IAX_COMMAND_PING:
10933          {
10934             struct iax_ie_data pingied;
10935             construct_rr(iaxs[fr->callno], &pingied);
10936             /* Send back a pong packet with the original timestamp */
10937             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10938          }
10939             break;
10940          case IAX_COMMAND_PONG:
10941             /* Calculate ping time */
10942             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10943             /* save RR info */
10944             save_rr(fr, &ies);
10945 
10946             /* Good time to write jb stats for this call */
10947             log_jitterstats(fr->callno);
10948 
10949             if (iaxs[fr->callno]->peerpoke) {
10950                peer = iaxs[fr->callno]->peerpoke;
10951                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
10952                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10953                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10954                      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); 
10955                      ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
10956                   }
10957                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10958                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
10959                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10960                      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); 
10961                      ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
10962                   }
10963                }
10964                peer->lastms = iaxs[fr->callno]->pingtime;
10965                if (peer->smoothing && (peer->lastms > -1))
10966                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10967                else if (peer->smoothing && peer->lastms < 0)
10968                   peer->historicms = (0 + peer->historicms) / 2;
10969                else              
10970                   peer->historicms = iaxs[fr->callno]->pingtime;
10971 
10972                /* Remove scheduled iax2_poke_noanswer */
10973                if (peer->pokeexpire > -1) {
10974                   if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10975                      peer_unref(peer);
10976                      peer->pokeexpire = -1;
10977                   }
10978                }
10979                /* Schedule the next cycle */
10980                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
10981                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10982                else
10983                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10984                if (peer->pokeexpire == -1)
10985                   peer_unref(peer);
10986                /* and finally send the ack */
10987                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10988                /* And wrap up the qualify call */
10989                iax2_destroy(fr->callno);
10990                peer->callno = 0;
10991                ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10992             }
10993             break;
10994          case IAX_COMMAND_LAGRQ:
10995          case IAX_COMMAND_LAGRP:
10996             f.src = "LAGRQ";
10997             f.mallocd = 0;
10998             f.offset = 0;
10999             f.samples = 0;
11000             iax_frame_wrap(fr, &f);
11001             if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
11002                /* Received a LAGRQ - echo back a LAGRP */
11003                fr->af.subclass.integer = IAX_COMMAND_LAGRP;
11004                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
11005             } else {
11006                /* Received LAGRP in response to our LAGRQ */
11007                unsigned int ts;
11008                /* This is a reply we've been given, actually measure the difference */
11009                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
11010                iaxs[fr->callno]->lag = ts - fr->ts;
11011                if (iaxdebug)
11012                   ast_debug(1, "Peer %s lag measured as %dms\n",
11013                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
11014             }
11015             break;
11016          case IAX_COMMAND_AUTHREQ:
11017             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11018                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>");
11019                break;
11020             }
11021             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
11022                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
11023                         .subclass.integer = AST_CONTROL_HANGUP,
11024                };
11025                ast_log(LOG_WARNING, 
11026                   "I don't know how to authenticate %s to %s\n", 
11027                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
11028                iax2_queue_frame(fr->callno, &hangup_fr);
11029             }
11030             break;
11031          case IAX_COMMAND_AUTHREP:
11032             /* For security, always ack immediately */
11033             if (delayreject)
11034                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11035             /* Ignore once we've started */
11036             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11037                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>");
11038                break;
11039             }
11040             if (authenticate_verify(iaxs[fr->callno], &ies)) {
11041                if (authdebug)
11042                   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);
11043                memset(&ied0, 0, sizeof(ied0));
11044                auth_fail(fr->callno, IAX_COMMAND_REJECT);
11045                break;
11046             }
11047             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
11048                /* This might re-enter the IAX code and need the lock */
11049                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
11050             } else
11051                exists = 0;
11052             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
11053                if (authdebug)
11054                   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);
11055                memset(&ied0, 0, sizeof(ied0));
11056                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11057                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11058                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11059                if (!iaxs[fr->callno]) {
11060                   break;
11061                }
11062             } else {
11063                /* Select an appropriate format */
11064                if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11065                   if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11066                      using_prefs = "reqonly";
11067                   } else {
11068                      using_prefs = "disabled";
11069                   }
11070                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
11071                   memset(&pref, 0, sizeof(pref));
11072                   strcpy(caller_pref_buf, "disabled");
11073                   strcpy(host_pref_buf, "disabled");
11074                } else {
11075                   using_prefs = "mine";
11076                   if (ies.codec_prefs)
11077                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11078                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11079                      if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11080                         pref = iaxs[fr->callno]->rprefs;
11081                         using_prefs = "caller";
11082                      } else {
11083                         pref = iaxs[fr->callno]->prefs;
11084                      }
11085                   } else /* if no codec_prefs IE do it the old way */
11086                      pref = iaxs[fr->callno]->prefs;
11087                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
11088                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11089                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11090                }
11091                if (!format) {
11092                   char tmp1[256], tmp2[256], tmp3[256];
11093                   if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11094                      ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11095                         ast_getformatname(iaxs[fr->callno]->peerformat),
11096                         ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
11097                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11098                   }
11099                   if (!format) {
11100                      if (authdebug) {
11101                         if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11102                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
11103                               ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11104                               ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11105                         } else {
11106                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11107                               ast_inet_ntoa(sin.sin_addr),
11108                               ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11109                               ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11110                               ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11111                         }
11112                      }
11113                      memset(&ied0, 0, sizeof(ied0));
11114                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11115                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11116                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11117                      if (!iaxs[fr->callno]) {
11118                         break;
11119                      }
11120                   } else {
11121                      /* Pick one... */
11122                      if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11123                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11124                            format = 0;
11125                      } else {
11126                         if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11127                            using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11128                            memset(&pref, 0, sizeof(pref));
11129                            format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
11130                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11131                            strcpy(caller_pref_buf,"disabled");
11132                            strcpy(host_pref_buf,"disabled");
11133                         } else {
11134                            using_prefs = "mine";
11135                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11136                               /* Do the opposite of what we tried above. */
11137                               if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11138                                  pref = iaxs[fr->callno]->prefs;
11139                               } else {
11140                                  pref = iaxs[fr->callno]->rprefs;
11141                                  using_prefs = "caller";
11142                               }
11143                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11144                            } else /* if no codec_prefs IE do it the old way */
11145                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
11146                         }
11147                      }
11148                      if (!format) {
11149                         char tmp1[256], tmp2[256], tmp3[256];
11150                         ast_log(LOG_ERROR, "No best format in %s???\n",
11151                            ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11152                         if (authdebug) {
11153                            if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11154                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11155                                  ast_inet_ntoa(sin.sin_addr),
11156                                  ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11157                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11158                            } else {
11159                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11160                                  ast_inet_ntoa(sin.sin_addr),
11161                                  ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11162                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11163                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11164                            }
11165                         }
11166                         memset(&ied0, 0, sizeof(ied0));
11167                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11168                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11169                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11170                         if (!iaxs[fr->callno]) {
11171                            break;
11172                         }
11173                      }
11174                   }
11175                }
11176                if (format) {
11177                   /* Authentication received */
11178                   memset(&ied1, 0, sizeof(ied1));
11179                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11180                   iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11181                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11182                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11183                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11184                      ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11185                                  "%srequested format = %s,\n"
11186                                  "%srequested prefs = %s,\n"
11187                                  "%sactual format = %s,\n"
11188                                  "%shost prefs = %s,\n"
11189                                  "%spriority = %s\n", 
11190                                  ast_inet_ntoa(sin.sin_addr), 
11191                                  VERBOSE_PREFIX_4,
11192                                  ast_getformatname(iaxs[fr->callno]->peerformat),
11193                                  VERBOSE_PREFIX_4,
11194                                  caller_pref_buf,
11195                                  VERBOSE_PREFIX_4,
11196                                  ast_getformatname(format),
11197                                  VERBOSE_PREFIX_4,
11198                                  host_pref_buf,
11199                                  VERBOSE_PREFIX_4,
11200                                  using_prefs);
11201 
11202                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11203                      if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1)))
11204                         iax2_destroy(fr->callno);
11205                      else if (ies.vars) {
11206                         struct ast_datastore *variablestore;
11207                         struct ast_variable *var, *prev = NULL;
11208                         AST_LIST_HEAD(, ast_var_t) *varlist;
11209                         varlist = ast_calloc(1, sizeof(*varlist));
11210                         variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11211                         if (variablestore && varlist) {
11212                            variablestore->data = varlist;
11213                            variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11214                            AST_LIST_HEAD_INIT(varlist);
11215                            ast_debug(1, "I can haz IAX vars? w00t\n");
11216                            for (var = ies.vars; var; var = var->next) {
11217                               struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11218                               if (prev)
11219                                  ast_free(prev);
11220                               prev = var;
11221                               if (!newvar) {
11222                                  /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11223                                  ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11224                               } else {
11225                                  AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11226                               }
11227                            }
11228                            if (prev)
11229                               ast_free(prev);
11230                            ies.vars = NULL;
11231                            ast_channel_datastore_add(c, variablestore);
11232                         } else {
11233                            ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11234                            if (variablestore)
11235                               ast_datastore_free(variablestore);
11236                            if (varlist)
11237                               ast_free(varlist);
11238                         }
11239                      }
11240                   } else {
11241                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11242                      /* If this is a TBD call, we're ready but now what...  */
11243                      ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11244                      if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11245                         goto immediatedial;
11246                      }
11247                   }
11248                }
11249             }
11250             break;
11251          case IAX_COMMAND_DIAL:
11252 immediatedial:
11253             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11254                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11255                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11256                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11257                   if (authdebug)
11258                      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);
11259                   memset(&ied0, 0, sizeof(ied0));
11260                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11261                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11262                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11263                   if (!iaxs[fr->callno]) {
11264                      break;
11265                   }
11266                } else {
11267                   char tmp[256];
11268                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11269                   ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11270                      ast_inet_ntoa(sin.sin_addr),
11271                      ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11272                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11273                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11274                   if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1)))
11275                      iax2_destroy(fr->callno);
11276                   else if (ies.vars) {
11277                      struct ast_datastore *variablestore;
11278                      struct ast_variable *var, *prev = NULL;
11279                      AST_LIST_HEAD(, ast_var_t) *varlist;
11280                      varlist = ast_calloc(1, sizeof(*varlist));
11281                      variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11282                      ast_debug(1, "I can haz IAX vars? w00t\n");
11283                      if (variablestore && varlist) {
11284                         variablestore->data = varlist;
11285                         variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11286                         AST_LIST_HEAD_INIT(varlist);
11287                         for (var = ies.vars; var; var = var->next) {
11288                            struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11289                            if (prev)
11290                               ast_free(prev);
11291                            prev = var;
11292                            if (!newvar) {
11293                               /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11294                               ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11295                            } else {
11296                               AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11297                            }
11298                         }
11299                         if (prev)
11300                            ast_free(prev);
11301                         ies.vars = NULL;
11302                         ast_channel_datastore_add(c, variablestore);
11303                      } else {
11304                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11305                         if (variablestore)
11306                            ast_datastore_free(variablestore);
11307                         if (varlist)
11308                            ast_free(varlist);
11309                      }
11310                   }
11311                }
11312             }
11313             break;
11314          case IAX_COMMAND_INVAL:
11315             iaxs[fr->callno]->error = ENOTCONN;
11316             ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11317             iax2_destroy(fr->callno);
11318             ast_debug(1, "Destroying call %d\n", fr->callno);
11319             break;
11320          case IAX_COMMAND_VNAK:
11321             ast_debug(1, "Received VNAK: resending outstanding frames\n");
11322             /* Force retransmission */
11323             vnak_retransmit(fr->callno, fr->iseqno);
11324             break;
11325          case IAX_COMMAND_REGREQ:
11326          case IAX_COMMAND_REGREL:
11327             /* For security, always ack immediately */
11328             if (delayreject)
11329                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11330             if (register_verify(fr->callno, &sin, &ies)) {
11331                if (!iaxs[fr->callno]) {
11332                   break;
11333                }
11334                /* Send delayed failure */
11335                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11336                break;
11337             }
11338             if (!iaxs[fr->callno]) {
11339                break;
11340             }
11341             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11342                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11343 
11344                if (f.subclass.integer == IAX_COMMAND_REGREL) {
11345                   memset(&sin, 0, sizeof(sin));
11346                   sin.sin_family = AF_INET;
11347                }
11348                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11349                   ast_log(LOG_WARNING, "Registry error\n");
11350                }
11351                if (!iaxs[fr->callno]) {
11352                   break;
11353                }
11354                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11355                   ast_mutex_unlock(&iaxsl[fr->callno]);
11356                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11357                   ast_mutex_lock(&iaxsl[fr->callno]);
11358                }
11359                break;
11360             }
11361             registry_authrequest(fr->callno);
11362             break;
11363          case IAX_COMMAND_REGACK:
11364             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
11365                ast_log(LOG_WARNING, "Registration failure\n");
11366             /* Send ack immediately, before we destroy */
11367             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11368             iax2_destroy(fr->callno);
11369             break;
11370          case IAX_COMMAND_REGREJ:
11371             if (iaxs[fr->callno]->reg) {
11372                if (authdebug) {
11373                   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));
11374                   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>");
11375                }
11376                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11377             }
11378             /* Send ack immediately, before we destroy */
11379             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11380             iax2_destroy(fr->callno);
11381             break;
11382          case IAX_COMMAND_REGAUTH:
11383             /* Authentication request */
11384             if (registry_rerequest(&ies, fr->callno, &sin)) {
11385                memset(&ied0, 0, sizeof(ied0));
11386                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11387                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11388                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11389             }
11390             break;
11391          case IAX_COMMAND_TXREJ:
11392             while (iaxs[fr->callno]
11393                && iaxs[fr->callno]->bridgecallno
11394                && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
11395                DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
11396             }
11397             if (!iaxs[fr->callno]) {
11398                break;
11399             }
11400 
11401             iaxs[fr->callno]->transferring = TRANSFER_NONE;
11402             ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11403             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11404 
11405             if (!iaxs[fr->callno]->bridgecallno) {
11406                break;
11407             }
11408 
11409             if (iaxs[iaxs[fr->callno]->bridgecallno]
11410                && iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11411                iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_NONE;
11412                send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11413             }
11414             ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11415             break;
11416          case IAX_COMMAND_TXREADY:
11417             while (iaxs[fr->callno]
11418                && iaxs[fr->callno]->bridgecallno
11419                && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
11420                DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
11421             }
11422             if (!iaxs[fr->callno]) {
11423                break;
11424             }
11425 
11426             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
11427                iaxs[fr->callno]->transferring = TRANSFER_READY;
11428             } else if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) {
11429                iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11430             } else {
11431                if (iaxs[fr->callno]->bridgecallno) {
11432                   ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11433                }
11434                break;
11435             }
11436             ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11437 
11438             if (!iaxs[fr->callno]->bridgecallno) {
11439                break;
11440             }
11441 
11442             if (!iaxs[iaxs[fr->callno]->bridgecallno]
11443                || (iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_READY
11444                   && iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_MREADY)) {
11445                ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11446                break;
11447             }
11448 
11449             /* Both sides are ready */
11450 
11451             /* XXX what isn't checked here is that both sides match transfer types. */
11452 
11453             if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11454                ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11455                      iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11456 
11457                iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11458                iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11459 
11460                memset(&ied0, 0, sizeof(ied0));
11461                memset(&ied1, 0, sizeof(ied1));
11462                iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11463                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11464                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11465                send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11466             } else {
11467                ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11468                      iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11469 
11470                iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11471                iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11472                ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11473                ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11474 
11475                /* Stop doing lag & ping requests */
11476                stop_stuff(fr->callno);
11477                stop_stuff(iaxs[fr->callno]->bridgecallno);
11478 
11479                memset(&ied0, 0, sizeof(ied0));
11480                memset(&ied1, 0, sizeof(ied1));
11481                iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11482                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11483                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11484                send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11485             }
11486             ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11487             break;
11488          case IAX_COMMAND_TXREQ:
11489             try_transfer(iaxs[fr->callno], &ies);
11490             break;
11491          case IAX_COMMAND_TXCNT:
11492             if (iaxs[fr->callno]->transferring)
11493                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11494             break;
11495          case IAX_COMMAND_TXREL:
11496             /* Send ack immediately, rather than waiting until we've changed addresses */
11497             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11498             complete_transfer(fr->callno, &ies);
11499             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
11500             break;   
11501          case IAX_COMMAND_TXMEDIA:
11502             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11503                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11504                   /* Cancel any outstanding frames and start anew */
11505                   if (cur->transfer) {
11506                      cur->retries = -1;
11507                   }
11508                }
11509                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
11510                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11511             }
11512             break;
11513          case IAX_COMMAND_RTKEY:
11514             if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11515                ast_log(LOG_WARNING, 
11516                   "we've been told to rotate our encryption key, "
11517                   "but this isn't an encrypted call. bad things will happen.\n"
11518                );
11519                break;
11520             }
11521 
11522             IAX_DEBUGDIGEST("Receiving", ies.challenge);
11523 
11524             ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11525             break;
11526          case IAX_COMMAND_DPREP:
11527             complete_dpreply(iaxs[fr->callno], &ies);
11528             break;
11529          case IAX_COMMAND_UNSUPPORT:
11530             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11531             break;
11532          case IAX_COMMAND_FWDOWNL:
11533             /* Firmware download */
11534             if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11535                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11536                break;
11537             }
11538             memset(&ied0, 0, sizeof(ied0));
11539             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11540             if (res < 0)
11541                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11542             else if (res > 0)
11543                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11544             else
11545                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11546             break;
11547          case IAX_COMMAND_CALLTOKEN:
11548          {
11549             struct iax_frame *cur;
11550             /* find last sent frame */
11551             if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11552                resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11553             }
11554             break;
11555          }
11556          default:
11557             ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11558             memset(&ied0, 0, sizeof(ied0));
11559             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11560             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11561          }
11562          /* Free remote variables (if any) */
11563          if (ies.vars) {
11564             ast_variables_destroy(ies.vars);
11565             ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11566             ies.vars = NULL;
11567          }
11568 
11569          /* Don't actually pass these frames along */
11570          if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11571             (f.subclass.integer != IAX_COMMAND_TXCNT) &&
11572             (f.subclass.integer != IAX_COMMAND_TXACC) &&
11573             (f.subclass.integer != IAX_COMMAND_INVAL) &&
11574             (f.subclass.integer != IAX_COMMAND_VNAK)) {
11575             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) {
11576                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11577             }
11578          }
11579          ast_mutex_unlock(&iaxsl[fr->callno]);
11580          return 1;
11581       }
11582       /* Unless this is an ACK or INVAL frame, ack it */
11583       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11584          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11585    } else if (minivid) {
11586       f.frametype = AST_FRAME_VIDEO;
11587       if (iaxs[fr->callno]->videoformat > 0) 
11588          f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11589       else {
11590          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11591          iax2_vnak(fr->callno);
11592          ast_variables_destroy(ies.vars);
11593          ast_mutex_unlock(&iaxsl[fr->callno]);
11594          return 1;
11595       }
11596       f.datalen = res - sizeof(*vh);
11597       if (f.datalen)
11598          f.data.ptr = thread->buf + sizeof(*vh);
11599       else
11600          f.data.ptr = NULL;
11601 #ifdef IAXTESTS
11602       if (test_resync) {
11603          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11604       } else
11605 #endif /* IAXTESTS */
11606          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11607    } else {
11608       /* A mini frame */
11609       f.frametype = AST_FRAME_VOICE;
11610       if (iaxs[fr->callno]->voiceformat > 0)
11611          f.subclass.codec = iaxs[fr->callno]->voiceformat;
11612       else {
11613          ast_debug(1, "Received mini frame before first full voice frame\n");
11614          iax2_vnak(fr->callno);
11615          ast_variables_destroy(ies.vars);
11616          ast_mutex_unlock(&iaxsl[fr->callno]);
11617          return 1;
11618       }
11619       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11620       if (f.datalen < 0) {
11621          ast_log(LOG_WARNING, "Datalen < 0?\n");
11622          ast_variables_destroy(ies.vars);
11623          ast_mutex_unlock(&iaxsl[fr->callno]);
11624          return 1;
11625       }
11626       if (f.datalen)
11627          f.data.ptr = thread->buf + sizeof(*mh);
11628       else
11629          f.data.ptr = NULL;
11630 #ifdef IAXTESTS
11631       if (test_resync) {
11632          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11633       } else
11634 #endif /* IAXTESTS */
11635       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11636       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
11637    }
11638    /* Don't pass any packets until we're started */
11639    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11640       ast_variables_destroy(ies.vars);
11641       ast_mutex_unlock(&iaxsl[fr->callno]);
11642       return 1;
11643    }
11644    /* Don't allow connected line updates unless we are configured to */
11645    if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) {
11646       struct ast_party_connected_line connected;
11647 
11648       if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11649          ast_variables_destroy(ies.vars);
11650          ast_mutex_unlock(&iaxsl[fr->callno]);
11651          return 1;
11652       }
11653 
11654       /* Initialize defaults */
11655       ast_party_connected_line_init(&connected);
11656       connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11657       connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11658 
11659       if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11660          ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11661          ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11662          iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11663 
11664          iax2_lock_owner(fr->callno);
11665          if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
11666             ast_set_callerid(iaxs[fr->callno]->owner,
11667                S_COR(connected.id.number.valid, connected.id.number.str, ""),
11668                S_COR(connected.id.name.valid, connected.id.name.str, ""),
11669                NULL);
11670             iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11671             iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11672             ast_channel_unlock(iaxs[fr->callno]->owner);
11673          }
11674       }
11675       ast_party_connected_line_free(&connected);
11676    }
11677    /* Common things */
11678    f.src = "IAX2";
11679    f.mallocd = 0;
11680    f.offset = 0;
11681    f.len = 0;
11682    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11683       f.samples = ast_codec_get_samples(&f);
11684       /* We need to byteswap incoming slinear samples from network byte order */
11685       if (f.subclass.codec == AST_FORMAT_SLINEAR)
11686          ast_frame_byteswap_be(&f);
11687    } else
11688       f.samples = 0;
11689    iax_frame_wrap(fr, &f);
11690 
11691    /* If this is our most recent packet, use it as our basis for timestamping */
11692    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11693       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
11694       fr->outoforder = 0;
11695    } else {
11696       if (iaxdebug && iaxs[fr->callno]) {
11697          ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last);
11698       }
11699       fr->outoforder = -1;
11700    }
11701    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11702    duped_fr = iaxfrdup2(fr);
11703    if (duped_fr) {
11704       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11705    }
11706    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11707       iaxs[fr->callno]->last = fr->ts;
11708 #if 1
11709       if (iaxdebug)
11710          ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11711 #endif
11712    }
11713 
11714    /* Always run again */
11715    ast_variables_destroy(ies.vars);
11716    ast_mutex_unlock(&iaxsl[fr->callno]);
11717    return 1;
11718 }

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

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

Referenced by socket_process().

09719 {
09720    unsigned char metatype;
09721    struct ast_iax2_meta_trunk_mini *mtm;
09722    struct ast_iax2_meta_trunk_hdr *mth;
09723    struct ast_iax2_meta_trunk_entry *mte;
09724    struct iax2_trunk_peer *tpeer;
09725    unsigned int ts;
09726    void *ptr;
09727    struct timeval rxtrunktime;
09728    struct ast_frame f = { 0, };
09729 
09730    if (packet_len < sizeof(*meta)) {
09731       ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 
09732          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09733       return 1;
09734    }
09735 
09736    if (meta->metacmd != IAX_META_TRUNK)
09737       return 1;
09738 
09739    if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09740       ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09741          (int) (sizeof(*meta) + sizeof(*mth)));
09742       return 1;
09743    }
09744    mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09745    ts = ntohl(mth->ts);
09746    metatype = meta->cmddata;
09747    packet_len -= (sizeof(*meta) + sizeof(*mth));
09748    ptr = mth->data;
09749    tpeer = find_tpeer(sin, sockfd);
09750    if (!tpeer) {
09751       ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 
09752          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09753       return 1;
09754    }
09755    tpeer->trunkact = ast_tvnow();
09756    if (!ts || ast_tvzero(tpeer->rxtrunktime))
09757       tpeer->rxtrunktime = tpeer->trunkact;
09758    rxtrunktime = tpeer->rxtrunktime;
09759    ast_mutex_unlock(&tpeer->lock);
09760    while (packet_len >= sizeof(*mte)) {
09761       /* Process channels */
09762       unsigned short callno, trunked_ts, len;
09763 
09764       if (metatype == IAX_META_TRUNK_MINI) {
09765          mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09766          ptr += sizeof(*mtm);
09767          packet_len -= sizeof(*mtm);
09768          len = ntohs(mtm->len);
09769          callno = ntohs(mtm->mini.callno);
09770          trunked_ts = ntohs(mtm->mini.ts);
09771       } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09772          mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09773          ptr += sizeof(*mte);
09774          packet_len -= sizeof(*mte);
09775          len = ntohs(mte->len);
09776          callno = ntohs(mte->callno);
09777          trunked_ts = 0;
09778       } else {
09779          ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09780          break;
09781       }
09782       /* Stop if we don't have enough data */
09783       if (len > packet_len)
09784          break;
09785       fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09786       if (!fr->callno)
09787          continue;
09788 
09789       /* If it's a valid call, deliver the contents.  If not, we
09790          drop it, since we don't have a scallno to use for an INVAL */
09791       /* Process as a mini frame */
09792       memset(&f, 0, sizeof(f));
09793       f.frametype = AST_FRAME_VOICE;
09794       if (!iaxs[fr->callno]) {
09795          /* drop it */
09796       } else if (iaxs[fr->callno]->voiceformat == 0) {
09797          ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09798          iax2_vnak(fr->callno);
09799       } else {
09800          f.subclass.codec = iaxs[fr->callno]->voiceformat;
09801          f.datalen = len;
09802          if (f.datalen >= 0) {
09803             if (f.datalen)
09804                f.data.ptr = ptr;
09805             else
09806                f.data.ptr = NULL;
09807             if (trunked_ts)
09808                fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09809             else
09810                fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09811             /* Don't pass any packets until we're started */
09812             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09813                struct iax_frame *duped_fr;
09814 
09815                /* Common things */
09816                f.src = "IAX2";
09817                f.mallocd = 0;
09818                f.offset = 0;
09819                if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
09820                   f.samples = ast_codec_get_samples(&f);
09821                else
09822                   f.samples = 0;
09823                fr->outoforder = 0;
09824                iax_frame_wrap(fr, &f);
09825                duped_fr = iaxfrdup2(fr);
09826                if (duped_fr)
09827                   schedule_delivery(duped_fr, 1, 1, &fr->ts);
09828                if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09829                   iaxs[fr->callno]->last = fr->ts;
09830             }
09831          } else {
09832             ast_log(LOG_WARNING, "Datalen < 0?\n");
09833          }
09834       }
09835       ast_mutex_unlock(&iaxsl[fr->callno]);
09836       ptr += len;
09837       packet_len -= len;
09838    }
09839 
09840    return 1;
09841 }

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

Definition at line 9637 of file chan_iax2.c.

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

Referenced by peer_set_srcaddr(), and set_config().

09638 {
09639    struct iax2_thread *thread;
09640    socklen_t len;
09641    time_t t;
09642    static time_t last_errtime = 0;
09643    struct ast_iax2_full_hdr *fh;
09644 
09645    if (!(thread = find_idle_thread())) {
09646       time(&t);
09647       if (t != last_errtime) {
09648          last_errtime = t;
09649          ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09650       }
09651       usleep(1);
09652       return 1;
09653    }
09654 
09655    len = sizeof(thread->iosin);
09656    thread->iofd = fd;
09657    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09658    thread->buf_size = sizeof(thread->readbuf);
09659    thread->buf = thread->readbuf;
09660    if (thread->buf_len < 0) {
09661       if (errno != ECONNREFUSED && errno != EAGAIN)
09662          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09663       handle_error();
09664       thread->iostate = IAX_IOSTATE_IDLE;
09665       signal_condition(&thread->lock, &thread->cond);
09666       return 1;
09667    }
09668    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
09669       thread->iostate = IAX_IOSTATE_IDLE;
09670       signal_condition(&thread->lock, &thread->cond);
09671       return 1;
09672    }
09673    
09674    /* Determine if this frame is a full frame; if so, and any thread is currently
09675       processing a full frame for the same callno from this peer, then drop this
09676       frame (and the peer will retransmit it) */
09677    fh = (struct ast_iax2_full_hdr *) thread->buf;
09678    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09679       struct iax2_thread *cur = NULL;
09680       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09681       
09682       AST_LIST_LOCK(&active_list);
09683       AST_LIST_TRAVERSE(&active_list, cur, list) {
09684          if ((cur->ffinfo.callno == callno) &&
09685              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09686             break;
09687       }
09688       if (cur) {
09689          /* we found another thread processing a full frame for this call,
09690             so queue it up for processing later. */
09691          defer_full_frame(thread, cur);
09692          AST_LIST_UNLOCK(&active_list);
09693          thread->iostate = IAX_IOSTATE_IDLE;
09694          signal_condition(&thread->lock, &thread->cond);
09695          return 1;
09696       } else {
09697          /* this thread is going to process this frame, so mark it */
09698          thread->ffinfo.callno = callno;
09699          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09700          thread->ffinfo.type = fh->type;
09701          thread->ffinfo.csub = fh->csub;
09702          AST_LIST_INSERT_HEAD(&active_list, thread, list);
09703       }
09704       AST_LIST_UNLOCK(&active_list);
09705    }
09706    
09707    /* Mark as ready and send on its way */
09708    thread->iostate = IAX_IOSTATE_READY;
09709 #ifdef DEBUG_SCHED_MULTITHREAD
09710    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09711 #endif
09712    signal_condition(&thread->lock, &thread->cond);
09713 
09714    return 1;
09715 }

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

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

09305 {
09306    pthread_t newthread;
09307    struct dpreq_data *dpr;
09308    
09309    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09310       return;
09311 
09312    dpr->callno = callno;
09313    ast_copy_string(dpr->context, context, sizeof(dpr->context));
09314    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09315    if (callerid)
09316       dpr->callerid = ast_strdup(callerid);
09317    if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09318       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09319    }
09320 }

static int start_network_thread ( void   )  [static]

Definition at line 12282 of file chan_iax2.c.

References ast_calloc, ast_cond_destroy, ast_cond_init, ast_cond_wait, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, ast_verb, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, LOG_ERROR, LOG_WARNING, network_thread(), and thread.

Referenced by load_module().

12283 {
12284    struct iax2_thread *thread;
12285    int threadcount = 0;
12286    int x;
12287    for (x = 0; x < iaxthreadcount; x++) {
12288       thread = ast_calloc(1, sizeof(*thread));
12289       if (thread) {
12290          thread->type = IAX_THREAD_TYPE_POOL;
12291          thread->threadnum = ++threadcount;
12292          ast_mutex_init(&thread->lock);
12293          ast_cond_init(&thread->cond, NULL);
12294          ast_mutex_init(&thread->init_lock);
12295          ast_cond_init(&thread->init_cond, NULL);
12296 
12297          ast_mutex_lock(&thread->init_lock);
12298 
12299          if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12300             ast_log(LOG_WARNING, "Failed to create new thread!\n");
12301             ast_mutex_destroy(&thread->lock);
12302             ast_cond_destroy(&thread->cond);
12303             ast_mutex_unlock(&thread->init_lock);
12304             ast_mutex_destroy(&thread->init_lock);
12305             ast_cond_destroy(&thread->init_cond);
12306             ast_free(thread);
12307             thread = NULL;
12308             continue;
12309          }
12310          /* Wait for the thread to be ready */
12311          ast_cond_wait(&thread->init_cond, &thread->init_lock);
12312 
12313          /* Done with init_lock */
12314          ast_mutex_unlock(&thread->init_lock);
12315 
12316          AST_LIST_LOCK(&idle_list);
12317          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12318          AST_LIST_UNLOCK(&idle_list);
12319       }
12320    }
12321    if (ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL)) {
12322       ast_log(LOG_ERROR, "Failed to create new thread!\n");
12323       return -1;
12324    }
12325    ast_verb(2, "%d helper threads started\n", threadcount);
12326    return 0;
12327 }

static void stop_stuff ( int  callno  )  [static]

Definition at line 9007 of file chan_iax2.c.

References iax2_destroy_helper(), and iaxs.

Referenced by socket_process().

09008 {
09009    iax2_destroy_helper(iaxs[callno]);
09010 }

static void store_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2130 of file chan_iax2.c.

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

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

02131 {
02132    if (!pvt->peercallno) {
02133       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02134       return;
02135    }
02136 
02137    ao2_link(iax_peercallno_pvts, pvt);
02138 }

static void store_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2111 of file chan_iax2.c.

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

Referenced by try_transfer().

02112 {
02113    if (!pvt->transfercallno) {
02114       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02115       return;
02116    }
02117 
02118    ao2_link(iax_transfercallno_pvts, pvt);
02119 }

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

Definition at line 9190 of file chan_iax2.c.

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

Referenced by network_thread().

09191 {
09192    int res, processed = 0, totalcalls = 0;
09193    struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09194    struct timeval now = ast_tvnow();
09195 
09196    if (iaxtrunkdebug)
09197       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09198 
09199    if (timer) {
09200       if (ast_timer_ack(timer, 1) < 0) {
09201          ast_log(LOG_ERROR, "Timer failed acknowledge\n");
09202          return 0;
09203       }
09204    }
09205 
09206    /* For each peer that supports trunking... */
09207    AST_LIST_LOCK(&tpeers);
09208    AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09209       processed++;
09210       res = 0;
09211       ast_mutex_lock(&tpeer->lock);
09212       /* We can drop a single tpeer per pass.  That makes all this logic
09213          substantially easier */
09214       if (!drop && iax2_trunk_expired(tpeer, &now)) {
09215          /* Take it out of the list, but don't free it yet, because it
09216             could be in use */
09217          AST_LIST_REMOVE_CURRENT(list);
09218          drop = tpeer;
09219       } else {
09220          res = send_trunk(tpeer, &now);
09221          trunk_timed++; 
09222          if (iaxtrunkdebug)
09223             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);
09224       }     
09225       totalcalls += res;   
09226       res = 0;
09227       ast_mutex_unlock(&tpeer->lock);
09228    }
09229    AST_LIST_TRAVERSE_SAFE_END;
09230    AST_LIST_UNLOCK(&tpeers);
09231 
09232    if (drop) {
09233       ast_mutex_lock(&drop->lock);
09234       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
09235          because by the time they could get tpeerlock, we've already grabbed it */
09236       ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09237       if (drop->trunkdata) {
09238          ast_free(drop->trunkdata);
09239          drop->trunkdata = NULL;
09240       }
09241       ast_mutex_unlock(&drop->lock);
09242       ast_mutex_destroy(&drop->lock);
09243       ast_free(drop);
09244       
09245    }
09246 
09247    if (iaxtrunkdebug)
09248       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09249    iaxtrunkdebug = 0;
09250 
09251    return 1;
09252 }

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

Definition at line 14554 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, and match().

Referenced by load_objects().

14555 {
14556    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14557 
14558    /* The frames_received field is used to hold whether we're matching
14559     * against a full frame or not ... */
14560 
14561    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14562       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14563 }

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

Definition at line 14547 of file chan_iax2.c.

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

14548 {
14549    const struct chan_iax2_pvt *pvt = obj;
14550 
14551    return pvt->transfercallno;
14552 }

static int transmit_frame ( void *  data  )  [static]

Definition at line 4264 of file chan_iax2.c.

References AST_LIST_INSERT_TAIL, ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, iax2_sched_add(), iax_frame_free(), iaxs, iaxsl, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), and iax_frame::sentyet.

Referenced by iax2_transmit().

04265 {
04266    struct iax_frame *fr = data;
04267 
04268    ast_mutex_lock(&iaxsl[fr->callno]);
04269 
04270    fr->sentyet = 1;
04271 
04272    if (iaxs[fr->callno]) {
04273       send_packet(fr);
04274    }
04275 
04276    if (fr->retries < 0) {
04277       ast_mutex_unlock(&iaxsl[fr->callno]);
04278       /* No retransmit requested */
04279       iax_frame_free(fr);
04280    } else {
04281       /* We need reliable delivery.  Schedule a retransmission */
04282       AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04283       fr->retries++;
04284       fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04285       ast_mutex_unlock(&iaxsl[fr->callno]);
04286    }
04287 
04288    return 0;
04289 }

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

Definition at line 3322 of file chan_iax2.c.

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

Referenced by send_trunk().

03323 {
03324    int res;
03325    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03326                sizeof(*sin));
03327    if (res < 0) {
03328       ast_debug(1, "Received error: %s\n", strerror(errno));
03329       handle_error();
03330    } else
03331       res = 0;
03332    return res;
03333 }

static int try_firmware ( char *  s  )  [static]

Definition at line 3027 of file chan_iax2.c.

References ast_alloca, ast_calloc, AST_FILE_MODE, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strlen_zero(), MD5Context::buf, ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, errno, IAX_FIRMWARE_MAGIC, last, len(), LOG_WARNING, ast_iax2_firmware_header::magic, MD5Final(), MD5Init(), MD5Update(), and ast_iax2_firmware_header::version.

Referenced by reload_firmware().

03028 {
03029    struct stat stbuf;
03030    struct iax_firmware *cur = NULL;
03031    int ifd, fd, res, len, chunk;
03032    struct ast_iax2_firmware_header *fwh, fwh2;
03033    struct MD5Context md5;
03034    unsigned char sum[16], buf[1024];
03035    char *s2, *last;
03036 
03037    s2 = ast_alloca(strlen(s) + 100);
03038 
03039    last = strrchr(s, '/');
03040    if (last)
03041       last++;
03042    else
03043       last = s;
03044 
03045    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
03046 
03047    if ((res = stat(s, &stbuf) < 0)) {
03048       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03049       return -1;
03050    }
03051 
03052    /* Make sure it's not a directory */
03053    if (S_ISDIR(stbuf.st_mode))
03054       return -1;
03055    ifd = open(s, O_RDONLY);
03056    if (ifd < 0) {
03057       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03058       return -1;
03059    }
03060    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03061    if (fd < 0) {
03062       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03063       close(ifd);
03064       return -1;
03065    }
03066    /* Unlink our newly created file */
03067    unlink(s2);
03068    
03069    /* Now copy the firmware into it */
03070    len = stbuf.st_size;
03071    while(len) {
03072       chunk = len;
03073       if (chunk > sizeof(buf))
03074          chunk = sizeof(buf);
03075       res = read(ifd, buf, chunk);
03076       if (res != chunk) {
03077          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03078          close(ifd);
03079          close(fd);
03080          return -1;
03081       }
03082       res = write(fd, buf, chunk);
03083       if (res != chunk) {
03084          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03085          close(ifd);
03086          close(fd);
03087          return -1;
03088       }
03089       len -= chunk;
03090    }
03091    close(ifd);
03092    /* Return to the beginning */
03093    lseek(fd, 0, SEEK_SET);
03094    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03095       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03096       close(fd);
03097       return -1;
03098    }
03099    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03100       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03101       close(fd);
03102       return -1;
03103    }
03104    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03105       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03106       close(fd);
03107       return -1;
03108    }
03109    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03110       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03111       close(fd);
03112       return -1;
03113    }
03114    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
03115    if (fwh == MAP_FAILED) {
03116       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03117       close(fd);
03118       return -1;
03119    }
03120    MD5Init(&md5);
03121    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03122    MD5Final(sum, &md5);
03123    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03124       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03125       munmap((void*)fwh, stbuf.st_size);
03126       close(fd);
03127       return -1;
03128    }
03129 
03130    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03131       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03132          /* Found a candidate */
03133          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03134             /* The version we have on loaded is older, load this one instead */
03135             break;
03136          /* This version is no newer than what we have.  Don't worry about it.
03137             We'll consider it a proper load anyhow though */
03138          munmap((void*)fwh, stbuf.st_size);
03139          close(fd);
03140          return 0;
03141       }
03142    }
03143    
03144    if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03145       cur->fd = -1;
03146       AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03147    }
03148    
03149    if (cur) {
03150       if (cur->fwh)
03151          munmap((void*)cur->fwh, cur->mmaplen);
03152       if (cur->fd > -1)
03153          close(cur->fd);
03154       cur->fwh = fwh;
03155       cur->fd = fd;
03156       cur->mmaplen = stbuf.st_size;
03157       cur->dead = 0;
03158    }
03159    
03160    return 0;
03161 }

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

Definition at line 8324 of file chan_iax2.c.

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

Referenced by socket_process().

08325 {
08326    int newcall = 0;
08327    char newip[256];
08328    struct iax_ie_data ied;
08329    struct sockaddr_in new = { 0, };
08330 
08331    memset(&ied, 0, sizeof(ied));
08332    if (ies->apparent_addr)
08333       memmove(&new, ies->apparent_addr, sizeof(new));
08334    if (ies->callno)
08335       newcall = ies->callno;
08336    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08337       ast_log(LOG_WARNING, "Invalid transfer request\n");
08338       return -1;
08339    }
08340    pvt->transfercallno = newcall;
08341    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08342    inet_aton(newip, &pvt->transfer.sin_addr);
08343    pvt->transfer.sin_family = AF_INET;
08344    pvt->transferid = ies->transferid;
08345    /* only store by transfercallno if this is a new transfer,
08346     * just in case we get a duplicate TXREQ */
08347    if (pvt->transferring == TRANSFER_NONE) {
08348       store_by_transfercallno(pvt);
08349    }
08350    pvt->transferring = TRANSFER_BEGIN;
08351 
08352    if (ies->transferid)
08353       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08354    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08355    return 0;
08356 }

static format_t uncompress_subclass ( unsigned char  csub  )  [static]

Definition at line 1628 of file chan_iax2.c.

References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

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

01629 {
01630    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01631    if (csub & IAX_FLAG_SC_LOG) {
01632       /* special case for 'compressed' -1 */
01633       if (csub == 0xff)
01634          return -1;
01635       else
01636          return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01637    }
01638    else
01639       return csub;
01640 }

static void unlink_peer ( struct iax2_peer peer  )  [static]

Definition at line 8618 of file chan_iax2.c.

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

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

08619 {
08620    if (peer->expire > -1) {
08621       if (!ast_sched_thread_del(sched, peer->expire)) {
08622          peer->expire = -1;
08623          peer_unref(peer);
08624       }
08625    }
08626 
08627    if (peer->pokeexpire > -1) {
08628       if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08629          peer->pokeexpire = -1;
08630          peer_unref(peer);
08631       }
08632    }
08633 
08634    ao2_unlink(peers, peer);
08635 }

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

Definition at line 5472 of file chan_iax2.c.

References ast_mutex_unlock, and iaxsl.

Referenced by iax2_bridge().

05473 {
05474    ast_mutex_unlock(&iaxsl[callno1]);
05475    ast_mutex_unlock(&iaxsl[callno0]);
05476 }

static void unwrap_timestamp ( struct iax_frame fr  )  [static]

Definition at line 4017 of file chan_iax2.c.

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

Referenced by schedule_delivery().

04018 {
04019    /* Video mini frames only encode the lower 15 bits of the session
04020     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
04021    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
04022    const int lower_mask = (1 << ts_shift) - 1;
04023    const int upper_mask = ~lower_mask;
04024    const int last_upper = iaxs[fr->callno]->last & upper_mask;
04025 
04026    if ( (fr->ts & upper_mask) == last_upper ) {
04027       const int x = fr->ts - iaxs[fr->callno]->last;
04028       const int threshold = (ts_shift == 15) ? 25000 : 50000;
04029 
04030       if (x < -threshold) {
04031          /* Sudden big jump backwards in timestamp:
04032             What likely happened here is that miniframe timestamp has circled but we haven't
04033             gotten the update from the main packet.  We'll just pretend that we did, and
04034             update the timestamp appropriately. */
04035          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04036          if (iaxdebug)
04037             ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04038       } else if (x > threshold) {
04039          /* Sudden apparent big jump forwards in timestamp:
04040             What's likely happened is this is an old miniframe belonging to the previous
04041             top 15 or 16-bit timestamp that has turned up out of order.
04042             Adjust the timestamp appropriately. */
04043          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04044          if (iaxdebug)
04045             ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04046       }
04047    }
04048 }

static void update_jbsched ( struct chan_iax2_pvt pvt  )  [static]

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

04053 {
04054    int when;
04055    
04056    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04057    
04058    when = jb_next(pvt->jb) - when;
04059 
04060    if (when <= 0) {
04061       /* XXX should really just empty until when > 0.. */
04062       when = 1;
04063    }
04064    
04065    pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 
04066       CALLNO_TO_PTR(pvt->callno));
04067 }

static int update_packet ( struct iax_frame f  )  [static]

Definition at line 3458 of file chan_iax2.c.

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

Referenced by __attempt_transmit().

03459 {
03460    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
03461    struct ast_iax2_full_hdr *fh = f->data;
03462    struct ast_frame af;
03463 
03464    /* if frame is encrypted. decrypt before updating it. */
03465    if (f->encmethods) {
03466       decode_frame(&f->mydcx, fh, &af, &f->datalen);
03467    }
03468    /* Mark this as a retransmission */
03469    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03470    /* Update iseqno */
03471    f->iseqno = iaxs[f->callno]->iseqno;
03472    fh->iseqno = f->iseqno;
03473 
03474    /* Now re-encrypt the frame */
03475    if (f->encmethods) {
03476    /* since this is a retransmit frame, create a new random padding
03477     * before re-encrypting. */
03478       build_rand_pad(f->semirand, sizeof(f->semirand));
03479       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03480    }
03481    return 0;
03482 }

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

References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, ast_sockaddr_cmp(), ast_sockaddr_from_sin, ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_verb, iax_ie_data::buf, context, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, iaxsl, LOG_NOTICE, LOG_WARNING, mailbox, manager_event, iax2_peer::maxcallno, peer_ref(), peer_unref(), peercnt_modify(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), send_command_final(), iax2_peer::sockfd, and version.

Referenced by socket_process().

08737 {
08738    /* Called from IAX thread only, with proper iaxsl lock */
08739    struct iax_ie_data ied = {
08740       .pos = 0,
08741    };
08742    struct iax2_peer *p;
08743    int msgcount;
08744    char data[80];
08745    int version;
08746    const char *peer_name;
08747    int res = -1;
08748    struct ast_sockaddr sockaddr;
08749 
08750    ast_sockaddr_from_sin(&sockaddr, sin);
08751 
08752    peer_name = ast_strdupa(iaxs[callno]->peer);
08753 
08754    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
08755    ast_mutex_unlock(&iaxsl[callno]);
08756    if (!(p = find_peer(peer_name, 1))) {
08757       ast_mutex_lock(&iaxsl[callno]);
08758       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08759       return -1;
08760    }
08761    ast_mutex_lock(&iaxsl[callno]);
08762    if (!iaxs[callno])
08763       goto return_unref;
08764 
08765    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08766       if (sin->sin_addr.s_addr) {
08767          time_t nowtime;
08768          time(&nowtime);
08769          realtime_update_peer(peer_name, &sockaddr, nowtime);
08770       } else {
08771          realtime_update_peer(peer_name, &sockaddr, 0);
08772       }
08773    }
08774 
08775    /* treat an unspecified refresh interval as the minimum */
08776    if (!refresh) {
08777       refresh = min_reg_expire;
08778    }
08779    if (refresh > max_reg_expire) {
08780       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08781          p->name, max_reg_expire, refresh);
08782       p->expiry = max_reg_expire;
08783    } else if (refresh < min_reg_expire) {
08784       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08785          p->name, min_reg_expire, refresh);
08786       p->expiry = min_reg_expire;
08787    } else {
08788       p->expiry = refresh;
08789    }
08790 
08791    if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08792       if (iax2_regfunk) {
08793          iax2_regfunk(p->name, 1);
08794       }
08795 
08796       /* modify entry in peercnts table as _not_ registered */
08797       peercnt_modify((unsigned char) 0, 0, &p->addr);
08798 
08799       /* Stash the IP address from which they registered */
08800       ast_sockaddr_from_sin(&p->addr, sin);
08801 
08802       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08803       if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08804          ast_db_put("IAX/Registry", p->name, data);
08805          ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08806                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08807          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08808          register_peer_exten(p, 1);
08809          ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
08810       } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08811          ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08812                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08813          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08814          register_peer_exten(p, 0);
08815          ast_db_del("IAX/Registry", p->name);
08816          ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
08817       }
08818       /* Update the host */
08819       /* Verify that the host is really there */
08820       iax2_poke_peer(p, callno);
08821    }
08822 
08823    /* modify entry in peercnts table as registered */
08824    if (p->maxcallno) {
08825       peercnt_modify((unsigned char) 1, p->maxcallno, &p->addr);
08826    }
08827 
08828    /* Make sure our call still exists, an INVAL at the right point may make it go away */
08829    if (!iaxs[callno]) {
08830       res = -1;
08831       goto return_unref;
08832    }
08833 
08834    /* Store socket fd */
08835    p->sockfd = fd;
08836    /* Setup the expiry */
08837    if (p->expire > -1) {
08838       if (!ast_sched_thread_del(sched, p->expire)) {
08839          p->expire = -1;
08840          peer_unref(p);
08841       }
08842    }
08843 
08844    if (p->expiry && sin->sin_addr.s_addr) {
08845       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08846       if (p->expire == -1)
08847          peer_unref(p);
08848    }
08849    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08850    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08851    if (sin->sin_addr.s_addr) {
08852       struct sockaddr_in peer_addr;
08853 
08854       ast_sockaddr_to_sin(&p->addr, &peer_addr);
08855 
08856       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08857       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08858       if (!ast_strlen_zero(p->mailbox)) {
08859          struct ast_event *event;
08860          int new, old;
08861          char *mailbox, *context;
08862 
08863          context = mailbox = ast_strdupa(p->mailbox);
08864          strsep(&context, "@");
08865          if (ast_strlen_zero(context))
08866             context = "default";
08867 
08868          event = ast_event_get_cached(AST_EVENT_MWI,
08869             AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08870             AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08871             AST_EVENT_IE_END);
08872          if (event) {
08873             new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08874             old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08875             ast_event_destroy(event);
08876          } else { /* Fall back on checking the mailbox directly */
08877             ast_app_inboxcount(p->mailbox, &new, &old);
08878          }
08879 
08880          if (new > 255) {
08881             new = 255;
08882          }
08883          if (old > 255) {
08884             old = 255;
08885          }
08886          msgcount = (old << 8) | new;
08887 
08888          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08889       }
08890       if (ast_test_flag64(p, IAX_HASCALLERID)) {
08891          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08892          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08893       }
08894    }
08895    version = iax_check_version(devtype);
08896    if (version) 
08897       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08898 
08899    res = 0;
08900 
08901 return_unref:
08902    peer_unref(p);
08903 
08904    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08905 }

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

References CMP_MATCH, and CMP_STOP.

Referenced by load_objects().

01676 {
01677    struct iax2_user *user = obj, *user2 = arg;
01678 
01679    return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01680 }

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

Definition at line 13033 of file chan_iax2.c.

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

13034 {
13035    struct iax2_user *user = obj;
13036 
13037    ast_set_flag64(user, IAX_DELME);
13038 
13039    return 0;
13040 }

static void user_destructor ( void *  obj  )  [static]

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

12759 {
12760    struct iax2_user *user = obj;
12761 
12762    ast_free_ha(user->ha);
12763    free_context(user->contexts);
12764    if(user->vars) {
12765       ast_variables_destroy(user->vars);
12766       user->vars = NULL;
12767    }
12768    ast_string_field_free_memory(user);
12769 }

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

References ast_str_hash().

Referenced by load_objects().

01666 {
01667    const struct iax2_user *user = obj;
01668 
01669    return ast_str_hash(user->name);
01670 }

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

Definition at line 1722 of file chan_iax2.c.

References ao2_ref.

01723 {
01724    ao2_ref(user, +1);
01725    return user;
01726 }

static struct iax2_user* user_unref ( struct iax2_user user  )  [static, read]
static int users_data_provider_get ( const struct ast_data_search search,
struct ast_data data_root 
) [static]

Definition at line 14717 of file chan_iax2.c.

References iax2_user::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cdr_flags2str(), ast_copy_string(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_password(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_strlen_zero(), ast_test_flag64, iax2_user::authmethods, iax2_user::capability, iax2_context::context, iax2_user::contexts, DEFAULT_CONTEXT, iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, and user_unref().

14719 {
14720    struct ast_data *data_user, *data_authmethods, *data_enum_node;
14721    struct iax2_user *user;
14722    struct ao2_iterator i;
14723    char auth[90];
14724    char *pstr = "";
14725 
14726    i = ao2_iterator_init(users, 0);
14727    for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
14728       data_user = ast_data_add_node(data_root, "user");
14729       if (!data_user) {
14730          continue;
14731       }
14732 
14733       ast_data_add_structure(iax2_user, data_user, user);
14734 
14735       ast_data_add_codecs(data_user, "codecs", user->capability);
14736 
14737       if (!ast_strlen_zero(user->secret)) {
14738          ast_copy_string(auth, user->secret, sizeof(auth));
14739       } else if (!ast_strlen_zero(user->inkeys)) {
14740          snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14741       } else {
14742          ast_copy_string(auth, "no secret", sizeof(auth));
14743       }
14744       ast_data_add_password(data_user, "secret", auth);
14745 
14746       ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14747 
14748       /* authmethods */
14749       data_authmethods = ast_data_add_node(data_user, "authmethods");
14750       if (!data_authmethods) {
14751          ast_data_remove_node(data_root, data_user);
14752          continue;
14753       }
14754       ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14755       ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14756       ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14757 
14758       /* amaflags */
14759       data_enum_node = ast_data_add_node(data_user, "amaflags");
14760       if (!data_enum_node) {
14761          ast_data_remove_node(data_root, data_user);
14762          continue;
14763       }
14764       ast_data_add_int(data_enum_node, "value", user->amaflags);
14765       ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14766 
14767       ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14768 
14769       if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14770          pstr = "REQ only";
14771       } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14772          pstr = "disabled";
14773       } else {
14774          pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14775       }
14776       ast_data_add_str(data_user, "codec-preferences", pstr);
14777 
14778       if (!ast_data_search_match(search, data_user)) {
14779          ast_data_remove_node(data_root, data_user);
14780       }
14781    }
14782    ao2_iterator_destroy(&i);
14783 
14784    return 0;
14785 }

static void vnak_retransmit ( int  callno,
int  last 
) [static]

Definition at line 9108 of file chan_iax2.c.

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

Referenced by socket_process().

09109 {
09110    struct iax_frame *f;
09111 
09112    AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09113       /* Send a copy immediately */
09114       if (((unsigned char) (f->oseqno - last) < 128) &&
09115             (f->retries >= 0)) {
09116          send_packet(f);
09117       }
09118    }
09119 }

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

Definition at line 5282 of file chan_iax2.c.

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

Referenced by iax2_indicate(), and iax2_setoption().

05283 {
05284    unsigned short callno = pvt->callno;
05285 
05286    if (!pvt->peercallno) {
05287       /* We don't know the remote side's call number, yet.  :( */
05288       int count = 10;
05289       while (count-- && pvt && !pvt->peercallno) {
05290          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05291          pvt = iaxs[callno];
05292       }
05293       if (!pvt || !pvt->peercallno) {
05294          return -1;
05295       }
05296    }
05297 
05298    return 0;
05299 }


Variable Documentation

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

Definition at line 387 of file chan_iax2.c.

int amaflags = 0 [static]

Definition at line 386 of file chan_iax2.c.

Referenced by ast_async_goto().

int authdebug = 1 [static]

Definition at line 294 of file chan_iax2.c.

int autokill = 0 [static]

Definition at line 295 of file chan_iax2.c.

struct ao2_container* callno_pool [static]

table of available call numbers

Definition at line 849 of file chan_iax2.c.

const unsigned int CALLNO_POOL_BUCKETS = 2699 [static]

Definition at line 854 of file chan_iax2.c.

struct ao2_container* callno_pool_trunk [static]

table of available trunk call numbers

Definition at line 852 of file chan_iax2.c.

struct ast_cli_entry cli_iax2[] [static]

Definition at line 14257 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

unsigned int cos

Definition at line 305 of file chan_iax2.c.

struct sockaddr_in debugaddr [static]

Definition at line 1101 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_debug(), iax_outputframe(), and reload_config().

char default_parkinglot[AST_MAX_CONTEXT] [static]

Definition at line 272 of file chan_iax2.c.

int defaultsockfd = -1 [static]

Definition at line 317 of file chan_iax2.c.

int delayreject = 0 [static]

Definition at line 388 of file chan_iax2.c.

int global_max_trunk_mtu [static]

Maximum MTU, 0 if not used

Definition at line 267 of file chan_iax2.c.

int global_rtautoclear = 120 [static]

Definition at line 439 of file chan_iax2.c.

struct ast_flags64 globalflags = { 0 } [static]

Definition at line 391 of file chan_iax2.c.

format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static]

Definition at line 369 of file chan_iax2.c.

Initial value:
 {
   AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
   AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
}

Definition at line 14797 of file chan_iax2.c.

Referenced by load_module().

int iax2_encryption = 0 [static]

Definition at line 389 of file chan_iax2.c.

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

Definition at line 14143 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

struct ast_channel_tech iax2_tech [static]
Initial value:
 {
   .type = "IAX2_VARIABLE",
   .duplicate = iax2_dup_variable_datastore,
   .destroy = iax2_free_variable_datastore,
}

Definition at line 1331 of file chan_iax2.c.

Referenced by acf_iaxvar_read(), acf_iaxvar_write(), ast_iax2_new(), authenticate_reply(), iax2_call(), and socket_process().

Another container of iax2_pvt structures.

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

Definition at line 1078 of file chan_iax2.c.

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_peercallno(), and store_by_peercallno().

Another container of iax2_pvt structures.

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

Definition at line 1094 of file chan_iax2.c.

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_transfercallno(), and store_by_transfercallno().

int iaxactivethreadcount = 0 [static]

Definition at line 638 of file chan_iax2.c.

Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().

int iaxcompat = 0 [static]

Definition at line 296 of file chan_iax2.c.

int iaxdebug = 0 [static]

Definition at line 371 of file chan_iax2.c.

int iaxdefaultdpcache = 10 * 60 [static]

Definition at line 299 of file chan_iax2.c.

int iaxdefaulttimeout = 5 [static]

Definition at line 301 of file chan_iax2.c.

int iaxdynamicthreadcount = 0 [static]

Definition at line 636 of file chan_iax2.c.

Referenced by find_idle_thread(), and iax2_process_thread().

int iaxdynamicthreadnum = 0 [static]

Definition at line 637 of file chan_iax2.c.

Referenced by find_idle_thread().

int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static]

Definition at line 635 of file chan_iax2.c.

Referenced by find_idle_thread(), and set_config().

Initial value:
 {
   .name = "IAXPEER",
   .read = function_iaxpeer,
}

Definition at line 14063 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static]

an array of iax2 pvt structures

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

Definition at line 1067 of file chan_iax2.c.

Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __find_callno(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), acf_channel_read(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), handle_cli_iax2_show_channels(), iax2_ack_registry(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_lock_owner(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queryoption(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_setoption(), iax2_start_transfer(), iax2_vnak(), iax2_write(), load_module(), log_jitterstats(), make_trunk(), register_verify(), registry_authrequest(), registry_rerequest(), resend_with_token(), save_osptoken(), save_rr(), schedule_delivery(), scheduled_destroy(), send_command_final(), send_command_locked(), send_lagrq(), send_packet(), send_ping(), set_hangup_source_and_cause(), socket_process(), socket_process_meta(), stop_stuff(), transmit_frame(), unwrap_timestamp(), update_packet(), update_registry(), and wait_for_peercallno().

ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static]
int iaxthreadcount = DEFAULT_THREAD_COUNT [static]

Definition at line 634 of file chan_iax2.c.

Referenced by handle_cli_iax2_show_threads(), set_config(), and start_network_thread().

int iaxtrunkdebug = 0 [static]

Definition at line 373 of file chan_iax2.c.

Initial value:
 {
   .name = "IAXVAR",
   .read = acf_iaxvar_read,
   .write = acf_iaxvar_write,
}

Definition at line 9910 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct io_context* io [static]

Definition at line 364 of file chan_iax2.c.

int jittertargetextra = 40 [static]

Definition at line 287 of file chan_iax2.c.

int lagrq_time = 10 [static]

Definition at line 283 of file chan_iax2.c.

char language[MAX_LANGUAGE] = "" [static]

Definition at line 274 of file chan_iax2.c.

int last_authmethod = 0 [static]

Definition at line 297 of file chan_iax2.c.

int max_reg_expire [static]

Definition at line 309 of file chan_iax2.c.

int max_retries = 4 [static]

Definition at line 281 of file chan_iax2.c.

int maxauthreq = 3 [static]

Definition at line 280 of file chan_iax2.c.

int maxjitterbuffer = 1000 [static]

Definition at line 284 of file chan_iax2.c.

int maxjitterinterps = 10 [static]

Definition at line 286 of file chan_iax2.c.

int min_reg_expire [static]

Definition at line 308 of file chan_iax2.c.

char mohinterpret[MAX_MUSICCLASS] [static]

Definition at line 384 of file chan_iax2.c.

char mohsuggest[MAX_MUSICCLASS] [static]
struct ast_netsock_list* netsock [static]

Definition at line 315 of file chan_iax2.c.

pthread_t netthreadid = AST_PTHREADT_NULL [static]

Definition at line 393 of file chan_iax2.c.

int network_change_event_sched_id = -1 [static]

Definition at line 278 of file chan_iax2.c.

subscription id for network change events

Definition at line 277 of file chan_iax2.c.

struct ast_netsock_list* outsock [static]

used if sourceaddress specified and bindaddr == INADDR_ANY

Definition at line 316 of file chan_iax2.c.

char* papp = "IAX2Provision" [static]

Definition at line 11987 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

Initial value:

Definition at line 14787 of file chan_iax2.c.

int ping_time = 21 [static]

Definition at line 282 of file chan_iax2.c.

struct ast_codec_pref prefs [static]
struct { ... } qos [static]

Referenced by peer_set_srcaddr(), and set_config().

char regcontext[AST_MAX_CONTEXT] = "" [static]

Definition at line 275 of file chan_iax2.c.

int resyncthreshold = 1000 [static]

Definition at line 285 of file chan_iax2.c.

struct ast_sched_thread* sched [static]

Definition at line 365 of file chan_iax2.c.

int srvlookup = 0 [static]

Definition at line 311 of file chan_iax2.c.

Referenced by build_peer().

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

Definition at line 260 of file chan_iax2.c.

int test_losspct = 0 [static]

Definition at line 375 of file chan_iax2.c.

struct ast_timer* timer [static]
unsigned int tos

Definition at line 304 of file chan_iax2.c.

int trunk_maxmtu [static]

Definition at line 268 of file chan_iax2.c.

int trunk_nmaxmtu [static]

Trunk MTU statistics

Definition at line 268 of file chan_iax2.c.

int trunk_timed [static]

Definition at line 268 of file chan_iax2.c.

int trunk_untimed [static]

Definition at line 268 of file chan_iax2.c.

int trunkfreq = 20 [static]

Definition at line 291 of file chan_iax2.c.

int trunkmaxsize = MAX_TRUNKDATA [static]

Definition at line 292 of file chan_iax2.c.

Initial value:

Definition at line 14792 of file chan_iax2.c.


Generated on 3 Apr 2014 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1