Tue Aug 20 16:34:51 2013

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

#define DATA_EXPORT_IAX2_USER ( MEMBER   ) 

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

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

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

08994 {
08995    /* Called from IAX thread only, without iaxs lock */
08996    int callno = (int)(long)(nothing);
08997    struct iax_ie_data ied;
08998    ast_mutex_lock(&iaxsl[callno]);
08999    if (iaxs[callno]) {
09000       memset(&ied, 0, sizeof(ied));
09001       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
09002          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
09003          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
09004       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
09005          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
09006          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09007       }
09008       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
09009    }
09010    ast_mutex_unlock(&iaxsl[callno]);
09011 }

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

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

04669 {
04670    int callno = PTR_TO_CALLNO(nothing);
04671    struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04672    ast_mutex_lock(&iaxsl[callno]);
04673    if (iaxs[callno]) {
04674       iaxs[callno]->initid = -1;
04675       iax2_queue_frame(callno, &f);
04676       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04677    }
04678    ast_mutex_unlock(&iaxsl[callno]);
04679 }

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

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

09043 {
09044    /* Called from IAX thread only, without iaxs lock */
09045    int callno = (int)(long)(nothing);
09046    struct iax_ie_data ied;
09047    ast_mutex_lock(&iaxsl[callno]);
09048    if (iaxs[callno]) {
09049       memset(&ied, 0, sizeof(ied));
09050       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09051       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09052       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09053    }
09054    ast_mutex_unlock(&iaxsl[callno]);
09055 }

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

08620 {
08621    struct iax2_peer *peer = (struct iax2_peer *) data;
08622 
08623    if (!peer)
08624       return;
08625    if (peer->expire == -1) {
08626       /* Removed already (possibly through CLI), ignore */
08627       return;
08628    }
08629 
08630    peer->expire = -1;
08631 
08632    ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08633    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08634       realtime_update_peer(peer->name, &peer->addr, 0);
08635    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08636    /* modify entry in peercnts table as _not_ registered */
08637    peercnt_modify(0, 0, &peer->addr);
08638    /* Reset the address */
08639    memset(&peer->addr, 0, sizeof(peer->addr));
08640    /* Reset expiry value */
08641    peer->expiry = min_reg_expire;
08642    if (!ast_test_flag64(peer, IAX_TEMPONLY))
08643       ast_db_del("IAX/Registry", peer->name);
08644    register_peer_exten(peer, 0);
08645    ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
08646    if (iax2_regfunk)
08647       iax2_regfunk(peer->name, 0);
08648 
08649    if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08650       unlink_peer(peer);
08651 
08652    peer_unref(peer);
08653 }

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

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

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

Definition at line 8290 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

08291 {
08292    struct iax2_registry *reg = (struct iax2_registry *)data;
08293    reg->expire = -1;
08294    iax2_do_register(reg);
08295 }

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

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

11999 {
12000    struct iax2_peer *peer = (struct iax2_peer *)data;
12001    int callno;
12002 
12003    if (peer->lastms > -1) {
12004       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
12005       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
12006       ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
12007    }
12008    if ((callno = peer->callno) > 0) {
12009       ast_mutex_lock(&iaxsl[callno]);
12010       iax2_destroy(callno);
12011       ast_mutex_unlock(&iaxsl[callno]);
12012    }
12013    peer->callno = 0;
12014    peer->lastms = -1;
12015    /* Try again quickly */
12016    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
12017    if (peer->pokeexpire == -1)
12018       peer_unref(peer);
12019 }

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

Definition at line 9102 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

09103 {
09104    struct iax2_peer *peer = (struct iax2_peer *)data;
09105    iax2_poke_peer(peer, 0);
09106    peer_unref(peer);
09107 }

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

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

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

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

07483 {
07484    struct ast_frame f = { 0, };
07485    int res = 0;
07486 
07487    f.frametype = type;
07488    f.subclass.integer = command;
07489    f.datalen = datalen;
07490    f.src = __FUNCTION__;
07491    f.data.ptr = (void *) data;
07492 
07493    if ((res = queue_signalling(i, &f)) <= 0) {
07494       return res;
07495    }
07496 
07497    return iax2_send(i, &f, ts, seqno, now, transfer, final);
07498 }

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

14357 {
14358    struct ast_context *con;
14359    int x;
14360 
14361    network_change_event_unsubscribe();
14362 
14363    ast_manager_unregister("IAXpeers");
14364    ast_manager_unregister("IAXpeerlist");
14365    ast_manager_unregister("IAXnetstats");
14366    ast_manager_unregister("IAXregistry");
14367    ast_unregister_application(papp);
14368    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14369    ast_unregister_switch(&iax2_switch);
14370    ast_channel_unregister(&iax2_tech);
14371 
14372    if (netthreadid != AST_PTHREADT_NULL) {
14373       pthread_cancel(netthreadid);
14374       pthread_kill(netthreadid, SIGURG);
14375       pthread_join(netthreadid, NULL);
14376    }
14377 
14378    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14379       if (iaxs[x]) {
14380          iax2_destroy(x);
14381       }
14382    }
14383 
14384    /* Call for all threads to halt */
14385    cleanup_thread_list(&idle_list);
14386    cleanup_thread_list(&active_list);
14387    cleanup_thread_list(&dynamic_list);
14388 
14389    ast_netsock_release(netsock);
14390    ast_netsock_release(outsock);
14391    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14392       if (iaxs[x]) {
14393          iax2_destroy(x);
14394       }
14395    }
14396    ast_manager_unregister( "IAXpeers" );
14397    ast_manager_unregister( "IAXpeerlist" );
14398    ast_manager_unregister( "IAXnetstats" );
14399    ast_manager_unregister( "IAXregistry" );
14400    ast_unregister_application(papp);
14401 #ifdef TEST_FRAMEWORK
14402    AST_TEST_UNREGISTER(test_iax2_peers_get);
14403    AST_TEST_UNREGISTER(test_iax2_users_get);
14404 #endif
14405    ast_data_unregister(NULL);
14406    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14407    ast_unregister_switch(&iax2_switch);
14408    ast_channel_unregister(&iax2_tech);
14409    delete_users();
14410    iax_provision_unload();
14411    reload_firmware(1);
14412 
14413    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14414       ast_mutex_destroy(&iaxsl[x]);
14415    }
14416 
14417    ao2_ref(peers, -1);
14418    ao2_ref(users, -1);
14419    ao2_ref(iax_peercallno_pvts, -1);
14420    ao2_ref(iax_transfercallno_pvts, -1);
14421    ao2_ref(peercnts, -1);
14422    ao2_ref(callno_limits, -1);
14423    ao2_ref(calltoken_ignores, -1);
14424    ao2_ref(callno_pool, -1);
14425    ao2_ref(callno_pool_trunk, -1);
14426    if (timer) {
14427       ast_timer_close(timer);
14428       timer = NULL;
14429    }
14430    transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14431    sched = ast_sched_thread_destroy(sched);
14432 
14433    con = ast_context_find(regcontext);
14434    if (con)
14435       ast_context_destroy(con, "IAX2");
14436    ast_unload_realtime("iaxpeers");
14437    return 0;
14438 }

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

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

13997 {
13998    struct chan_iax2_pvt *pvt;
13999    unsigned int callno;
14000    int res = 0;
14001 
14002    if (!chan || chan->tech != &iax2_tech) {
14003       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
14004       return -1;
14005    }
14006 
14007    callno = PTR_TO_CALLNO(chan->tech_pvt);
14008    ast_mutex_lock(&iaxsl[callno]);
14009    if (!(pvt = iaxs[callno])) {
14010       ast_mutex_unlock(&iaxsl[callno]);
14011       return -1;
14012    }
14013 
14014    if (!strcasecmp(args, "osptoken")) {
14015       ast_copy_string(buf, pvt->osptoken, buflen);
14016    } else if (!strcasecmp(args, "peerip")) {
14017       ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
14018    } else if (!strcasecmp(args, "peername")) {
14019       ast_copy_string(buf, pvt->username, buflen);
14020    } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
14021       snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
14022    } else {
14023       res = -1;
14024    }
14025 
14026    ast_mutex_unlock(&iaxsl[callno]);
14027 
14028    return res;
14029 }

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

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

09821 {
09822    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09823    AST_LIST_HEAD(, ast_var_t) *varlist;
09824    struct ast_var_t *var;
09825 
09826    if (!variablestore) {
09827       *buf = '\0';
09828       return 0;
09829    }
09830    varlist = variablestore->data;
09831 
09832    AST_LIST_LOCK(varlist);
09833    AST_LIST_TRAVERSE(varlist, var, entries) {
09834       if (strcmp(var->name, data) == 0) {
09835          ast_copy_string(buf, var->value, len);
09836          break;
09837       }
09838    }
09839    AST_LIST_UNLOCK(varlist);
09840    return 0;
09841 }

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

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

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       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09851       if (!variablestore) {
09852          ast_log(LOG_ERROR, "Memory allocation error\n");
09853          return -1;
09854       }
09855       varlist = ast_calloc(1, sizeof(*varlist));
09856       if (!varlist) {
09857          ast_datastore_free(variablestore);
09858          ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09859          return -1;
09860       }
09861 
09862       AST_LIST_HEAD_INIT(varlist);
09863       variablestore->data = varlist;
09864       variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09865       ast_channel_datastore_add(chan, variablestore);
09866    } else
09867       varlist = variablestore->data;
09868 
09869    AST_LIST_LOCK(varlist);
09870    AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09871       if (strcmp(var->name, data) == 0) {
09872          AST_LIST_REMOVE_CURRENT(entries);
09873          ast_var_delete(var);
09874          break;
09875       }
09876    }
09877    AST_LIST_TRAVERSE_SAFE_END;
09878    var = ast_var_assign(data, value);
09879    if (var)
09880       AST_LIST_INSERT_TAIL(varlist, var, entries);
09881    else
09882       ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09883    AST_LIST_UNLOCK(varlist);
09884    return 0;
09885 }

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

04745 {
04746    /* first make sure their are two empty bytes left in ied->buf */
04747    if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04748       ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;  /* type */
04749       ied->buf[ied->pos++] = 0;   /* data size,  ZERO in this case */
04750       pvt->calltoken_ie_len = 2;
04751    }
04752 }

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

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

Referenced by check_access().

07540 {
07541    while(con) {
07542       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07543          return -1;
07544       con = con->next;
07545    }
07546    return 0;
07547 }

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

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

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

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

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

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

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and transmit_frame().

03562 {
03563 #ifdef SCHED_MULTITHREADED
03564    if (schedule_action(__attempt_transmit, data))
03565 #endif      
03566       __attempt_transmit(data);
03567    return 0;
03568 }

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

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

09028 {
09029    /* Schedule sending the authentication failure in one second, to prevent
09030       guessing */
09031    if (iaxs[callno]) {
09032       iaxs[callno]->authfail = failcode;
09033       if (delayreject) {
09034          iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 
09035             sched, 1000, auth_reject, (void *)(long)callno);
09036       } else
09037          auth_reject((void *)(long)callno);
09038    }
09039    return 0;
09040 }

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

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

09014 {
09015    int callno = (int)(long)(data);
09016    ast_mutex_lock(&iaxsl[callno]);
09017    if (iaxs[callno])
09018       iaxs[callno]->authid = -1;
09019    ast_mutex_unlock(&iaxsl[callno]);
09020 #ifdef SCHED_MULTITHREADED
09021    if (schedule_action(__auth_reject, data))
09022 #endif      
09023       __auth_reject(data);
09024    return 0;
09025 }

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

08113 {
08114    int res = -1;
08115    int x;
08116    if (!ast_strlen_zero(keyn)) {
08117       if (!(authmethods & IAX_AUTH_RSA)) {
08118          if (ast_strlen_zero(secret)) 
08119             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));
08120       } else if (ast_strlen_zero(challenge)) {
08121          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08122       } else {
08123          char sig[256];
08124          struct ast_key *key;
08125          key = ast_key_get(keyn, AST_KEY_PRIVATE);
08126          if (!key) {
08127             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08128          } else {
08129             if (ast_sign(key, (char*)challenge, sig)) {
08130                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08131                res = -1;
08132             } else {
08133                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08134                res = 0;
08135             }
08136          }
08137       }
08138    } 
08139    /* Fall back */
08140    if (res && !ast_strlen_zero(secret)) {
08141       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08142          struct MD5Context md5;
08143          unsigned char digest[16];
08144          char digres[128];
08145          MD5Init(&md5);
08146          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08147          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08148          MD5Final(digest, &md5);
08149          /* If they support md5, authenticate with it.  */
08150          for (x=0;x<16;x++)
08151             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
08152          if (pvt) {
08153             build_encryption_keys(digest, pvt);
08154          }
08155          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08156          res = 0;
08157       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08158          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08159          res = 0;
08160       } else
08161          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08162    }
08163    return res;
08164 }

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

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

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

07819 {
07820    struct iax_ie_data ied;
07821    int res = -1, authreq_restrict = 0;
07822    char challenge[10];
07823    struct chan_iax2_pvt *p = iaxs[call_num];
07824 
07825    memset(&ied, 0, sizeof(ied));
07826 
07827    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
07828    if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07829       struct iax2_user *user, tmp_user = {
07830          .name = p->username, 
07831       };
07832 
07833       user = ao2_find(users, &tmp_user, OBJ_POINTER);
07834       if (user) {
07835          if (user->curauthreq == user->maxauthreq)
07836             authreq_restrict = 1;
07837          else
07838             user->curauthreq++;
07839          user = user_unref(user);
07840       }
07841    }
07842 
07843    /* If the AUTHREQ limit test failed, send back an error */
07844    if (authreq_restrict) {
07845       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07846       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07847       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07848       return 0;
07849    }
07850 
07851    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07852    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07853       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07854       ast_string_field_set(p, challenge, challenge);
07855       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
07856       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07857    }
07858    if (p->encmethods)
07859       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07860 
07861    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07862 
07863    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07864 
07865    if (p->encmethods)
07866       ast_set_flag64(p, IAX_ENCRYPTED);
07867 
07868    return res;
07869 }

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

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

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

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

Definition at line 4681 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

Referenced by iax2_call().

04682 {
04683 #ifdef SCHED_MULTITHREADED
04684    if (schedule_action(__auto_congest, data))
04685 #endif      
04686       __auto_congest(data);
04687    return 0;
04688 }

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

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

09058 {
09059    int callno = (int)(long)(data);
09060    ast_mutex_lock(&iaxsl[callno]);
09061    if (iaxs[callno]) {
09062       iaxs[callno]->autoid = -1;
09063    }
09064    ast_mutex_unlock(&iaxsl[callno]);
09065 #ifdef SCHED_MULTITHREADED
09066    if (schedule_action(__auto_hangup, data))
09067 #endif      
09068       __auto_hangup(data);
09069    return 0;
09070 }

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

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

Referenced by build_user().

12258 {
12259    struct iax2_context *con;
12260 
12261    if ((con = ast_calloc(1, sizeof(*con))))
12262       ast_copy_string(con->context, context, sizeof(con->context));
12263    
12264    return con;
12265 }

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

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

06200 {
06201    /* it is required to hold the corresponding decrypt key to our encrypt key
06202     * in the pvt struct because queued frames occasionally need to be decrypted and
06203     * re-encrypted when updated for a retransmission */
06204    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06205    ast_aes_set_encrypt_key(digest, &pvt->ecx);
06206    ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06207 }

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

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

06194 {
06195    build_ecx_key(digest, pvt);
06196    ast_aes_set_decrypt_key(digest, &pvt->dcx);
06197 }

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

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

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

Definition at line 6183 of file chan_iax2.c.

References ast_random().

Referenced by build_ecx_key(), and update_packet().

06184 {
06185    long tmp;
06186    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06187       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06188       buf += sizeof(tmp);
06189       len -= sizeof(tmp);
06190    }
06191 }

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

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

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

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

13598 {
13599    struct sockaddr_in sin;
13600    int x;
13601    int callno;
13602    struct iax_ie_data ied;
13603    struct create_addr_info cai;
13604    struct parsed_dial_string pds;
13605    char *tmpstr;
13606 
13607    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13608       /* Look for an *exact match* call.  Once a call is negotiated, it can only
13609          look up entries for a single context */
13610       if (!ast_mutex_trylock(&iaxsl[x])) {
13611          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13612             return x;
13613          ast_mutex_unlock(&iaxsl[x]);
13614       }
13615    }
13616 
13617    /* No match found, we need to create a new one */
13618 
13619    memset(&cai, 0, sizeof(cai));
13620    memset(&ied, 0, sizeof(ied));
13621    memset(&pds, 0, sizeof(pds));
13622 
13623    tmpstr = ast_strdupa(data);
13624    parse_dial_string(tmpstr, &pds);
13625 
13626    if (ast_strlen_zero(pds.peer)) {
13627       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13628       return -1;
13629    }
13630 
13631    /* Populate our address from the given */
13632    if (create_addr(pds.peer, NULL, &sin, &cai))
13633       return -1;
13634 
13635    ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13636       pds.peer, pds.username, pds.password, pds.context);
13637 
13638    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13639    if (callno < 1) {
13640       ast_log(LOG_WARNING, "Unable to create call\n");
13641       return -1;
13642    }
13643 
13644    ast_string_field_set(iaxs[callno], dproot, data);
13645    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13646 
13647    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13648    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13649    /* the string format is slightly different from a standard dial string,
13650       because the context appears in the 'exten' position
13651    */
13652    if (pds.exten)
13653       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13654    if (pds.username)
13655       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13656    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13657    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13658    /* Keep password handy */
13659    if (pds.password)
13660       ast_string_field_set(iaxs[callno], secret, pds.password);
13661    if (pds.key)
13662       ast_string_field_set(iaxs[callno], outkey, pds.key);
13663    /* Start the call going */
13664    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
13665    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13666 
13667    return callno;
13668 }

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

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

06037 {
06038    /* Returns where in "receive time" we are.  That is, how many ms
06039       since we received (or would have received) the frame with timestamp 0 */
06040    int ms;
06041 #ifdef IAXTESTS
06042    int jit;
06043 #endif /* IAXTESTS */
06044    /* Setup rxcore if necessary */
06045    if (ast_tvzero(p->rxcore)) {
06046       p->rxcore = ast_tvnow();
06047       if (iaxdebug)
06048          ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
06049                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06050       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06051 #if 1
06052       if (iaxdebug)
06053          ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06054                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06055 #endif
06056    }
06057 
06058    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06059 #ifdef IAXTESTS
06060    if (test_jit) {
06061       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06062          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06063          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06064             jit = -jit;
06065          ms += jit;
06066       }
06067    }
06068    if (test_late) {
06069       ms += test_late;
06070       test_late = 0;
06071    }
06072 #endif /* IAXTESTS */
06073    return ms;
06074 }

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

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

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

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

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

05861 {
05862    unsigned long int mssincetx; /* unsigned to handle overflows */
05863    long int ms, pred;
05864 
05865    tpeer->trunkact = *now;
05866    mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05867    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05868       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
05869       tpeer->txtrunktime = *now;
05870       tpeer->lastsent = 999999;
05871    }
05872    /* Update last transmit time now */
05873    tpeer->lasttxtime = *now;
05874    
05875    /* Calculate ms offset */
05876    ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05877    /* Predict from last value */
05878    pred = tpeer->lastsent + sampms;
05879    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05880       ms = pred;
05881    
05882    /* We never send the same timestamp twice, so fudge a little if we must */
05883    if (ms == tpeer->lastsent)
05884       ms = tpeer->lastsent + 1;
05885    tpeer->lastsent = ms;
05886    return ms;
05887 }

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

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

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

Definition at line 9427 of file chan_iax2.c.

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

Referenced by socket_process().

09428 {
09429    unsigned int ourver;
09430    char rsi[80];
09431    snprintf(rsi, sizeof(rsi), "si-%s", si);
09432    if (iax_provision_version(&ourver, rsi, 1))
09433       return 0;
09434    ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09435    if (ourver != ver) 
09436       iax2_provision(sin, sockfd, NULL, rsi, 1);
09437    return 0;
09438 }

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

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

Referenced by peer_set_srcaddr().

12284 {
12285    int sd;
12286    int res;
12287    
12288    sd = socket(AF_INET, SOCK_DGRAM, 0);
12289    if (sd < 0) {
12290       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12291       return -1;
12292    }
12293 
12294    res = bind(sd, sa, salen);
12295    if (res < 0) {
12296       ast_debug(1, "Can't bind: %s\n", strerror(errno));
12297       close(sd);
12298       return 1;
12299    }
12300 
12301    close(sd);
12302    return 0;
12303 }

static void cleanup_thread_list ( void *  head  )  [static]

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

14337 {
14338    AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14339    struct iax2_thread_list *list_head = head;
14340    struct iax2_thread *thread;
14341 
14342    AST_LIST_LOCK(list_head);
14343    while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
14344       pthread_t thread_id = thread->threadid;
14345 
14346       thread->stop = 1;
14347       signal_condition(&thread->lock, &thread->cond);
14348 
14349       AST_LIST_UNLOCK(list_head);
14350       pthread_join(thread_id, NULL);
14351       AST_LIST_LOCK(list_head);
14352    }
14353    AST_LIST_UNLOCK(list_head);
14354 }

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

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

08341 {
08342    char exten[256] = "";
08343    int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08344    struct iax2_dpcache *dp = NULL;
08345    
08346    if (ies->called_number)
08347       ast_copy_string(exten, ies->called_number, sizeof(exten));
08348    
08349    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08350       status = CACHE_FLAG_EXISTS;
08351    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08352       status = CACHE_FLAG_CANEXIST;
08353    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08354       status = CACHE_FLAG_NONEXISTENT;
08355 
08356    if (ies->refresh)
08357       expiry = ies->refresh;
08358    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08359       matchmore = CACHE_FLAG_MATCHMORE;
08360    
08361    AST_LIST_LOCK(&dpcache);
08362    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08363       if (strcmp(dp->exten, exten))
08364          continue;
08365       AST_LIST_REMOVE_CURRENT(peer_list);
08366       dp->callno = 0;
08367       dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08368       if (dp->flags & CACHE_FLAG_PENDING) {
08369          dp->flags &= ~CACHE_FLAG_PENDING;
08370          dp->flags |= status;
08371          dp->flags |= matchmore;
08372       }
08373       /* Wake up waiters */
08374       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08375          if (dp->waiters[x] > -1) {
08376             if (write(dp->waiters[x], "asdf", 4) < 0) {
08377             }
08378          }
08379       }
08380    }
08381    AST_LIST_TRAVERSE_SAFE_END;
08382    AST_LIST_UNLOCK(&dpcache);
08383 
08384    return 0;
08385 }

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

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

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

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

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

06904 {
06905    int which = 0;
06906    struct iax2_peer *p = NULL;
06907    char *res = NULL;
06908    int wordlen = strlen(word);
06909 
06910    /* 0 - iax2; 1 - unregister; 2 - <peername> */
06911    if (pos == 2) {
06912       struct ao2_iterator i = ao2_iterator_init(peers, 0);
06913       while ((p = ao2_iterator_next(&i))) {
06914          if (!strncasecmp(p->name, word, wordlen) && 
06915             ++which > state && p->expire > 0) {
06916             res = ast_strdup(p->name);
06917             peer_unref(p);
06918             break;
06919          }
06920          peer_unref(p);
06921       }
06922       ao2_iterator_destroy(&i);
06923    }
06924 
06925    return res;
06926 }

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

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

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

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

09441 {
09442    jb_info stats;
09443    jb_getinfo(pvt->jb, &stats);
09444    
09445    memset(iep, 0, sizeof(*iep));
09446 
09447    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09448    if(stats.frames_in == 0) stats.frames_in = 1;
09449    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09450    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09451    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09452    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09453    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09454 }

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

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

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

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

06258 {
06259    int padding;
06260    unsigned char *workspace;
06261 
06262    workspace = ast_alloca(*datalen);
06263    memset(f, 0, sizeof(*f));
06264    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06265       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06266       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06267          return -1;
06268       /* Decrypt */
06269       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06270 
06271       padding = 16 + (workspace[15] & 0x0f);
06272       if (iaxdebug)
06273          ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06274       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06275          return -1;
06276 
06277       *datalen -= padding;
06278       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06279       f->frametype = fh->type;
06280       if (f->frametype == AST_FRAME_VIDEO) {
06281          f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06282       } else if (f->frametype == AST_FRAME_VOICE) {
06283          f->subclass.codec = uncompress_subclass(fh->csub);
06284       } else {
06285          f->subclass.integer = uncompress_subclass(fh->csub);
06286       }
06287    } else {
06288       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06289       if (iaxdebug)
06290          ast_debug(1, "Decoding mini with length %d\n", *datalen);
06291       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06292          return -1;
06293       /* Decrypt */
06294       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06295       padding = 16 + (workspace[15] & 0x0f);
06296       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06297          return -1;
06298       *datalen -= padding;
06299       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06300    }
06301    return 0;
06302 }

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

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

06344 {
06345    int res=-1;
06346    if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06347       /* Search for possible keys, given secrets */
06348       struct MD5Context md5;
06349       unsigned char digest[16];
06350       char *tmppw, *stringp;
06351       
06352       tmppw = ast_strdupa(iaxs[callno]->secret);
06353       stringp = tmppw;
06354       while ((tmppw = strsep(&stringp, ";"))) {
06355          MD5Init(&md5);
06356          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06357          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06358          MD5Final(digest, &md5);
06359          build_encryption_keys(digest, iaxs[callno]);
06360          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06361          if (!res) {
06362             ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06363             break;
06364          }
06365       }
06366    } else 
06367       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06368    return res;
06369 }

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

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

Referenced by socket_read().

09588 {
09589    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09590    struct ast_iax2_full_hdr *fh, *cur_fh;
09591 
09592    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09593       return;
09594 
09595    pkt_buf->len = from_here->buf_len;
09596    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09597 
09598    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09599    ast_mutex_lock(&to_here->lock);
09600    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09601       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09602       if (fh->oseqno < cur_fh->oseqno) {
09603          AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09604          break;
09605       }
09606    }
09607    AST_LIST_TRAVERSE_SAFE_END
09608 
09609    if (!cur_pkt_buf)
09610       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09611    
09612    ast_mutex_unlock(&to_here->lock);
09613 }

static void delete_users ( void   )  [static]

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

12971 {
12972    struct iax2_registry *reg;
12973 
12974    ao2_callback(users, 0, user_delme_cb, NULL);
12975 
12976    AST_LIST_LOCK(&registrations);
12977    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
12978       if (sched) {
12979          ast_sched_thread_del(sched, reg->expire);
12980       }
12981       if (reg->callno) {
12982          int callno = reg->callno;
12983          ast_mutex_lock(&iaxsl[callno]);
12984          if (iaxs[callno]) {
12985             iaxs[callno]->reg = NULL;
12986             iax2_destroy(callno);
12987          }
12988          ast_mutex_unlock(&iaxsl[callno]);
12989       }
12990       if (reg->dnsmgr)
12991          ast_dnsmgr_release(reg->dnsmgr);
12992       ast_free(reg);
12993    }
12994    AST_LIST_UNLOCK(&registrations);
12995 
12996    ao2_callback(peers, 0, peer_delme_cb, NULL);
12997 }

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

09243 {
09244    unsigned short dpstatus = 0;
09245    struct iax_ie_data ied1;
09246    int mm;
09247 
09248    memset(&ied1, 0, sizeof(ied1));
09249    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09250    /* Must be started */
09251    if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09252       dpstatus = IAX_DPSTATUS_EXISTS;
09253    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09254       dpstatus = IAX_DPSTATUS_CANEXIST;
09255    } else {
09256       dpstatus = IAX_DPSTATUS_NONEXISTENT;
09257    }
09258    if (ast_ignore_pattern(context, callednum))
09259       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09260    if (mm)
09261       dpstatus |= IAX_DPSTATUS_MATCHMORE;
09262    if (!skiplock)
09263       ast_mutex_lock(&iaxsl[callno]);
09264    if (iaxs[callno]) {
09265       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09266       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09267       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09268       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09269    }
09270    if (!skiplock)
09271       ast_mutex_unlock(&iaxsl[callno]);
09272 }

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

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

09275 {
09276    /* Look up for dpreq */
09277    struct dpreq_data *dpr = data;
09278    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09279    if (dpr->callerid)
09280       ast_free(dpr->callerid);
09281    ast_free(dpr);
09282    return NULL;
09283 }

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

06305 {
06306    int padding;
06307    unsigned char *workspace;
06308    workspace = ast_alloca(*datalen + 32);
06309    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06310       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06311       if (iaxdebug)
06312          ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06313       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06314       padding = 16 + (padding & 0xf);
06315       memcpy(workspace, poo, padding);
06316       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06317       workspace[15] &= 0xf0;
06318       workspace[15] |= (padding & 0xf);
06319       if (iaxdebug)
06320          ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06321       *datalen += padding;
06322       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06323       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06324          memcpy(poo, workspace + *datalen - 32, 32);
06325    } else {
06326       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06327       if (iaxdebug)
06328          ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06329       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06330       padding = 16 + (padding & 0xf);
06331       memcpy(workspace, poo, padding);
06332       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06333       workspace[15] &= 0xf0;
06334       workspace[15] |= (padding & 0x0f);
06335       *datalen += padding;
06336       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06337       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06338          memcpy(poo, workspace + *datalen - 32, 32);
06339    }
06340    return 0;
06341 }

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

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

08656 {
08657 #ifdef SCHED_MULTITHREADED
08658    if (schedule_action(__expire_registry, data))
08659 #endif      
08660       __expire_registry(data);
08661    return 0;
08662 }

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

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

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

06077 {
06078    struct iax2_trunk_peer *tpeer = NULL;
06079    
06080    /* Finds and locks trunk peer */
06081    AST_LIST_LOCK(&tpeers);
06082 
06083    AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06084       if (!inaddrcmp(&tpeer->addr, sin)) {
06085          ast_mutex_lock(&tpeer->lock);
06086          break;
06087       }
06088    }
06089 
06090    if (!tpeer) {
06091       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06092          ast_mutex_init(&tpeer->lock);
06093          tpeer->lastsent = 9999;
06094          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06095          tpeer->trunkact = ast_tvnow();
06096          ast_mutex_lock(&tpeer->lock);
06097          tpeer->sockfd = fd;
06098 #ifdef SO_NO_CHECK
06099          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06100 #endif
06101          ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06102          AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06103       }
06104    }
06105 
06106    AST_LIST_UNLOCK(&tpeers);
06107 
06108    return tpeer;
06109 }

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

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

Referenced by socket_process_meta().

05890 {
05891    long ms; /* NOT unsigned */
05892    if (ast_tvzero(iaxs[callno]->rxcore)) {
05893       /* Initialize rxcore time if appropriate */
05894       iaxs[callno]->rxcore = ast_tvnow();
05895       /* Round to nearest 20ms so traces look pretty */
05896       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05897    }
05898    /* Calculate difference between trunk and channel */
05899    ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05900    /* Return as the sum of trunk time and the difference between trunk and real time */
05901    return ms + ts;
05902 }

static void free_context ( struct iax2_context con  )  [static]

Definition at line 12112 of file chan_iax2.c.

References ast_free, and iax2_context::next.

Referenced by build_user(), and user_destructor().

12113 {
12114    struct iax2_context *conl;
12115    while(con) {
12116       conl = con;
12117       con = con->next;
12118       ast_free(conl);
12119    }
12120 }

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

13924 {
13925    struct iax2_peer *peer;
13926    char *peername, *colname;
13927 
13928    peername = ast_strdupa(data);
13929 
13930    /* if our channel, return the IP address of the endpoint of current channel */
13931    if (!strcmp(peername,"CURRENTCHANNEL")) {
13932            unsigned short callno;
13933       if (chan->tech != &iax2_tech)
13934          return -1;
13935       callno = PTR_TO_CALLNO(chan->tech_pvt);   
13936       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13937       return 0;
13938    }
13939 
13940    if ((colname = strchr(peername, ',')))
13941       *colname++ = '\0';
13942    else
13943       colname = "ip";
13944 
13945    if (!(peer = find_peer(peername, 1)))
13946       return -1;
13947 
13948    if (!strcasecmp(colname, "ip")) {
13949       ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
13950    } else  if (!strcasecmp(colname, "status")) {
13951       peer_status(peer, buf, len); 
13952    } else  if (!strcasecmp(colname, "mailbox")) {
13953       ast_copy_string(buf, peer->mailbox, len);
13954    } else  if (!strcasecmp(colname, "context")) {
13955       ast_copy_string(buf, peer->context, len);
13956    } else  if (!strcasecmp(colname, "expire")) {
13957       snprintf(buf, len, "%d", peer->expire);
13958    } else  if (!strcasecmp(colname, "dynamic")) {
13959       ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13960    } else  if (!strcasecmp(colname, "callerid_name")) {
13961       ast_copy_string(buf, peer->cid_name, len);
13962    } else  if (!strcasecmp(colname, "callerid_num")) {
13963       ast_copy_string(buf, peer->cid_num, len);
13964    } else  if (!strcasecmp(colname, "codecs")) {
13965       ast_getformatname_multiple(buf, len -1, peer->capability);
13966    } else  if (!strncasecmp(colname, "codec[", 6)) {
13967       char *codecnum, *ptr;
13968       int codec = 0;
13969 
13970       /* skip over "codec" to the '[' */
13971       codecnum = colname + 5;
13972       *codecnum = '\0';
13973       codecnum++;
13974       if ((ptr = strchr(codecnum, ']'))) {
13975          *ptr = '\0';
13976       }
13977       if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13978          ast_copy_string(buf, ast_getformatname(codec), len);
13979       } else {
13980          buf[0] = '\0';
13981       }
13982    } else {
13983       buf[0] = '\0';
13984    }
13985 
13986    peer_unref(peer);
13987 
13988    return 0;
13989 }

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

Definition at line 12267 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

12268 {
12269    int methods = 0;
12270    if (strstr(value, "rsa"))
12271       methods |= IAX_AUTH_RSA;
12272    if (strstr(value, "md5"))
12273       methods |= IAX_AUTH_MD5;
12274    if (strstr(value, "plaintext"))
12275       methods |= IAX_AUTH_PLAINTEXT;
12276    return methods;
12277 }

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

References __get_from_jb(), and schedule_action.

Referenced by update_jbsched().

04139 {
04140 #ifdef SCHED_MULTITHREADED
04141    if (schedule_action(__get_from_jb, data))
04142 #endif      
04143       __get_from_jb(data);
04144    return 0;
04145 }

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

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

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

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

11960 {
11961    int force = 0;
11962    int res;
11963 
11964    switch (cmd) {
11965    case CLI_INIT:
11966       e->command = "iax2 provision";
11967       e->usage = 
11968          "Usage: iax2 provision <host> <template> [forced]\n"
11969          "       Provisions the given peer or IP address using a template\n"
11970          "       matching either 'template' or '*' if the template is not\n"
11971          "       found.  If 'forced' is specified, even empty provisioning\n"
11972          "       fields will be provisioned as empty fields.\n";
11973       return NULL;
11974    case CLI_GENERATE:
11975       if (a->pos == 3)
11976          return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11977       return NULL;
11978    }
11979 
11980    if (a->argc < 4)
11981       return CLI_SHOWUSAGE;
11982    if (a->argc > 4) {
11983       if (!strcasecmp(a->argv[4], "forced"))
11984          force = 1;
11985       else
11986          return CLI_SHOWUSAGE;
11987    }
11988    res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11989    if (res < 0)
11990       ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11991    else if (res < 1)
11992       ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11993    else
11994       ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11995    return CLI_SUCCESS;
11996 }

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

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

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

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

Definition at line 13574 of file chan_iax2.c.

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

13575 {
13576    switch (cmd) {
13577    case CLI_INIT:
13578       e->command = "iax2 reload";
13579       e->usage =
13580          "Usage: iax2 reload\n"
13581          "       Reloads IAX configuration from iax.conf\n";
13582       return NULL;
13583    case CLI_GENERATE:
13584       return NULL;
13585    }
13586 
13587    reload_config();
13588 
13589    return CLI_SUCCESS;
13590 }

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

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

07348 {
07349    switch (cmd) {
07350    case CLI_INIT:
07351       e->command = "iax2 set debug {on|off|peer}";
07352       e->usage =
07353          "Usage: iax2 set debug {on|off|peer peername}\n"
07354          "       Enables/Disables dumping of IAX packets for debugging purposes.\n";
07355       return NULL;
07356    case CLI_GENERATE:
07357       if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07358          return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07359       return NULL;
07360    }
07361 
07362    if (a->argc < e->args  || a->argc > e->args + 1)
07363       return CLI_SHOWUSAGE;
07364 
07365    if (!strcasecmp(a->argv[3], "peer")) {
07366       struct iax2_peer *peer;
07367       struct sockaddr_in peer_addr;
07368 
07369 
07370       if (a->argc != e->args + 1)
07371          return CLI_SHOWUSAGE;
07372 
07373       peer = find_peer(a->argv[4], 1);
07374 
07375       if (!peer) {
07376          ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07377          return CLI_FAILURE;
07378       }
07379 
07380       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07381 
07382       debugaddr.sin_addr = peer_addr.sin_addr;
07383       debugaddr.sin_port = peer_addr.sin_port;
07384 
07385       ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07386          ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07387 
07388       ao2_ref(peer, -1);
07389    } else if (!strncasecmp(a->argv[3], "on", 2)) {
07390       iaxdebug = 1;
07391       ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07392    } else {
07393       iaxdebug = 0;
07394       memset(&debugaddr, 0, sizeof(debugaddr));
07395       ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07396    }
07397    return CLI_SUCCESS;
07398 }

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

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

07427 {
07428    switch (cmd) {
07429    case CLI_INIT:
07430       e->command = "iax2 set debug jb {on|off}";
07431       e->usage =
07432          "Usage: iax2 set debug jb {on|off}\n"
07433          "       Enables/Disables jitterbuffer debugging information\n";
07434       return NULL;
07435    case CLI_GENERATE:
07436       return NULL;
07437    }
07438 
07439    if (a->argc != e->args)
07440       return CLI_SHOWUSAGE;
07441    
07442    if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07443       jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07444       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07445    } else {
07446       jb_setoutput(jb_error_output, jb_warning_output, NULL);
07447       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07448    }
07449    return CLI_SUCCESS;
07450 }

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

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

07401 {
07402    switch (cmd) {
07403    case CLI_INIT:
07404       e->command = "iax2 set debug trunk {on|off}";
07405       e->usage =
07406          "Usage: iax2 set debug trunk {on|off}\n"
07407          "       Enables/Disables debugging of IAX trunking\n";
07408       return NULL;
07409    case CLI_GENERATE:
07410       return NULL;
07411    }
07412 
07413    if (a->argc != e->args)
07414       return CLI_SHOWUSAGE;
07415 
07416    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07417       iaxtrunkdebug = 1;
07418       ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07419    } else {
07420       iaxtrunkdebug = 0;
07421       ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07422    }
07423    return CLI_SUCCESS;
07424 }

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

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

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

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

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

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

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

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

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

06961 {
06962    struct iax_firmware *cur = NULL;
06963 
06964    switch (cmd) {
06965    case CLI_INIT:
06966       e->command = "iax2 show firmware";
06967       e->usage =
06968          "Usage: iax2 show firmware\n"
06969          "       Lists all known IAX firmware images.\n";
06970       return NULL;
06971    case CLI_GENERATE:
06972       return NULL;
06973    }
06974 
06975    if (a->argc != 3 && a->argc != 4)
06976       return CLI_SHOWUSAGE;
06977 
06978    ast_cli(a->fd, "%-15.15s  %-15.15s %-15.15s\n", "Device", "Version", "Size");
06979    AST_LIST_LOCK(&firmwares);
06980    AST_LIST_TRAVERSE(&firmwares, cur, list) {
06981       if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname)))  {
06982          ast_cli(a->fd, "%-15.15s  %-15d %-15d\n", cur->fwh->devname, 
06983             ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06984       }
06985    }
06986    AST_LIST_UNLOCK(&firmwares);
06987 
06988    return CLI_SUCCESS;
06989 }

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

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

07325 {
07326    int numchans = 0;
07327 
07328    switch (cmd) {
07329    case CLI_INIT:
07330       e->command = "iax2 show netstats";
07331       e->usage =
07332          "Usage: iax2 show netstats\n"
07333          "       Lists network status for all currently active IAX channels.\n";
07334       return NULL;
07335    case CLI_GENERATE:
07336       return NULL;
07337    }
07338    if (a->argc != 3)
07339       return CLI_SHOWUSAGE;
07340    ast_cli(a->fd, "                           -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
07341    ast_cli(a->fd, "Channel               RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts FirstMsg    LastMsg\n");
07342    numchans = ast_cli_netstats(NULL, a->fd, 1);
07343    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07344    return CLI_SUCCESS;
07345 }

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

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

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

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

06929 {
06930    switch (cmd) {
06931    case CLI_INIT:
06932       e->command = "iax2 show peers";
06933       e->usage =
06934          "Usage: iax2 show peers [registered] [like <pattern>]\n"
06935          "       Lists all known IAX2 peers.\n"
06936          "       Optional 'registered' argument lists only peers with known addresses.\n"
06937          "       Optional regular expression pattern is used to filter the peer list.\n";
06938       return NULL;
06939    case CLI_GENERATE:
06940       return NULL;
06941    }
06942 
06943    switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
06944    case RESULT_SHOWUSAGE:
06945       return CLI_SHOWUSAGE;
06946    case RESULT_FAILURE:
06947       return CLI_FAILURE;
06948    default:
06949       return CLI_SUCCESS;
06950    }
06951 }

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

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

07084 {
07085 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
07086 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
07087    struct iax2_registry *reg = NULL;
07088    char host[80];
07089    char perceived[80];
07090    int counter = 0;
07091 
07092    switch (cmd) {
07093    case CLI_INIT:
07094       e->command = "iax2 show registry";
07095       e->usage =
07096          "Usage: iax2 show registry\n"
07097          "       Lists all registration requests and status.\n";
07098       return NULL;
07099    case CLI_GENERATE:
07100       return NULL;
07101    }
07102    if (a->argc != 3)
07103       return CLI_SHOWUSAGE;
07104    ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07105    AST_LIST_LOCK(&registrations);
07106    AST_LIST_TRAVERSE(&registrations, reg, entry) {
07107       snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
07108       if (reg->us.sin_addr.s_addr) 
07109          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07110       else
07111          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07112       ast_cli(a->fd, FORMAT, host, 
07113                (reg->dnsmgr) ? "Y" : "N", 
07114                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07115       counter++;
07116    }
07117    AST_LIST_UNLOCK(&registrations);
07118    ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07119    return CLI_SUCCESS;
07120 #undef FORMAT
07121 #undef FORMAT2
07122 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

06860 {
06861    struct iax2_peer *p;
06862 
06863    switch (cmd) {
06864    case CLI_INIT:
06865       e->command = "iax2 unregister";
06866       e->usage =
06867          "Usage: iax2 unregister <peername>\n"
06868          "       Unregister (force expiration) an IAX2 peer from the registry.\n";
06869       return NULL;
06870    case CLI_GENERATE:
06871       return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06872    }
06873 
06874    if (a->argc != 3)
06875       return CLI_SHOWUSAGE;
06876 
06877    p = find_peer(a->argv[2], 1);
06878    if (p) {
06879       if (p->expire > 0) {
06880          struct iax2_peer tmp_peer = {
06881             .name = a->argv[2],
06882          };
06883          struct iax2_peer *peer;
06884 
06885          peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06886          if (peer) {
06887             expire_registry(peer_ref(peer)); /* will release its own reference when done */
06888             peer_unref(peer); /* ref from ao2_find() */
06889             ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06890          } else {
06891             ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06892          }
06893       } else {
06894          ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06895       }
06896       peer_unref(p);
06897    } else {
06898       ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06899    }
06900    return CLI_SUCCESS;
06901 }

static void handle_deferred_full_frames ( struct iax2_thread thread  )  [static]

Handle any deferred full frames for this thread.

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

09558 {
09559    struct iax2_pkt_buf *pkt_buf;
09560 
09561    ast_mutex_lock(&thread->lock);
09562 
09563    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09564       ast_mutex_unlock(&thread->lock);
09565 
09566       thread->buf = pkt_buf->buf;
09567       thread->buf_len = pkt_buf->len;
09568       thread->buf_size = pkt_buf->len + 1;
09569       
09570       socket_process(thread);
09571 
09572       thread->buf = NULL;
09573       ast_free(pkt_buf);
09574 
09575       ast_mutex_lock(&thread->lock);
09576    }
09577 
09578    ast_mutex_unlock(&thread->lock);
09579 }

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

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

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

05632 {
05633    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05634    ast_debug(1, "Answering IAX2 call\n");
05635    ast_mutex_lock(&iaxsl[callno]);
05636    if (iaxs[callno])
05637       iax2_ami_channelupdate(iaxs[callno]);
05638    ast_mutex_unlock(&iaxsl[callno]);
05639    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05640 }

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

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

08517 {
08518    struct iax2_registry *reg;
08519 
08520    if (!(reg = ast_calloc(1, sizeof(*reg))))
08521       return -1;
08522 
08523    reg->addr.ss.ss_family = AF_INET;
08524    if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08525       ast_free(reg);
08526       return -1;
08527    }
08528 
08529    ast_copy_string(reg->username, username, sizeof(reg->username));
08530 
08531    if (secret)
08532       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08533 
08534    reg->expire = -1;
08535    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08536    ast_sockaddr_set_port(&reg->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08537 
08538    AST_LIST_LOCK(&registrations);
08539    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
08540    AST_LIST_UNLOCK(&registrations);
08541    
08542    return 0;
08543 }

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

References ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_check_hangup(), AST_CONTROL_SRCUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_read(), AST_SOFTHANGUP_DEV, ast_test_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().

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

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

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

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

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

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

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

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

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

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

14033 {
14034    struct parsed_dial_string pds;
14035    char *tmp = ast_strdupa(data);
14036    struct iax2_peer *p;
14037    int res = AST_DEVICE_INVALID;
14038 
14039    memset(&pds, 0, sizeof(pds));
14040    parse_dial_string(tmp, &pds);
14041 
14042    if (ast_strlen_zero(pds.peer)) {
14043       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
14044       return res;
14045    }
14046    
14047    ast_debug(3, "Checking device state for device %s\n", pds.peer);
14048 
14049    /* SLD: FIXME: second call to find_peer during registration */
14050    if (!(p = find_peer(pds.peer, 1)))
14051       return res;
14052 
14053    res = AST_DEVICE_UNAVAILABLE;
14054    ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
14055       pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
14056    
14057    if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
14058        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
14059       /* Peer is registered, or have default IP address
14060          and a valid registration */
14061       if (p->historicms == 0 || p->historicms <= p->maxms)
14062          /* let the core figure out whether it is in use or not */
14063          res = AST_DEVICE_UNKNOWN;  
14064    }
14065 
14066    peer_unref(p);
14067 
14068    return res;
14069 }

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

Definition at line 4291 of file chan_iax2.c.

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

04292 {
04293    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04294 }

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

Definition at line 4296 of file chan_iax2.c.

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

04297 {
04298    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04299 }

static int iax2_do_register ( struct iax2_registry reg  )  [static]

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

11818 {
11819    struct iax_ie_data ied;
11820    if (iaxdebug)
11821       ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11822 
11823    if (reg->dnsmgr && 
11824        ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(&reg->addr))) {
11825       /* Maybe the IP has changed, force DNS refresh */
11826       ast_dnsmgr_refresh(reg->dnsmgr);
11827    }
11828    
11829    /*
11830     * if IP has Changed, free allocated call to create a new one with new IP
11831     * call has the pointer to IP and must be updated to the new one
11832     */
11833    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11834       int callno = reg->callno;
11835       ast_mutex_lock(&iaxsl[callno]);
11836       iax2_destroy(callno);
11837       ast_mutex_unlock(&iaxsl[callno]);
11838       reg->callno = 0;
11839    }
11840    if (!ast_sockaddr_ipv4(&reg->addr)) {
11841       if (iaxdebug)
11842          ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11843       /* Setup the next registration attempt */
11844       reg->expire = iax2_sched_replace(reg->expire, sched, 
11845          (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11846       return -1;
11847    }
11848 
11849    if (!reg->callno) {
11850       struct sockaddr_in reg_addr;
11851 
11852       ast_debug(3, "Allocate call number\n");
11853 
11854       ast_sockaddr_to_sin(&reg->addr, &reg_addr);
11855 
11856       reg->callno = find_callno_locked(0, 0, &reg_addr, NEW_FORCE, defaultsockfd, 0);
11857       if (reg->callno < 1) {
11858          ast_log(LOG_WARNING, "Unable to create call for registration\n");
11859          return -1;
11860       } else
11861          ast_debug(3, "Registration created on call %d\n", reg->callno);
11862       iaxs[reg->callno]->reg = reg;
11863       ast_mutex_unlock(&iaxsl[reg->callno]);
11864    }
11865    /* Setup the next registration a little early */
11866    reg->expire = iax2_sched_replace(reg->expire, sched, 
11867       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11868    /* Send the request */
11869    memset(&ied, 0, sizeof(ied));
11870    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11871    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11872    add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */
11873    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11874    reg->regstate = REG_STATE_REGSENT;
11875    return 0;
11876 }

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

Definition at line 8297 of file chan_iax2.c.

References __iax2_do_register_s(), and schedule_action.

Referenced by iax2_ack_registry(), and iax2_do_register().

08298 {
08299 #ifdef SCHED_MULTITHREADED
08300    if (schedule_action(__iax2_do_register_s, data))
08301 #endif      
08302       __iax2_do_register_s(data);
08303    return 0;
08304 }

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

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

09073 {
09074    struct iax_ie_data ied;
09075    /* Auto-hangup with 30 seconds of inactivity */
09076    iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
09077       sched, 30000, auto_hangup, (void *)(long)callno);
09078    memset(&ied, 0, sizeof(ied));
09079    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09080    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09081    dp->flags |= CACHE_FLAG_TRANSMITTED;
09082 }

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

13873 {
13874    char odata[256];
13875    char req[256];
13876    char *ncontext;
13877    struct iax2_dpcache *dp = NULL;
13878    struct ast_app *dial = NULL;
13879 #if 0
13880    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);
13881 #endif
13882    if (priority == 2) {
13883       /* Indicate status, can be overridden in dialplan */
13884       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13885       if (dialstatus) {
13886          dial = pbx_findapp(dialstatus);
13887          if (dial) 
13888             pbx_exec(chan, dial, "");
13889       }
13890       return -1;
13891    } else if (priority != 1)
13892       return -1;
13893 
13894    AST_LIST_LOCK(&dpcache);
13895    if ((dp = find_cache(chan, data, context, exten, priority))) {
13896       if (dp->flags & CACHE_FLAG_EXISTS) {
13897          ast_copy_string(odata, data, sizeof(odata));
13898          ncontext = strchr(odata, '/');
13899          if (ncontext) {
13900             *ncontext = '\0';
13901             ncontext++;
13902             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13903          } else {
13904             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13905          }
13906          ast_verb(3, "Executing Dial('%s')\n", req);
13907       } else {
13908          AST_LIST_UNLOCK(&dpcache);
13909          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13910          return -1;
13911       }
13912    }
13913    AST_LIST_UNLOCK(&dpcache);
13914 
13915    if ((dial = pbx_findapp("Dial")))
13916       return pbx_exec(chan, dial, req);
13917    else
13918       ast_log(LOG_WARNING, "No dial application registered\n");
13919 
13920    return -1;
13921 }

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

13804 {
13805    int res = 0;
13806    struct iax2_dpcache *dp = NULL;
13807 #if 0
13808    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13809 #endif
13810    if ((priority != 1) && (priority != 2))
13811       return 0;
13812 
13813    AST_LIST_LOCK(&dpcache);
13814    if ((dp = find_cache(chan, data, context, exten, priority))) {
13815       if (dp->flags & CACHE_FLAG_EXISTS)
13816          res = 1;
13817    } else {
13818       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13819    }
13820    AST_LIST_UNLOCK(&dpcache);
13821 
13822    return res;
13823 }

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

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

04319 {
04320    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04321    ast_mutex_lock(&iaxsl[callno]);
04322    if (iaxs[callno])
04323       iaxs[callno]->owner = newchan;
04324    else
04325       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04326    ast_mutex_unlock(&iaxsl[callno]);
04327    return 0;
04328 }

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

05707 {
05708    struct iax2_peer *peer;
05709    int res = 0;
05710    struct ao2_iterator i;
05711 
05712    i = ao2_iterator_init(peers, 0);
05713    while ((peer = ao2_iterator_next(&i))) {
05714       struct sockaddr_in peer_addr;
05715 
05716       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05717 
05718       if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05719           (peer_addr.sin_port == sin.sin_port)) {
05720          res = ast_test_flag64(peer, IAX_TRUNK);
05721          peer_unref(peer);
05722          break;
05723       }
05724       peer_unref(peer);
05725    }
05726    ao2_iterator_destroy(&i);
05727 
05728    return res;
05729 }

static int iax2_hangup ( struct ast_channel c  )  [static]

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

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

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

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

05643 {
05644    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05645    struct chan_iax2_pvt *pvt;
05646    int res = 0;
05647 
05648    if (iaxdebug)
05649       ast_debug(1, "Indicating condition %d\n", condition);
05650 
05651    ast_mutex_lock(&iaxsl[callno]);
05652    pvt = iaxs[callno];
05653 
05654    if (wait_for_peercallno(pvt)) {
05655       res = -1;
05656       goto done;
05657    }
05658 
05659    switch (condition) {
05660    case AST_CONTROL_HOLD:
05661       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05662          ast_moh_start(c, data, pvt->mohinterpret);
05663          goto done;
05664       }
05665       break;
05666    case AST_CONTROL_UNHOLD:
05667       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05668          ast_moh_stop(c);
05669          goto done;
05670       }
05671       break;
05672    case AST_CONTROL_CONNECTED_LINE:
05673       if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
05674          goto done;
05675       break;
05676    }
05677 
05678    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05679 
05680 done:
05681    ast_mutex_unlock(&iaxsl[callno]);
05682 
05683    return res;
05684 }

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

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

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

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

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

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

Definition at line 12021 of file chan_iax2.c.

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

Referenced by iax2_poke_peer().

12022 {
12023    struct iax2_peer *peer = (struct iax2_peer *)data;
12024    peer->pokeexpire = -1;
12025 #ifdef SCHED_MULTITHREADED
12026    if (schedule_action(__iax2_poke_noanswer, data))
12027 #endif      
12028       __iax2_poke_noanswer(data);
12029    peer_unref(peer);
12030    return 0;
12031 }

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

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

12043 {
12044    int callno;
12045    struct sockaddr_in peer_addr;
12046 
12047    if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
12048       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
12049         immediately after clearing things out */
12050       peer->lastms = 0;
12051       peer->historicms = 0;
12052       peer->pokeexpire = -1;
12053       peer->callno = 0;
12054       return 0;
12055    }
12056 
12057    ast_sockaddr_to_sin(&peer->addr, &peer_addr);
12058 
12059    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
12060    if ((callno = peer->callno) > 0) {
12061       ast_log(LOG_NOTICE, "Still have a callno...\n");
12062       ast_mutex_lock(&iaxsl[callno]);
12063       iax2_destroy(callno);
12064       ast_mutex_unlock(&iaxsl[callno]);
12065    }
12066    if (heldcall)
12067       ast_mutex_unlock(&iaxsl[heldcall]);
12068    callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
12069    if (heldcall)
12070       ast_mutex_lock(&iaxsl[heldcall]);
12071    if (peer->callno < 1) {
12072       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12073       return -1;
12074    }
12075 
12076    /* Speed up retransmission times for this qualify call */
12077    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
12078    iaxs[peer->callno]->peerpoke = peer;
12079 
12080    if (peer->pokeexpire > -1) {
12081       if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
12082          peer->pokeexpire = -1;
12083          peer_unref(peer);
12084       }
12085    }
12086  
12087    /* Queue up a new task to handle no reply */
12088    /* If the host is already unreachable then use the unreachable interval instead */
12089    if (peer->lastms < 0)
12090       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
12091    else
12092       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
12093 
12094    if (peer->pokeexpire == -1)
12095       peer_unref(peer);
12096 
12097    /* And send the poke */
12098    ast_mutex_lock(&iaxsl[callno]);
12099    if (iaxs[callno]) {
12100       struct iax_ie_data ied = {
12101          .buf = { 0 },
12102          .pos = 0,
12103       };
12104       add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
12105       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12106    }
12107    ast_mutex_unlock(&iaxsl[callno]);
12108 
12109    return 0;
12110 }

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

Definition at line 12033 of file chan_iax2.c.

References iax2_poke_peer().

Referenced by load_module().

12034 {
12035    struct iax2_peer *peer = obj;
12036 
12037    iax2_poke_peer(peer, 0);
12038 
12039    return 0;
12040 }

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

Definition at line 9109 of file chan_iax2.c.

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

Referenced by __iax2_poke_noanswer(), and socket_process().

09110 {
09111    struct iax2_peer *peer = (struct iax2_peer *)data;
09112    peer->pokeexpire = -1;
09113 #ifdef SCHED_MULTITHREADED
09114    if (schedule_action(__iax2_poke_peer_s, data))
09115 #endif      
09116       __iax2_poke_peer_s(data);
09117    return 0;
09118 }

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

11673 {
11674    struct iax2_thread *thread = data;
11675    struct timeval wait;
11676    struct timespec ts;
11677    int put_into_idle = 0;
11678    int first_time = 1;
11679    int old_state;
11680 
11681    ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11682 
11683    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11684    pthread_cleanup_push(iax2_process_thread_cleanup, data);
11685 
11686    for (;;) {
11687       /* Wait for something to signal us to be awake */
11688       ast_mutex_lock(&thread->lock);
11689 
11690       if (thread->stop) {
11691          ast_mutex_unlock(&thread->lock);
11692          break;
11693       }
11694 
11695       /* Flag that we're ready to accept signals */
11696       if (first_time) {
11697          signal_condition(&thread->init_lock, &thread->init_cond);
11698          first_time = 0;
11699       }
11700 
11701       /* Put into idle list if applicable */
11702       if (put_into_idle) {
11703          insert_idle_thread(thread);
11704       }
11705 
11706       if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11707          struct iax2_thread *t = NULL;
11708          /* Wait to be signalled or time out */
11709          wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11710          ts.tv_sec = wait.tv_sec;
11711          ts.tv_nsec = wait.tv_usec * 1000;
11712          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11713             /* This thread was never put back into the available dynamic
11714              * thread list, so just go away. */
11715             if (!put_into_idle || thread->stop) {
11716                ast_mutex_unlock(&thread->lock);
11717                break;
11718             }
11719             AST_LIST_LOCK(&dynamic_list);
11720             /* Account for the case where this thread is acquired *right* after a timeout */
11721             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11722                ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11723             AST_LIST_UNLOCK(&dynamic_list);
11724             if (t) {
11725                /* This dynamic thread timed out waiting for a task and was
11726                 * not acquired immediately after the timeout, 
11727                 * so it's time to go away. */
11728                ast_mutex_unlock(&thread->lock);
11729                break;
11730             }
11731             /* Someone grabbed our thread *right* after we timed out.
11732              * Wait for them to set us up with something to do and signal
11733              * us to continue. */
11734             wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11735             ts.tv_sec = wait.tv_sec;
11736             ts.tv_nsec = wait.tv_usec * 1000;
11737             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11738                ast_mutex_unlock(&thread->lock);
11739                break;
11740             }
11741          }
11742       } else {
11743          ast_cond_wait(&thread->cond, &thread->lock);
11744       }
11745 
11746       /* Go back into our respective list */
11747       put_into_idle = 1;
11748 
11749       ast_mutex_unlock(&thread->lock);
11750 
11751       if (thread->stop) {
11752          break;
11753       }
11754 
11755       if (thread->iostate == IAX_IOSTATE_IDLE)
11756          continue;
11757 
11758       /* See what we need to do */
11759       switch (thread->iostate) {
11760       case IAX_IOSTATE_READY:
11761          thread->actions++;
11762          thread->iostate = IAX_IOSTATE_PROCESSING;
11763          socket_process(thread);
11764          handle_deferred_full_frames(thread);
11765          break;
11766       case IAX_IOSTATE_SCHEDREADY:
11767          thread->actions++;
11768          thread->iostate = IAX_IOSTATE_PROCESSING;
11769 #ifdef SCHED_MULTITHREADED
11770          thread->schedfunc(thread->scheddata);
11771 #endif      
11772       default:
11773          break;
11774       }
11775       time(&thread->checktime);
11776       thread->iostate = IAX_IOSTATE_IDLE;
11777 #ifdef DEBUG_SCHED_MULTITHREAD
11778       thread->curfunc[0]='\0';
11779 #endif      
11780 
11781       /* The network thread added us to the active_thread list when we were given
11782        * frames to process, Now that we are done, we must remove ourselves from
11783        * the active list, and return to the idle list */
11784       AST_LIST_LOCK(&active_list);
11785       AST_LIST_REMOVE(&active_list, thread, list);
11786       AST_LIST_UNLOCK(&active_list);
11787 
11788       /* Make sure another frame didn't sneak in there after we thought we were done. */
11789       handle_deferred_full_frames(thread);
11790    }
11791 
11792    /*!
11793     * \note For some reason, idle threads are exiting without being removed
11794     * from an idle list, which is causing memory corruption.  Forcibly remove
11795     * it from the list, if it's there.
11796     */
11797    AST_LIST_LOCK(&idle_list);
11798    AST_LIST_REMOVE(&idle_list, thread, list);
11799    AST_LIST_UNLOCK(&idle_list);
11800 
11801    AST_LIST_LOCK(&dynamic_list);
11802    AST_LIST_REMOVE(&dynamic_list, thread, list);
11803    AST_LIST_UNLOCK(&dynamic_list);
11804 
11805    if (!thread->stop) {
11806       /* Nobody asked me to stop so nobody is waiting to join me. */
11807       pthread_detach(pthread_self());
11808    }
11809 
11810    /* I am exiting here on my own volition, I need to clean up my own data structures
11811    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
11812    */
11813    pthread_cleanup_pop(1);
11814    return NULL;
11815 }

static void iax2_process_thread_cleanup ( void *  data  )  [static]

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

11661 {
11662    struct iax2_thread *thread = data;
11663    ast_mutex_destroy(&thread->lock);
11664    ast_cond_destroy(&thread->cond);
11665    ast_mutex_destroy(&thread->init_lock);
11666    ast_cond_destroy(&thread->init_cond);
11667    ast_free(thread);
11668    /* Ignore check_return warning from Coverity for ast_atomic_dec_and_test below */
11669    ast_atomic_dec_and_test(&iaxactivethreadcount);
11670 }

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

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

11879 {
11880    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
11881       is found for template */
11882    struct iax_ie_data provdata;
11883    struct iax_ie_data ied;
11884    unsigned int sig;
11885    struct sockaddr_in sin;
11886    int callno;
11887    struct create_addr_info cai;
11888 
11889    memset(&cai, 0, sizeof(cai));
11890 
11891    ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11892 
11893    if (iax_provision_build(&provdata, &sig, template, force)) {
11894       ast_debug(1, "No provisioning found for template '%s'\n", template);
11895       return 0;
11896    }
11897 
11898    if (end) {
11899       memcpy(&sin, end, sizeof(sin));
11900       cai.sockfd = sockfd;
11901    } else if (create_addr(dest, NULL, &sin, &cai))
11902       return -1;
11903 
11904    /* Build the rest of the message */
11905    memset(&ied, 0, sizeof(ied));
11906    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11907 
11908    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11909    if (!callno)
11910       return -1;
11911 
11912    if (iaxs[callno]) {
11913       /* Schedule autodestruct in case they don't ever give us anything back */
11914       iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
11915          sched, 15000, auto_hangup, (void *)(long)callno);
11916       ast_set_flag64(iaxs[callno], IAX_PROVISION);
11917       /* Got a call number now, so go ahead and send the provisioning information */
11918       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11919    }
11920    ast_mutex_unlock(&iaxsl[callno]);
11921 
11922    return 1;
11923 }

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

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

05367 {
05368    switch (option) {
05369    case AST_OPTION_SECURE_SIGNALING:
05370    case AST_OPTION_SECURE_MEDIA:
05371    {
05372       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05373       ast_mutex_lock(&iaxsl[callno]);
05374       *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05375       ast_mutex_unlock(&iaxsl[callno]);
05376       return 0;
05377    }
05378    default:
05379       return -1;
05380    }
05381 }

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

References ast_debug, and ast_null_frame.

05384 {
05385    ast_debug(1, "I should never be called!\n");
05386    return &ast_null_frame;
05387 }

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

Definition at line 8545 of file chan_iax2.c.

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

Referenced by set_config().

08546 {
08547    char copy[256];
08548    char *username, *hostname, *secret;
08549    char *porta;
08550    char *stringp=NULL;
08551    
08552    if (!value)
08553       return -1;
08554 
08555    ast_copy_string(copy, value, sizeof(copy));
08556    stringp = copy;
08557    username = strsep(&stringp, "@");
08558    hostname = strsep(&stringp, "@");
08559 
08560    if (!hostname) {
08561       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08562       return -1;
08563    }
08564 
08565    stringp = username;
08566    username = strsep(&stringp, ":");
08567    secret = strsep(&stringp, ":");
08568    stringp = hostname;
08569    hostname = strsep(&stringp, ":");
08570    porta = strsep(&stringp, ":");
08571    
08572    if (porta && !atoi(porta)) {
08573       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08574       return -1;
08575    }
08576 
08577    return iax2_append_register(hostname, username, secret, porta);
08578 }

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

12123 {
12124    int callno;
12125    int res;
12126    format_t fmt, native;
12127    struct sockaddr_in sin;
12128    struct ast_channel *c;
12129    struct parsed_dial_string pds;
12130    struct create_addr_info cai;
12131    char *tmpstr;
12132 
12133    memset(&pds, 0, sizeof(pds));
12134    tmpstr = ast_strdupa(data);
12135    parse_dial_string(tmpstr, &pds);
12136 
12137    if (ast_strlen_zero(pds.peer)) {
12138       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12139       return NULL;
12140    }
12141           
12142    memset(&cai, 0, sizeof(cai));
12143    cai.capability = iax2_capability;
12144 
12145    ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12146    
12147    /* Populate our address from the given */
12148    if (create_addr(pds.peer, NULL, &sin, &cai)) {
12149       *cause = AST_CAUSE_UNREGISTERED;
12150       return NULL;
12151    }
12152 
12153    if (pds.port)
12154       sin.sin_port = htons(atoi(pds.port));
12155 
12156    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12157    if (callno < 1) {
12158       ast_log(LOG_WARNING, "Unable to create call\n");
12159       *cause = AST_CAUSE_CONGESTION;
12160       return NULL;
12161    }
12162 
12163    /* If this is a trunk, update it now */
12164    ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12165    if (ast_test_flag64(&cai, IAX_TRUNK)) {
12166       int new_callno;
12167       if ((new_callno = make_trunk(callno, 1)) != -1)
12168          callno = new_callno;
12169    }
12170    iaxs[callno]->maxtime = cai.maxtime;
12171    if (cai.found)
12172       ast_string_field_set(iaxs[callno], host, pds.peer);
12173 
12174    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL, cai.found);
12175 
12176    ast_mutex_unlock(&iaxsl[callno]);
12177 
12178    if (c) {
12179       /* Choose a format we can live with */
12180       if (c->nativeformats & format) 
12181          c->nativeformats &= format;
12182       else {
12183          native = c->nativeformats;
12184          fmt = format;
12185          res = ast_translator_best_choice(&fmt, &native);
12186          if (res < 0) {
12187             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12188                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
12189             ast_hangup(c);
12190             return NULL;
12191          }
12192          c->nativeformats = native;
12193       }
12194       c->readformat = ast_best_codec(c->nativeformats);
12195       c->writeformat = c->readformat;
12196    }
12197 
12198    return c;
12199 }

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

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

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

Definition at line 4313 of file chan_iax2.c.

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

04314 {
04315    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04316 }

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

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

04302 {
04303    
04304    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04305       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04306 }

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

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

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

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

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

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

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

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

05687 {
05688    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05689    struct iax_ie_data ied = { "", };
05690    char tmp[256], *context;
05691    enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05692    ast_copy_string(tmp, dest, sizeof(tmp));
05693    context = strchr(tmp, '@');
05694    if (context) {
05695       *context = '\0';
05696       context++;
05697    }
05698    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05699    if (context)
05700       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05701    ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05702    ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05703    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05704 }

static int iax2_transmit ( struct iax_frame fr  )  [static]

Definition at line 4284 of file chan_iax2.c.

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

Referenced by iax2_send().

04285 {
04286    fr->sentyet = 0;
04287 
04288    return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04289 }

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

Definition at line 9163 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

09164 {
09165    /* Drop when trunk is about 5 seconds idle */
09166    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
09167       return 1;
09168    return 0;
09169 }

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

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

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

static int iax2_vnak ( int  callno  )  [static]

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

09085 {
09086    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09087 }

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

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

07453 {
07454    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07455    int res = -1;
07456    ast_mutex_lock(&iaxsl[callno]);
07457    if (iaxs[callno]) {
07458    /* If there's an outstanding error, return failure now */
07459       if (!iaxs[callno]->error) {
07460          if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07461             res = 0;
07462             /* Don't waste bandwidth sending null frames */
07463          else if (f->frametype == AST_FRAME_NULL)
07464             res = 0;
07465          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07466             res = 0;
07467          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07468             res = 0;
07469          else
07470          /* Simple, just queue for transmission */
07471             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07472       } else {
07473          ast_debug(1, "Write error: %s\n", strerror(errno));
07474       }
07475    }
07476    /* If it's already gone, just return */
07477    ast_mutex_unlock(&iaxsl[callno]);
07478    return res;
07479 }

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

09338 {
09339    struct iax_dual *d;
09340    struct ast_channel *chan1m, *chan2m;/* Chan2m: The transferer, chan1m: The transferee */
09341    pthread_t th;
09342 
09343    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09344    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09345    d = ast_calloc(1, sizeof(*d));
09346    if (!chan1m || !chan2m || !d) {
09347       if (chan1m) {
09348          ast_hangup(chan1m);
09349       }
09350       if (chan2m) {
09351          ast_hangup(chan2m);
09352       }
09353       ast_free(d);
09354       return -1;
09355    }
09356    d->park_exten = ast_strdup(park_exten);
09357    d->park_context = ast_strdup(park_context);
09358    if (!d->park_exten || !d->park_context) {
09359       ast_hangup(chan1m);
09360       ast_hangup(chan2m);
09361       ast_free(d->park_exten);
09362       ast_free(d->park_context);
09363       ast_free(d);
09364       return -1;
09365    }
09366 
09367    /* Make formats okay */
09368    chan1m->readformat = chan1->readformat;
09369    chan1m->writeformat = chan1->writeformat;
09370 
09371    /* Prepare for taking over the channel */
09372    if (ast_channel_masquerade(chan1m, chan1)) {
09373       ast_hangup(chan1m);
09374       ast_hangup(chan2m);
09375       ast_free(d->park_exten);
09376       ast_free(d->park_context);
09377       ast_free(d);
09378       return -1;
09379    }
09380 
09381    /* Setup the extensions and such */
09382    ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09383    ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09384    chan1m->priority = chan1->priority;
09385 
09386    ast_do_masquerade(chan1m);
09387 
09388    /* We make a clone of the peer channel too, so we can play
09389       back the announcement */
09390 
09391    /* Make formats okay */
09392    chan2m->readformat = chan2->readformat;
09393    chan2m->writeformat = chan2->writeformat;
09394    ast_string_field_set(chan2m, parkinglot, chan2->parkinglot);
09395 
09396    /* Prepare for taking over the channel */
09397    if (ast_channel_masquerade(chan2m, chan2)) {
09398       ast_hangup(chan1m);
09399       ast_hangup(chan2m);
09400       ast_free(d->park_exten);
09401       ast_free(d->park_context);
09402       ast_free(d);
09403       return -1;
09404    }
09405 
09406    /* Setup the extensions and such */
09407    ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09408    ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09409    chan2m->priority = chan2->priority;
09410 
09411    ast_do_masquerade(chan2m);
09412 
09413    d->chan1 = chan1m;   /* Transferee */
09414    d->chan2 = chan2m;   /* Transferer */
09415    if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) {
09416       /* Could not start thread */
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    return 0;
09425 }

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

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

09311 {
09312    struct iax_dual *d;
09313    int res;
09314    int ext = 0;
09315 
09316    d = stuff;
09317 
09318    ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n",
09319       d->chan2->name, d->chan1->name);
09320 
09321    res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext);
09322    if (res) {
09323       /* Parking failed. */
09324       ast_hangup(d->chan1);
09325    } else {
09326       ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09327    }
09328    ast_hangup(d->chan2);
09329 
09330    ast_free(d->park_exten);
09331    ast_free(d->park_context);
09332    ast_free(d);
09333    return NULL;
09334 }

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

14732 {
14733    static const char config[] = "iax.conf";
14734    int x = 0;
14735    struct iax2_registry *reg = NULL;
14736 
14737    if (load_objects()) {
14738       return AST_MODULE_LOAD_FAILURE;
14739    }
14740 
14741    memset(iaxs, 0, sizeof(iaxs));
14742 
14743    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14744       ast_mutex_init(&iaxsl[x]);
14745    }
14746 
14747    if (!(sched = ast_sched_thread_create())) {
14748       ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14749       return AST_MODULE_LOAD_FAILURE;
14750    }
14751 
14752    if (!(io = io_context_create())) {
14753       ast_log(LOG_ERROR, "Failed to create I/O context\n");
14754       sched = ast_sched_thread_destroy(sched);
14755       return AST_MODULE_LOAD_FAILURE;
14756    }
14757 
14758    if (!(netsock = ast_netsock_list_alloc())) {
14759       ast_log(LOG_ERROR, "Failed to create netsock list\n");
14760       io_context_destroy(io);
14761       sched = ast_sched_thread_destroy(sched);
14762       return AST_MODULE_LOAD_FAILURE;
14763    }
14764    ast_netsock_init(netsock);
14765    
14766    outsock = ast_netsock_list_alloc();
14767    if (!outsock) {
14768       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14769       io_context_destroy(io);
14770       sched = ast_sched_thread_destroy(sched);
14771       return AST_MODULE_LOAD_FAILURE;
14772    }
14773    ast_netsock_init(outsock);
14774 
14775    randomcalltokendata = ast_random();
14776 
14777    iax_set_output(iax_debug_output);
14778    iax_set_error(iax_error_output);
14779    jb_setoutput(jb_error_output, jb_warning_output, NULL);
14780    
14781    if ((timer = ast_timer_open())) {
14782       ast_timer_set_rate(timer, 1000 / trunkfreq);
14783    }
14784 
14785    if (set_config(config, 0) == -1) {
14786       if (timer) {
14787          ast_timer_close(timer);
14788          timer = NULL;
14789       }
14790       return AST_MODULE_LOAD_DECLINE;
14791    }
14792 
14793 #ifdef TEST_FRAMEWORK
14794    AST_TEST_REGISTER(test_iax2_peers_get);
14795    AST_TEST_REGISTER(test_iax2_users_get);
14796 #endif
14797 
14798    /* Register AstData providers */
14799    ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
14800    ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14801 
14802    ast_register_application_xml(papp, iax2_prov_app);
14803 
14804    ast_custom_function_register(&iaxpeer_function);
14805    ast_custom_function_register(&iaxvar_function);
14806 
14807    ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
14808    ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
14809    ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
14810    ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
14811 
14812    if (ast_channel_register(&iax2_tech)) {
14813       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
14814       __unload_module();
14815       return AST_MODULE_LOAD_FAILURE;
14816    }
14817 
14818    if (ast_register_switch(&iax2_switch)) {
14819       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
14820    }
14821 
14822    if (start_network_thread()) {
14823       ast_log(LOG_ERROR, "Unable to start network thread\n");
14824       __unload_module();
14825       return AST_MODULE_LOAD_FAILURE;
14826    } else {
14827       ast_verb(2, "IAX Ready and Listening\n");
14828    }
14829 
14830    AST_LIST_LOCK(&registrations);
14831    AST_LIST_TRAVERSE(&registrations, reg, entry)
14832       iax2_do_register(reg);
14833    AST_LIST_UNLOCK(&registrations); 
14834    
14835    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
14836    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
14837 
14838 
14839    reload_firmware(0);
14840    iax_provision_reload(0);
14841 
14842    ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
14843 
14844    network_change_event_subscribe();
14845 
14846    return AST_MODULE_LOAD_SUCCESS;
14847 }

static int load_objects ( void   )  [static]

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

14494 {
14495    peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14496    peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14497 
14498    if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14499       goto container_fail;
14500    } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14501       goto container_fail;
14502    } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14503       goto container_fail;
14504    } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14505       goto container_fail;
14506    } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14507       goto container_fail;
14508    } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14509       goto container_fail;
14510    } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14511       goto container_fail;
14512    } else if (create_callno_pools()) {
14513       goto container_fail;
14514    } else if  (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14515       goto container_fail;
14516    }
14517 
14518    return 0;
14519 
14520 container_fail:
14521    if (peers) {
14522       ao2_ref(peers, -1);
14523    }
14524    if (users) {
14525       ao2_ref(users, -1);
14526    }
14527    if (iax_peercallno_pvts) {
14528       ao2_ref(iax_peercallno_pvts, -1);
14529    }
14530    if (iax_transfercallno_pvts) {
14531       ao2_ref(iax_transfercallno_pvts, -1);
14532    }
14533    if (peercnts) {
14534       ao2_ref(peercnts, -1);
14535    }
14536    if (callno_limits) {
14537       ao2_ref(callno_limits, -1);
14538    }
14539    if (calltoken_ignores) {
14540       ao2_ref(calltoken_ignores, -1);
14541    }
14542    if (callno_pool) {
14543       ao2_ref(callno_pool, -1);
14544    }
14545    if (callno_pool_trunk) {
14546       ao2_ref(callno_pool_trunk, -1);
14547    }
14548    return AST_MODULE_LOAD_FAILURE;
14549 }

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

Definition at line 5457 of file chan_iax2.c.

References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.

Referenced by iax2_bridge().

05458 {
05459    ast_mutex_lock(&iaxsl[callno0]);
05460    while (ast_mutex_trylock(&iaxsl[callno1])) {
05461       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05462    }
05463 }

static void log_jitterstats ( unsigned short  callno  )  [static]

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

09498 {
09499    int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09500    jb_info jbinfo;
09501 
09502    ast_mutex_lock(&iaxsl[callno]);
09503    if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09504       if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09505          jb_getinfo(iaxs[callno]->jb, &jbinfo);
09506          localjitter = jbinfo.jitter;
09507          localdelay = jbinfo.current - jbinfo.min;
09508          locallost = jbinfo.frames_lost;
09509          locallosspct = jbinfo.losspct/1000;
09510          localdropped = jbinfo.frames_dropped;
09511          localooo = jbinfo.frames_ooo;
09512          localpackets = jbinfo.frames_in;
09513       }
09514       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",
09515          iaxs[callno]->owner->name,
09516          iaxs[callno]->pingtime,
09517          localjitter,
09518          localdelay,
09519          locallost,
09520          locallosspct,
09521          localdropped,
09522          localooo,
09523          localpackets,
09524          iaxs[callno]->remote_rr.jitter,
09525          iaxs[callno]->remote_rr.delay,
09526          iaxs[callno]->remote_rr.losscnt,
09527          iaxs[callno]->remote_rr.losspct/1000,
09528          iaxs[callno]->remote_rr.dropped,
09529          iaxs[callno]->remote_rr.ooo,
09530          iaxs[callno]->remote_rr.packets);
09531       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",
09532          iaxs[callno]->owner->name,
09533          iaxs[callno]->pingtime,
09534          localjitter,
09535          localdelay,
09536          locallost,
09537          locallosspct,
09538          localdropped,
09539          localooo,
09540          localpackets,
09541          iaxs[callno]->remote_rr.jitter,
09542          iaxs[callno]->remote_rr.delay,
09543          iaxs[callno]->remote_rr.losscnt,
09544          iaxs[callno]->remote_rr.losspct/1000,
09545          iaxs[callno]->remote_rr.dropped,
09546          iaxs[callno]->remote_rr.ooo,
09547          iaxs[callno]->remote_rr.packets);
09548    }
09549    ast_mutex_unlock(&iaxsl[callno]);
09550 }

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

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

Referenced by load_module().

06954 {
06955    ast_cli_netstats(s, -1, 0);
06956    astman_append(s, "\r\n");
06957    return RESULT_SUCCESS;
06958 }

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

07017 {
07018    struct iax2_peer *peer = NULL;
07019    int peer_count = 0;
07020    char nm[20];
07021    char status[20];
07022    const char *id = astman_get_header(m,"ActionID");
07023    char idtext[256] = "";
07024    struct ast_str *encmethods = ast_str_alloca(256);
07025    struct ao2_iterator i;
07026 
07027    if (!ast_strlen_zero(id))
07028       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07029 
07030    astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
07031 
07032 
07033    i = ao2_iterator_init(peers, 0);
07034    for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
07035       encmethods_to_str(peer->encmethods, &encmethods);
07036       astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
07037       if (!ast_strlen_zero(peer->username)) {
07038          astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
07039       } else {
07040          astman_append(s, "ObjectName: %s\r\n", peer->name);
07041       }
07042       astman_append(s, "ChanObjectType: peer\r\n");
07043       astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
07044       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
07045       astman_append(s, "Mask: %s\r\n", nm);
07046       astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
07047       astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
07048       astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
07049       astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
07050       peer_status(peer, status, sizeof(status));
07051       astman_append(s, "Status: %s\r\n\r\n", status);
07052       peer_count++;
07053    }
07054    ao2_iterator_destroy(&i);
07055 
07056    astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07057    return RESULT_SUCCESS;
07058 }

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

callback to display iax peers in manager

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

06993 {
06994    static const char * const a[] = { "iax2", "show", "peers" };
06995    const char *id = astman_get_header(m,"ActionID");
06996    char idtext[256] = "";
06997    int total = 0;
06998 
06999    if (!ast_strlen_zero(id))
07000       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07001 
07002    astman_send_listack(s, m, "Peer status list will follow", "start");
07003         /* List the peers in separate manager events */
07004    __iax2_show_peers(-1, &total, s, 3, a);
07005         /* Send final confirmation */
07006         astman_append(s,
07007         "Event: PeerlistComplete\r\n"
07008         "EventList: Complete\r\n"
07009         "ListItems: %d\r\n"
07010         "%s"
07011         "\r\n", total, idtext);
07012         return 0;
07013 }

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

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

07125 {
07126    const char *id = astman_get_header(m, "ActionID");
07127    struct iax2_registry *reg = NULL;
07128    char idtext[256] = "";
07129    char host[80] = "";
07130    char perceived[80] = "";
07131    int total = 0;
07132 
07133    if (!ast_strlen_zero(id))
07134       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07135 
07136    astman_send_listack(s, m, "Registrations will follow", "start");
07137 
07138    AST_LIST_LOCK(&registrations);
07139    AST_LIST_TRAVERSE(&registrations, reg, entry) {
07140       snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
07141       
07142       if (reg->us.sin_addr.s_addr) {
07143          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07144       } else {
07145          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07146       }
07147       
07148       astman_append(s,
07149          "Event: RegistryEntry\r\n"
07150          "%s"
07151          "Host: %s\r\n"
07152          "DNSmanager: %s\r\n"
07153          "Username: %s\r\n"
07154          "Perceived: %s\r\n"
07155          "Refresh: %d\r\n"
07156          "State: %s\r\n"
07157          "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 
07158          reg->refresh, regstate2str(reg->regstate));
07159 
07160       total++;
07161    }
07162    AST_LIST_UNLOCK(&registrations);
07163 
07164    astman_append(s,
07165       "Event: RegistrationsComplete\r\n"
07166       "EventList: Complete\r\n"
07167       "ListItems: %d\r\n"
07168       "%s"
07169       "\r\n", total, idtext);
07170    
07171    return 0;
07172 }

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

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

Referenced by decode_frame().

06210 {
06211 #if 0
06212    /* Debug with "fake encryption" */
06213    int x;
06214    if (len % 16)
06215       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06216    for (x=0;x<len;x++)
06217       dst[x] = src[x] ^ 0xff;
06218 #else 
06219    unsigned char lastblock[16] = { 0 };
06220    int x;
06221    while(len > 0) {
06222       ast_aes_decrypt(src, dst, dcx);
06223       for (x=0;x<16;x++)
06224          dst[x] ^= lastblock[x];
06225       memcpy(lastblock, src, sizeof(lastblock));
06226       dst += 16;
06227       src += 16;
06228       len -= 16;
06229    }
06230 #endif
06231 }

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

Definition at line 6233 of file chan_iax2.c.

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

Referenced by encrypt_frame().

06234 {
06235 #if 0
06236    /* Debug with "fake encryption" */
06237    int x;
06238    if (len % 16)
06239       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06240    for (x=0;x<len;x++)
06241       dst[x] = src[x] ^ 0xff;
06242 #else
06243    unsigned char curblock[16] = { 0 };
06244    int x;
06245    while(len > 0) {
06246       for (x=0;x<16;x++)
06247          curblock[x] ^= src[x];
06248       ast_aes_encrypt(curblock, dst, ecx);
06249       memcpy(curblock, dst, sizeof(curblock)); 
06250       dst += 16;
06251       src += 16;
06252       len -= 16;
06253    }
06254 #endif
06255 }

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

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

07798 {
07799    /* Select exactly one common encryption if there are any */
07800    p->encmethods &= enc;
07801    if (p->encmethods) {
07802       if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */
07803          p->keyrotateid = -2;
07804       }
07805       if (p->encmethods & IAX_ENCRYPT_AES128)
07806          p->encmethods = IAX_ENCRYPT_AES128;
07807       else
07808          p->encmethods = 0;
07809    }
07810 }

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

12202 {
12203    if (timer) {
12204       ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12205    }
12206 
12207    for (;;) {
12208       pthread_testcancel();
12209       /* Wake up once a second just in case SIGURG was sent while
12210        * we weren't in poll(), to make sure we don't hang when trying
12211        * to unload. */
12212       if (ast_io_wait(io, 1000) <= 0) {
12213          break;
12214       }
12215    }
12216 
12217    return NULL;
12218 }

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

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

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

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

12953 {
12954    struct iax2_peer *peer = obj;
12955 
12956    ast_set_flag64(peer, IAX_DELME);
12957 
12958    return 0;
12959 }

static void peer_destructor ( void *  obj  )  [static]

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

12382 {
12383    struct iax2_peer *peer = obj;
12384    int callno = peer->callno;
12385 
12386    ast_free_ha(peer->ha);
12387 
12388    if (callno > 0) {
12389       ast_mutex_lock(&iaxsl[callno]);
12390       iax2_destroy(callno);
12391       ast_mutex_unlock(&iaxsl[callno]);
12392    }
12393 
12394    register_peer_exten(peer, 0);
12395 
12396    if (peer->dnsmgr)
12397       ast_dnsmgr_release(peer->dnsmgr);
12398 
12399    if (peer->mwi_event_sub)
12400       ast_event_unsubscribe(peer->mwi_event_sub);
12401 
12402    ast_string_field_free_memory(peer);
12403 }

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

References iax2_peer::sockfd.

Referenced by load_module().

14448 {
14449    struct iax2_peer *peer = obj;
14450 
14451    if (peer->sockfd < 0)
14452       peer->sockfd = defaultsockfd;
14453 
14454    return 0;
14455 }

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

12309 {
12310    struct sockaddr_in sin;
12311    struct ast_sockaddr sin_tmp;
12312    int nonlocal = 1;
12313    int port = IAX_DEFAULT_PORTNO;
12314    int sockfd = defaultsockfd;
12315    char *tmp;
12316    char *addr;
12317    char *portstr;
12318 
12319    tmp = ast_strdupa(srcaddr);
12320    addr = strsep(&tmp, ":");
12321    portstr = tmp;
12322 
12323    if (portstr) {
12324       port = atoi(portstr);
12325       if (port < 1)
12326          port = IAX_DEFAULT_PORTNO;
12327    }
12328 
12329    sin_tmp.ss.ss_family = AF_INET;
12330    if (!ast_get_ip(&sin_tmp, addr)) {
12331       struct ast_netsock *sock;
12332       int res;
12333 
12334       ast_sockaddr_to_sin(&sin_tmp, &sin);
12335       sin.sin_port = 0;
12336       sin.sin_family = AF_INET;
12337       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12338       if (res == 0) {
12339          /* ip address valid. */
12340          sin.sin_port = htons(port);
12341          if (!(sock = ast_netsock_find(netsock, &sin)))
12342             sock = ast_netsock_find(outsock, &sin);
12343          if (sock) {
12344             sockfd = ast_netsock_sockfd(sock);
12345             nonlocal = 0;
12346          } else {
12347             unsigned int orig_saddr = sin.sin_addr.s_addr;
12348             /* INADDR_ANY matches anyway! */
12349             sin.sin_addr.s_addr = INADDR_ANY;
12350             if (ast_netsock_find(netsock, &sin)) {
12351                sin.sin_addr.s_addr = orig_saddr;
12352                sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12353                if (sock) {
12354                   sockfd = ast_netsock_sockfd(sock);
12355                   ast_netsock_unref(sock);
12356                   nonlocal = 0;
12357                } else {
12358                   nonlocal = 2;
12359                }
12360             }
12361          }
12362       }
12363    }
12364       
12365    peer->sockfd = sockfd;
12366 
12367    if (nonlocal == 1) {
12368       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12369          srcaddr, peer->name);
12370       return -1;
12371         } else if (nonlocal == 2) {
12372       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12373          srcaddr, peer->name);
12374          return -1;
12375    } else {
12376       ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12377       return 0;
12378    }
12379 }

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

peer_status: Report Peer status in character string

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

03723 {
03724    int res = 0;
03725    if (peer->maxms) {
03726       if (peer->lastms < 0) {
03727          ast_copy_string(status, "UNREACHABLE", statuslen);
03728       } else if (peer->lastms > peer->maxms) {
03729          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03730          res = 1;
03731       } else if (peer->lastms) {
03732          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03733          res = 1;
03734       } else {
03735          ast_copy_string(status, "UNKNOWN", statuslen);
03736       }
03737    } else { 
03738       ast_copy_string(status, "Unmonitored", statuslen);
03739       res = -1;
03740    }
03741    return res;
03742 }

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

14583 {
14584    struct ast_data *data_peer;
14585    struct iax2_peer *peer;
14586    struct ao2_iterator i;
14587    char status[20];
14588    struct ast_str *encmethods = ast_str_alloca(256);
14589 
14590    i = ao2_iterator_init(peers, 0);
14591    while ((peer = ao2_iterator_next(&i))) {
14592       data_peer = ast_data_add_node(data_root, "peer");
14593       if (!data_peer) {
14594          peer_unref(peer);
14595          continue;
14596       }
14597 
14598       ast_data_add_structure(iax2_peer, data_peer, peer);
14599 
14600       ast_data_add_codecs(data_peer, "codecs", peer->capability);
14601 
14602       peer_status(peer, status, sizeof(status));
14603       ast_data_add_str(data_peer, "status", status);
14604 
14605       ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14606 
14607       ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14608 
14609       ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14610 
14611       ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14612 
14613       ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14614 
14615       encmethods_to_str(peer->encmethods, &encmethods);
14616       ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14617 
14618       peer_unref(peer);
14619 
14620       if (!ast_data_search_match(search, data_peer)) {
14621          ast_data_remove_node(data_root, data_peer);
14622       }
14623    }
14624    ao2_iterator_destroy(&i);
14625 
14626    return 0;
14627 }

static void poke_all_peers ( void   )  [static]

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

13532 {
13533    struct ao2_iterator i;
13534    struct iax2_peer *peer;
13535 
13536    i = ao2_iterator_init(peers, 0);
13537    while ((peer = ao2_iterator_next(&i))) {
13538       iax2_poke_peer(peer, 0);
13539       peer_unref(peer);
13540    }
13541    ao2_iterator_destroy(&i);
13542 }

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

13016 {
13017    struct iax2_peer *peer;
13018    struct ao2_iterator i;
13019 
13020    i = ao2_iterator_init(peers, 0);
13021    while ((peer = ao2_iterator_next(&i))) {
13022       if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
13023          unlink_peer(peer);
13024       }
13025       peer_unref(peer);
13026    }
13027    ao2_iterator_destroy(&i);
13028 }

static void prune_users ( void   )  [static]

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

13000 {
13001    struct iax2_user *user;
13002    struct ao2_iterator i;
13003 
13004    i = ao2_iterator_init(users, 0);
13005    while ((user = ao2_iterator_next(&i))) {
13006       if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
13007          ao2_unlink(users, user);
13008       }
13009       user_unref(user);
13010    }
13011    ao2_iterator_destroy(&i);
13012 }

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

Definition at line 14464 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, and match().

Referenced by load_objects().

14465 {
14466    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14467 
14468    /* The frames_received field is used to hold whether we're matching
14469     * against a full frame or not ... */
14470 
14471    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
14472       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14473 }

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

References chan_iax2_pvt::peercallno.

Referenced by load_objects().

14458 {
14459    const struct chan_iax2_pvt *pvt = obj;
14460 
14461    return pvt->peercallno;
14462 }

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

07779 {
07780    struct ast_iax2_full_hdr fh;
07781    fh.scallno = htons(src | IAX_FLAG_FULL);
07782    fh.dcallno = htons(dst);
07783    fh.ts = 0;
07784    fh.oseqno = 0;
07785    fh.iseqno = 0;
07786    fh.type = AST_FRAME_IAX;
07787    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07788    iax_outputframe(NULL, &fh, 0, sin, 0);
07789 #if 0
07790    if (option_debug)
07791 #endif   
07792       ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07793          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07794    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07795 }

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

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

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

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

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

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

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

static void reg_source_db ( struct iax2_peer p  )  [static]

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

08667 {
08668    char data[80];
08669    char *expiry;
08670 
08671    if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08672       return;
08673    }
08674 
08675    expiry = strrchr(data, ':');
08676    if (!expiry) {
08677       ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08678       return;
08679    }
08680    *expiry++ = '\0';
08681 
08682    if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08683       ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08684       return;
08685    }
08686 
08687    p->expiry = atoi(expiry);
08688 
08689    ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08690       ast_sockaddr_stringify(&p->addr), p->expiry);
08691 
08692    iax2_poke_peer(p, 0);
08693    if (p->expire > -1) {
08694       if (!ast_sched_thread_del(sched, p->expire)) {
08695          p->expire = -1;
08696          peer_unref(p);
08697       }
08698    }
08699 
08700    ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
08701 
08702    p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08703    if (p->expire == -1) {
08704       peer_unref(p);
08705    }
08706 
08707    if (iax2_regfunk) {
08708       iax2_regfunk(p->name, 1);
08709    }
08710 
08711    register_peer_exten(p, 1);
08712 }

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

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

08582 {
08583    char multi[256];
08584    char *stringp, *ext;
08585    if (!ast_strlen_zero(regcontext)) {
08586       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08587       stringp = multi;
08588       while((ext = strsep(&stringp, "&"))) {
08589          if (onoff) {
08590             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08591                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08592                        "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08593          } else
08594             ast_context_remove_extension(regcontext, ext, 1, NULL);
08595       }
08596    }
08597 }

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

Verify inbound registration.

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

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

static int registry_authrequest ( int  callno  )  [static]

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

08889 {
08890    struct iax_ie_data ied;
08891    struct iax2_peer *p;
08892    char challenge[10];
08893    const char *peer_name;
08894    int sentauthmethod;
08895 
08896    peer_name = ast_strdupa(iaxs[callno]->peer);
08897 
08898    /* SLD: third call to find_peer in registration */
08899    ast_mutex_unlock(&iaxsl[callno]);
08900    if ((p = find_peer(peer_name, 1))) {
08901       last_authmethod = p->authmethods;
08902    }
08903 
08904    ast_mutex_lock(&iaxsl[callno]);
08905    if (!iaxs[callno])
08906       goto return_unref;
08907 
08908    memset(&ied, 0, sizeof(ied));
08909    /* The selection of which delayed reject is sent may leak information,
08910     * if it sets a static response.  For example, if a host is known to only
08911     * use MD5 authentication, then an RSA response would indicate that the
08912     * peer does not exist, and vice-versa.
08913     * Therefore, we use whatever the last peer used (which may vary over the
08914     * course of a server, which should leak minimal information). */
08915    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08916    if (!p) {
08917       iaxs[callno]->authmethods = sentauthmethod;
08918    }
08919    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08920    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08921       /* Build the challenge */
08922       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08923       ast_string_field_set(iaxs[callno], challenge, challenge);
08924       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08925    }
08926    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08927 
08928 return_unref:
08929    if (p) {
08930       peer_unref(p);
08931    }
08932 
08933    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08934 }

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

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

08937 {
08938    struct iax2_registry *reg;
08939    /* Start pessimistic */
08940    struct iax_ie_data ied;
08941    char peer[256] = "";
08942    char challenge[256] = "";
08943    int res;
08944    int authmethods = 0;
08945    if (ies->authmethods)
08946       authmethods = ies->authmethods;
08947    if (ies->username)
08948       ast_copy_string(peer, ies->username, sizeof(peer));
08949    if (ies->challenge)
08950       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08951    memset(&ied, 0, sizeof(ied));
08952    reg = iaxs[callno]->reg;
08953    if (reg) {
08954       struct sockaddr_in reg_addr;
08955 
08956       ast_sockaddr_to_sin(&reg->addr, &reg_addr);
08957 
08958       if (inaddrcmp(&reg_addr, sin)) {
08959          ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08960          return -1;
08961       }
08962       if (ast_strlen_zero(reg->secret)) {
08963          ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08964          reg->regstate = REG_STATE_NOAUTH;
08965          return -1;
08966       }
08967       iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08968       iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08969       if (reg->secret[0] == '[') {
08970          char tmpkey[256];
08971          ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08972          tmpkey[strlen(tmpkey) - 1] = '\0';
08973          res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08974       } else
08975          res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08976       if (!res) {
08977          reg->regstate = REG_STATE_AUTHSENT;
08978          add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
08979          return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08980       } else
08981          return -1;
08982       ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08983    } else   
08984       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08985    return -1;
08986 }

static char* regstate2str ( int  regstate  )  [static]

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

07062 {
07063    switch(regstate) {
07064    case REG_STATE_UNREGISTERED:
07065       return "Unregistered";
07066    case REG_STATE_REGSENT:
07067       return "Request Sent";
07068    case REG_STATE_AUTHSENT:
07069       return "Auth. Sent";
07070    case REG_STATE_REGISTERED:
07071       return "Registered";
07072    case REG_STATE_REJECTED:
07073       return "Rejected";
07074    case REG_STATE_TIMEOUT:
07075       return "Timeout";
07076    case REG_STATE_NOAUTH:
07077       return "No Authentication";
07078    default:
07079       return "Unknown";
07080    }
07081 }

static int reload ( void   )  [static]

Definition at line 13592 of file chan_iax2.c.

References reload_config().

13593 {
13594    return reload_config();
13595 }

static int reload_config ( void   )  [static]

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

13544 {
13545    static const char config[] = "iax.conf";
13546    struct iax2_registry *reg;
13547 
13548    if (set_config(config, 1) > 0) {
13549       prune_peers();
13550       prune_users();
13551       ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13552       ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13553       ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13554       trunk_timed = trunk_untimed = 0; 
13555       trunk_nmaxmtu = trunk_maxmtu = 0;
13556       memset(&debugaddr, '\0', sizeof(debugaddr));
13557 
13558       AST_LIST_LOCK(&registrations);
13559       AST_LIST_TRAVERSE(&registrations, reg, entry)
13560          iax2_do_register(reg);
13561       AST_LIST_UNLOCK(&registrations);
13562 
13563       /* Qualify hosts, too */
13564       poke_all_peers();
13565    }
13566    
13567    reload_firmware(0);
13568    iax_provision_reload(1);
13569    ast_unload_realtime("iaxpeers");
13570 
13571    return 0;
13572 }

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

04837 {
04838    struct iax2_user *user = NULL;
04839    struct iax2_peer *peer = NULL;
04840 
04841    if (ast_strlen_zero(name)) {
04842       return; /* no username given */
04843    }
04844 
04845    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04846       user->calltoken_required = CALLTOKEN_YES;
04847    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04848       peer->calltoken_required = CALLTOKEN_YES;
04849    }
04850 
04851    if (peer) {
04852       peer_unref(peer);
04853    }
04854    if (user) {
04855       user_unref(user);
04856    }
04857 }

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

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

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

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

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

09468 {
09469    int i;
09470    unsigned int length, offset = 0;
09471    char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09472 
09473    for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09474       length = ies->ospblocklength[i];
09475       if (length != 0) {
09476          if (length > IAX_MAX_OSPBLOCK_SIZE) {
09477             /* OSP token block length wrong, clear buffer */
09478             offset = 0;
09479             break;
09480          } else {
09481             memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09482             offset += length;
09483          }
09484       } else {
09485          break;
09486       }
09487    }
09488    *(full_osptoken + offset) = '\0';
09489    if (strlen(full_osptoken) != offset) {
09490       /* OSP token length wrong, clear buffer */
09491       *full_osptoken = '\0';
09492    }
09493 
09494    ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09495 }

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

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

09457 {
09458    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09459    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09460    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09461    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09462    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09463    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09464    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09465 }

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

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

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

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

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

07520 {
07521    int call_num = i->callno;
07522    /* It is assumed that the callno has already been locked */
07523    iax2_predestroy(i->callno);
07524    if (!iaxs[call_num])
07525       return -1;
07526    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07527 }

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

References __send_command().

Referenced by iax2_vnak(), and socket_process().

07530 {
07531    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07532 }

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

07506 {
07507    int res;
07508    ast_mutex_lock(&iaxsl[callno]);
07509    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07510    ast_mutex_unlock(&iaxsl[callno]);
07511    return res;
07512 }

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

References __send_command().

Referenced by socket_process(), and try_transfer().

07535 {
07536    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07537 }

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

09121 {
09122    int res = 0;
09123    struct iax_frame *fr;
09124    struct ast_iax2_meta_hdr *meta;
09125    struct ast_iax2_meta_trunk_hdr *mth;
09126    int calls = 0;
09127    
09128    /* Point to frame */
09129    fr = (struct iax_frame *)tpeer->trunkdata;
09130    /* Point to meta data */
09131    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09132    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09133    if (tpeer->trunkdatalen) {
09134       /* We're actually sending a frame, so fill the meta trunk header and meta header */
09135       meta->zeros = 0;
09136       meta->metacmd = IAX_META_TRUNK;
09137       if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09138          meta->cmddata = IAX_META_TRUNK_MINI;
09139       else
09140          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09141       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09142       /* And the rest of the ast_iax2 header */
09143       fr->direction = DIRECTION_OUTGRESS;
09144       fr->retrans = -1;
09145       fr->transfer = 0;
09146       /* Any appropriate call will do */
09147       fr->data = fr->afdata;
09148       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09149       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09150       calls = tpeer->calls;
09151 #if 0
09152       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));
09153 #endif      
09154       /* Reset transmit trunk side data */
09155       tpeer->trunkdatalen = 0;
09156       tpeer->calls = 0;
09157    }
09158    if (res < 0)
09159       return res;
09160    return calls;
09161 }

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

Load configuration.

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

13048 {
13049    struct ast_config *cfg, *ucfg;
13050    format_t capability = iax2_capability;
13051    struct ast_variable *v;
13052    char *cat;
13053    const char *utype;
13054    const char *tosval;
13055    int format;
13056    int portno = IAX_DEFAULT_PORTNO;
13057    int  x;
13058    int mtuv;
13059    int subscribe_network_change = 1;
13060    struct iax2_user *user;
13061    struct iax2_peer *peer;
13062    struct ast_netsock *ns;
13063    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13064 #if 0
13065    static unsigned short int last_port=0;
13066 #endif
13067 
13068    cfg = ast_config_load(config_file, config_flags);
13069 
13070    if (!cfg) {
13071       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13072       return -1;
13073    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13074       ucfg = ast_config_load("users.conf", config_flags);
13075       if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13076          return 0;
13077       /* Otherwise we need to reread both files */
13078       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13079       if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13080          ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config_file);
13081          ast_config_destroy(ucfg);
13082          return 0;
13083       }
13084       if (!cfg) {
13085          /* should have been able to load the config here */
13086          ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file);
13087          return -1;
13088       }
13089    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13090       ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config_file);
13091       return 0;
13092    } else { /* iax.conf changed, gotta reread users.conf, too */
13093       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13094       if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13095          ast_log(LOG_ERROR, "Config file users.conf is in an invalid format.  Aborting.\n");
13096          ast_config_destroy(cfg);
13097          return 0;
13098       }
13099    }
13100 
13101    if (reload) {
13102       set_config_destroy();
13103    }
13104 
13105    /* Reset global codec prefs */
13106    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
13107 
13108    /* Reset Global Flags */
13109    memset(&globalflags, 0, sizeof(globalflags));
13110    ast_set_flag64(&globalflags, IAX_RTUPDATE);
13111    ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13112 
13113 #ifdef SO_NO_CHECK
13114    nochecksums = 0;
13115 #endif
13116    /* Reset default parking lot */
13117    default_parkinglot[0] = '\0';
13118 
13119    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13120    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13121    global_max_trunk_mtu = MAX_TRUNK_MTU;
13122    global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
13123    global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
13124 
13125    maxauthreq = 3;
13126 
13127    srvlookup = 0;
13128 
13129    v = ast_variable_browse(cfg, "general");
13130 
13131    /* Seed initial tos value */
13132    tosval = ast_variable_retrieve(cfg, "general", "tos");
13133    if (tosval) {
13134       if (ast_str2tos(tosval, &qos.tos))
13135          ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13136    }
13137    /* Seed initial cos value */
13138    tosval = ast_variable_retrieve(cfg, "general", "cos");
13139    if (tosval) {
13140       if (ast_str2cos(tosval, &qos.cos))
13141          ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13142    }
13143    while(v) {
13144       if (!strcasecmp(v->name, "bindport")){ 
13145          if (reload)
13146             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13147          else
13148             portno = atoi(v->value);
13149       } else if (!strcasecmp(v->name, "pingtime")) 
13150          ping_time = atoi(v->value);
13151       else if (!strcasecmp(v->name, "iaxthreadcount")) {
13152          if (reload) {
13153             if (atoi(v->value) != iaxthreadcount)
13154                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13155          } else {
13156             iaxthreadcount = atoi(v->value);
13157             if (iaxthreadcount < 1) {
13158                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13159                iaxthreadcount = 1;
13160             } else if (iaxthreadcount > 256) {
13161                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13162                iaxthreadcount = 256;
13163             }
13164          }
13165       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13166          if (reload) {
13167             AST_LIST_LOCK(&dynamic_list);
13168             iaxmaxthreadcount = atoi(v->value);
13169             AST_LIST_UNLOCK(&dynamic_list);
13170          } else {
13171             iaxmaxthreadcount = atoi(v->value);
13172             if (iaxmaxthreadcount < 0) {
13173                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13174                iaxmaxthreadcount = 0;
13175             } else if (iaxmaxthreadcount > 256) {
13176                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13177                iaxmaxthreadcount = 256;
13178             }
13179          }
13180       } else if (!strcasecmp(v->name, "nochecksums")) {
13181 #ifdef SO_NO_CHECK
13182          if (ast_true(v->value))
13183             nochecksums = 1;
13184          else
13185             nochecksums = 0;
13186 #else
13187          if (ast_true(v->value))
13188             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13189 #endif
13190       }
13191       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
13192          maxjitterbuffer = atoi(v->value);
13193       else if (!strcasecmp(v->name, "resyncthreshold")) 
13194          resyncthreshold = atoi(v->value);
13195       else if (!strcasecmp(v->name, "maxjitterinterps")) 
13196          maxjitterinterps = atoi(v->value);
13197       else if (!strcasecmp(v->name, "jittertargetextra"))
13198          jittertargetextra = atoi(v->value);
13199       else if (!strcasecmp(v->name, "lagrqtime")) 
13200          lagrq_time = atoi(v->value);
13201       else if (!strcasecmp(v->name, "maxregexpire")) 
13202          max_reg_expire = atoi(v->value);
13203       else if (!strcasecmp(v->name, "minregexpire")) 
13204          min_reg_expire = atoi(v->value);
13205       else if (!strcasecmp(v->name, "bindaddr")) {
13206          if (reload) {
13207             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13208          } else {
13209             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13210                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13211             } else {
13212                   if (strchr(v->value, ':'))
13213                   ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13214                   else
13215                   ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13216                if (defaultsockfd < 0) 
13217                   defaultsockfd = ast_netsock_sockfd(ns);
13218                ast_netsock_unref(ns);
13219             }
13220          }
13221       } else if (!strcasecmp(v->name, "authdebug")) {
13222          authdebug = ast_true(v->value);
13223       } else if (!strcasecmp(v->name, "encryption")) {
13224             iax2_encryption |= get_encrypt_methods(v->value);
13225             if (!iax2_encryption) {
13226                ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13227             }
13228       } else if (!strcasecmp(v->name, "forceencryption")) {
13229          if (ast_false(v->value)) {
13230             ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13231          } else {
13232             iax2_encryption |= get_encrypt_methods(v->value);
13233             if (iax2_encryption) {
13234                ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13235             }
13236          }
13237       } else if (!strcasecmp(v->name, "transfer")) {
13238          if (!strcasecmp(v->value, "mediaonly")) {
13239             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13240          } else if (ast_true(v->value)) {
13241             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13242          } else
13243             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13244       } else if (!strcasecmp(v->name, "codecpriority")) {
13245          if(!strcasecmp(v->value, "caller"))
13246             ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13247          else if(!strcasecmp(v->value, "disabled"))
13248             ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13249          else if(!strcasecmp(v->value, "reqonly")) {
13250             ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13251             ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13252          }
13253       } else if (!strcasecmp(v->name, "jitterbuffer"))
13254          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13255       else if (!strcasecmp(v->name, "forcejitterbuffer"))
13256          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13257       else if (!strcasecmp(v->name, "delayreject"))
13258          delayreject = ast_true(v->value);
13259       else if (!strcasecmp(v->name, "allowfwdownload"))
13260          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13261       else if (!strcasecmp(v->name, "rtcachefriends"))
13262          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13263       else if (!strcasecmp(v->name, "rtignoreregexpire"))
13264          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13265       else if (!strcasecmp(v->name, "rtupdate"))
13266          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13267       else if (!strcasecmp(v->name, "rtsavesysname"))
13268          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13269       else if (!strcasecmp(v->name, "trunktimestamps"))
13270          ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13271       else if (!strcasecmp(v->name, "rtautoclear")) {
13272          int i = atoi(v->value);
13273          if(i > 0)
13274             global_rtautoclear = i;
13275          else
13276             i = 0;
13277          ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13278       } else if (!strcasecmp(v->name, "trunkfreq")) {
13279          trunkfreq = atoi(v->value);
13280          if (trunkfreq < 10) {
13281             ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n");
13282             trunkfreq = 10;
13283          } else if (trunkfreq > 1000) {
13284             ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n");
13285             trunkfreq = 1000;
13286          }
13287          if (timer) {
13288             ast_timer_set_rate(timer, 1000 / trunkfreq);
13289          }
13290       } else if (!strcasecmp(v->name, "trunkmtu")) {
13291          mtuv = atoi(v->value);
13292          if (mtuv  == 0 )
13293             global_max_trunk_mtu = 0;
13294          else if (mtuv >= 172 && mtuv < 4000)
13295             global_max_trunk_mtu = mtuv;
13296          else
13297             ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13298                mtuv, v->lineno);
13299       } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13300          trunkmaxsize = atoi(v->value);
13301          if (trunkmaxsize == 0)
13302             trunkmaxsize = MAX_TRUNKDATA;
13303       } else if (!strcasecmp(v->name, "autokill")) {
13304          if (sscanf(v->value, "%30d", &x) == 1) {
13305             if (x >= 0)
13306                autokill = x;
13307             else
13308                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13309          } else if (ast_true(v->value)) {
13310             autokill = DEFAULT_MAXMS;
13311          } else {
13312             autokill = 0;
13313          }
13314       } else if (!strcasecmp(v->name, "bandwidth")) {
13315          if (!strcasecmp(v->value, "low")) {
13316             capability = IAX_CAPABILITY_LOWBANDWIDTH;
13317          } else if (!strcasecmp(v->value, "medium")) {
13318             capability = IAX_CAPABILITY_MEDBANDWIDTH;
13319          } else if (!strcasecmp(v->value, "high")) {
13320             capability = IAX_CAPABILITY_FULLBANDWIDTH;
13321          } else
13322             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13323       } else if (!strcasecmp(v->name, "allow")) {
13324          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13325       } else if (!strcasecmp(v->name, "disallow")) {
13326          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13327       } else if (!strcasecmp(v->name, "register")) {
13328          iax2_register(v->value, v->lineno);
13329       } else if (!strcasecmp(v->name, "iaxcompat")) {
13330          iaxcompat = ast_true(v->value);
13331       } else if (!strcasecmp(v->name, "regcontext")) {
13332          ast_copy_string(regcontext, v->value, sizeof(regcontext));
13333          /* Create context if it doesn't exist already */
13334          ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13335       } else if (!strcasecmp(v->name, "tos")) {
13336          if (ast_str2tos(v->value, &qos.tos))
13337             ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13338       } else if (!strcasecmp(v->name, "cos")) {
13339          if (ast_str2cos(v->value, &qos.cos))
13340             ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13341       } else if (!strcasecmp(v->name, "parkinglot")) {
13342          ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13343       } else if (!strcasecmp(v->name, "accountcode")) {
13344          ast_copy_string(accountcode, v->value, sizeof(accountcode));
13345       } else if (!strcasecmp(v->name, "mohinterpret")) {
13346          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13347       } else if (!strcasecmp(v->name, "mohsuggest")) {
13348          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13349       } else if (!strcasecmp(v->name, "amaflags")) {
13350          format = ast_cdr_amaflags2int(v->value);
13351          if (format < 0) {
13352             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13353          } else {
13354             amaflags = format;
13355          }
13356       } else if (!strcasecmp(v->name, "language")) {
13357          ast_copy_string(language, v->value, sizeof(language));
13358       } else if (!strcasecmp(v->name, "maxauthreq")) {
13359          maxauthreq = atoi(v->value);
13360          if (maxauthreq < 0)
13361             maxauthreq = 0;
13362       } else if (!strcasecmp(v->name, "adsi")) {
13363          adsi = ast_true(v->value);
13364       } else if (!strcasecmp(v->name, "srvlookup")) {
13365          srvlookup = ast_true(v->value);
13366       } else if (!strcasecmp(v->name, "connectedline")) {
13367          if (ast_true(v->value)) {
13368             ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13369          } else if (!strcasecmp(v->value, "send")) {
13370             ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13371             ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13372          } else if (!strcasecmp(v->value, "receive")) {
13373             ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13374             ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13375          } else {
13376             ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13377          }
13378       } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13379          if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13380             ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number.  %s is not valid at line %d\n", v->value, v->lineno);
13381          }
13382       } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13383          if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13384             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);
13385          }
13386       } else if (!strcasecmp(v->name, "calltokenoptional")) {
13387          if (add_calltoken_ignore(v->value)) {
13388             ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13389          }
13390       } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13391          if (ast_true(v->value)) {
13392             subscribe_network_change = 1;
13393          } else if (ast_false(v->value)) {
13394             subscribe_network_change = 0;
13395          } else {
13396             ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13397          }
13398       } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13399          if (ast_true(v->value)) {
13400             ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13401          } else if (ast_false(v->value)) {
13402             ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13403          } else {
13404             ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13405          }
13406       }/*else if (strcasecmp(v->name,"type")) */
13407       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13408       v = v->next;
13409    }
13410 
13411    if (subscribe_network_change) {
13412       network_change_event_subscribe();
13413    } else {
13414       network_change_event_unsubscribe();
13415    }
13416 
13417    if (defaultsockfd < 0) {
13418       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13419          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13420       } else {
13421          ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13422          defaultsockfd = ast_netsock_sockfd(ns);
13423          ast_netsock_unref(ns);
13424       }
13425    }
13426    if (reload) {
13427       ast_netsock_release(outsock);
13428       outsock = ast_netsock_list_alloc();
13429       if (!outsock) {
13430          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13431          return -1;
13432       }
13433       ast_netsock_init(outsock);
13434    }
13435 
13436    if (min_reg_expire > max_reg_expire) {
13437       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13438          min_reg_expire, max_reg_expire, max_reg_expire);
13439       min_reg_expire = max_reg_expire;
13440    }
13441    iax2_capability = capability;
13442    
13443    if (ucfg) {
13444       struct ast_variable *gen;
13445       int genhasiax;
13446       int genregisteriax;
13447       const char *hasiax, *registeriax;
13448       
13449       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13450       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13451       gen = ast_variable_browse(ucfg, "general");
13452       cat = ast_category_browse(ucfg, NULL);
13453       while (cat) {
13454          if (strcasecmp(cat, "general")) {
13455             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13456             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13457             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13458                /* Start with general parameters, then specific parameters, user and peer */
13459                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13460                if (user) {
13461                   ao2_link(users, user);
13462                   user = user_unref(user);
13463                }
13464                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13465                if (peer) {
13466                   if (ast_test_flag64(peer, IAX_DYNAMIC))
13467                      reg_source_db(peer);
13468                   ao2_link(peers, peer);
13469                   peer = peer_unref(peer);
13470                }
13471             }
13472             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13473                char tmp[256];
13474                const char *host = ast_variable_retrieve(ucfg, cat, "host");
13475                const char *username = ast_variable_retrieve(ucfg, cat, "username");
13476                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13477                if (!host)
13478                   host = ast_variable_retrieve(ucfg, "general", "host");
13479                if (!username)
13480                   username = ast_variable_retrieve(ucfg, "general", "username");
13481                if (!secret)
13482                   secret = ast_variable_retrieve(ucfg, "general", "secret");
13483                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13484                   if (!ast_strlen_zero(secret))
13485                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13486                   else
13487                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13488                   iax2_register(tmp, 0);
13489                }
13490             }
13491          }
13492          cat = ast_category_browse(ucfg, cat);
13493       }
13494       ast_config_destroy(ucfg);
13495    }
13496    
13497    cat = ast_category_browse(cfg, NULL);
13498    while(cat) {
13499       if (strcasecmp(cat, "general")) {
13500          utype = ast_variable_retrieve(cfg, cat, "type");
13501          if (!strcasecmp(cat, "callnumberlimits")) {
13502             build_callno_limits(ast_variable_browse(cfg, cat));
13503          } else if (utype) {
13504             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13505                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13506                if (user) {
13507                   ao2_link(users, user);
13508                   user = user_unref(user);
13509                }
13510             }
13511             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13512                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13513                if (peer) {
13514                   if (ast_test_flag64(peer, IAX_DYNAMIC))
13515                      reg_source_db(peer);
13516                   ao2_link(peers, peer);
13517                   peer = peer_unref(peer);
13518                }
13519             } else if (strcasecmp(utype, "user")) {
13520                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13521             }
13522          } else
13523             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13524       }
13525       cat = ast_category_browse(cfg, cat);
13526    }
13527    ast_config_destroy(cfg);
13528    return 1;
13529 }

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

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

09894 {
09895    iax2_lock_owner(callno);
09896    if (iaxs[callno] && iaxs[callno]->owner) {
09897       struct ast_channel *owner;
09898       const char *name;
09899 
09900       owner = iaxs[callno]->owner;
09901       if (causecode) {
09902          owner->hangupcause = causecode;
09903       }
09904       name = ast_strdupa(owner->name);
09905       ast_channel_ref(owner);
09906       ast_channel_unlock(owner);
09907       ast_mutex_unlock(&iaxsl[callno]);
09908       ast_set_hangupsource(owner, name, 0);
09909       ast_channel_unref(owner);
09910       ast_mutex_lock(&iaxsl[callno]);
09911    }
09912 }

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 9914 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_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, 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_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().

09915 {
09916    struct sockaddr_in sin;
09917    int res;
09918    int updatehistory=1;
09919    int new = NEW_PREVENT;
09920    int dcallno = 0;
09921    char decrypted = 0;
09922    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09923    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09924    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09925    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09926    struct iax_frame *fr;
09927    struct iax_frame *cur;
09928    struct ast_frame f = { 0, };
09929    struct ast_channel *c = NULL;
09930    struct iax2_dpcache *dp;
09931    struct iax2_peer *peer;
09932    struct iax_ies ies;
09933    struct iax_ie_data ied0, ied1;
09934    format_t format;
09935    int fd;
09936    int exists;
09937    int minivid = 0;
09938    char empty[32]="";      /* Safety measure */
09939    struct iax_frame *duped_fr;
09940    char host_pref_buf[128];
09941    char caller_pref_buf[128];
09942    struct ast_codec_pref pref;
09943    char *using_prefs = "mine";
09944 
09945    /* allocate an iax_frame with 4096 bytes of data buffer */
09946    fr = ast_alloca(sizeof(*fr) + 4096);
09947    memset(fr, 0, sizeof(*fr));
09948    fr->afdatalen = 4096; /* From ast_alloca() above */
09949 
09950    /* Copy frequently used parameters to the stack */
09951    res = thread->buf_len;
09952    fd = thread->iofd;
09953    memcpy(&sin, &thread->iosin, sizeof(sin));
09954 
09955    if (res < sizeof(*mh)) {
09956       ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09957       return 1;
09958    }
09959    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09960       if (res < sizeof(*vh)) {
09961          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));
09962          return 1;
09963       }
09964 
09965       /* This is a video frame, get call number */
09966       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09967       minivid = 1;
09968    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09969       return socket_process_meta(res, meta, &sin, fd, fr);
09970 
09971 #ifdef DEBUG_SUPPORT
09972    if (res >= sizeof(*fh))
09973       iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09974 #endif
09975    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09976       if (res < sizeof(*fh)) {
09977          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));
09978          return 1;
09979       }
09980 
09981       /* Get the destination call number */
09982       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09983 
09984 
09985       /* check to make sure this full frame isn't encrypted before we attempt
09986        * to look inside of it. If it is encrypted, decrypt it first. Its ok if the
09987        * callno is not found here, that just means one hasn't been allocated for
09988        * this connection yet. */
09989       if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09990          ast_mutex_lock(&iaxsl[fr->callno]);
09991          if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
09992             if (decrypt_frame(fr->callno, fh, &f, &res)) {
09993                ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09994                ast_mutex_unlock(&iaxsl[fr->callno]);
09995                return 1;
09996             }
09997             decrypted = 1;
09998          }
09999          ast_mutex_unlock(&iaxsl[fr->callno]);
10000       }
10001 
10002       /* Retrieve the type and subclass */
10003       f.frametype = fh->type;
10004       if (f.frametype == AST_FRAME_VIDEO) {
10005          f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
10006       } else if (f.frametype == AST_FRAME_VOICE) {
10007          f.subclass.codec = uncompress_subclass(fh->csub);
10008       } else {
10009          f.subclass.integer = uncompress_subclass(fh->csub);
10010       }
10011 
10012       /* Deal with POKE/PONG without allocating a callno */
10013       if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
10014          /* Reply back with a PONG, but don't care about the result. */
10015          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10016          return 1;
10017       } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
10018          /* Ignore */
10019          return 1;
10020       }
10021 
10022       f.datalen = res - sizeof(*fh);
10023       if (f.datalen) {
10024          if (f.frametype == AST_FRAME_IAX) {
10025             if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
10026                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
10027                ast_variables_destroy(ies.vars);
10028                return 1;
10029             }
10030             f.data.ptr = NULL;
10031             f.datalen = 0;
10032          } else {
10033             f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
10034             memset(&ies, 0, sizeof(ies));
10035          }
10036       } else {
10037          if (f.frametype == AST_FRAME_IAX)
10038             f.data.ptr = NULL;
10039          else
10040             f.data.ptr = empty;
10041          memset(&ies, 0, sizeof(ies));
10042       }
10043 
10044       if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
10045          /* only set NEW_ALLOW if calltoken checks out */
10046          if (handle_call_token(fh, &ies, &sin, fd)) {
10047             ast_variables_destroy(ies.vars);
10048             return 1;
10049          }
10050 
10051          if (ies.calltoken && ies.calltokendata) {
10052             /* if we've gotten this far, and the calltoken ie data exists,
10053              * then calltoken validation _MUST_ have taken place.  If calltoken
10054              * data is provided, it is always validated reguardless of any
10055              * calltokenoptional or requirecalltoken options */
10056             new = NEW_ALLOW_CALLTOKEN_VALIDATED;
10057          } else {
10058             new = NEW_ALLOW;
10059          }
10060       }
10061    } else {
10062       /* Don't know anything about it yet */
10063       f.frametype = AST_FRAME_NULL;
10064       f.subclass.integer = 0;
10065       memset(&ies, 0, sizeof(ies));
10066    }
10067 
10068    if (!fr->callno) {
10069       int check_dcallno = 0;
10070 
10071       /*
10072        * We enforce accurate destination call numbers for ACKs.  This forces the other
10073        * end to know the destination call number before call setup can complete.
10074        *
10075        * Discussed in the following thread:
10076        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
10077        */
10078 
10079       if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10080          check_dcallno = 1;
10081       }
10082 
10083       if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
10084          if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
10085             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10086          } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
10087             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10088          }
10089          ast_variables_destroy(ies.vars);
10090          return 1;
10091       }
10092    }
10093 
10094    if (fr->callno > 0)
10095       ast_mutex_lock(&iaxsl[fr->callno]);
10096 
10097    if (!fr->callno || !iaxs[fr->callno]) {
10098       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
10099          frame, reply with an inval */
10100       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10101          /* We can only raw hangup control frames */
10102          if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10103              (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10104              (f.subclass.integer != IAX_COMMAND_TXACC) &&
10105              (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
10106              (f.frametype != AST_FRAME_IAX))
10107             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10108             fd);
10109       }
10110       if (fr->callno > 0) 
10111          ast_mutex_unlock(&iaxsl[fr->callno]);
10112       ast_variables_destroy(ies.vars);
10113       return 1;
10114    }
10115    if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10116       if (decrypt_frame(fr->callno, fh, &f, &res)) {
10117          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10118          ast_variables_destroy(ies.vars);
10119          ast_mutex_unlock(&iaxsl[fr->callno]);
10120          return 1;
10121       }
10122       decrypted = 1;
10123    }
10124 
10125 #ifdef DEBUG_SUPPORT
10126    if (decrypted) {
10127       iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10128    }
10129 #endif
10130 
10131 
10132    /* count this frame */
10133    iaxs[fr->callno]->frames_received++;
10134 
10135    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10136       f.subclass.integer != IAX_COMMAND_TXCNT &&      /* for attended transfer */
10137       f.subclass.integer != IAX_COMMAND_TXACC) {      /* for attended transfer */
10138       unsigned short new_peercallno;
10139       
10140       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10141       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10142          if (iaxs[fr->callno]->peercallno) {
10143             remove_by_peercallno(iaxs[fr->callno]);
10144          }
10145          iaxs[fr->callno]->peercallno = new_peercallno;
10146          store_by_peercallno(iaxs[fr->callno]);
10147       }
10148    }
10149    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10150       if (iaxdebug)
10151          ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10152       /* Check if it's out of order (and not an ACK or INVAL) */
10153       fr->oseqno = fh->oseqno;
10154       fr->iseqno = fh->iseqno;
10155       fr->ts = ntohl(fh->ts);
10156 #ifdef IAXTESTS
10157       if (test_resync) {
10158          ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10159          fr->ts += test_resync;
10160       }
10161 #endif /* IAXTESTS */
10162 #if 0
10163       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10164            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10165                         (f.subclass == IAX_COMMAND_NEW ||
10166                          f.subclass == IAX_COMMAND_AUTHREQ ||
10167                          f.subclass == IAX_COMMAND_ACCEPT ||
10168                          f.subclass == IAX_COMMAND_REJECT))      ) )
10169 #endif
10170       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10171          updatehistory = 0;
10172       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10173          (iaxs[fr->callno]->iseqno ||
10174             ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10175             (f.subclass.integer != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
10176             (f.subclass.integer != IAX_COMMAND_TXREL) &&    /* for attended transfer */
10177             (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
10178             (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10179             (f.frametype != AST_FRAME_IAX))) {
10180          if (
10181           ((f.subclass.integer != IAX_COMMAND_ACK) &&
10182            (f.subclass.integer != IAX_COMMAND_INVAL) &&
10183            (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10184            (f.subclass.integer != IAX_COMMAND_TXREADY) &&      /* for attended transfer */
10185            (f.subclass.integer != IAX_COMMAND_TXREL) &&     /* for attended transfer */
10186            (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
10187            (f.subclass.integer != IAX_COMMAND_TXACC) &&
10188            (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10189            (f.frametype != AST_FRAME_IAX)) {
10190             /* If it's not an ACK packet, it's out of order. */
10191             ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
10192                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10193             /* Check to see if we need to request retransmission,
10194              * and take sequence number wraparound into account */
10195             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10196                /* If we've already seen it, ack it XXX There's a border condition here XXX */
10197                if ((f.frametype != AST_FRAME_IAX) || 
10198                      ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10199                   ast_debug(1, "Acking anyway\n");
10200                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
10201                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
10202                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10203                }
10204             } else {
10205                /* Send a VNAK requesting retransmission */
10206                iax2_vnak(fr->callno);
10207             }
10208             ast_variables_destroy(ies.vars);
10209             ast_mutex_unlock(&iaxsl[fr->callno]);
10210             return 1;
10211          }
10212       } else {
10213          /* Increment unless it's an ACK or VNAK */
10214          if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10215              (f.subclass.integer != IAX_COMMAND_INVAL) &&
10216              (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10217              (f.subclass.integer != IAX_COMMAND_TXACC) &&
10218             (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10219              (f.frametype != AST_FRAME_IAX))
10220             iaxs[fr->callno]->iseqno++;
10221       }
10222       /* Ensure text frames are NULL-terminated */
10223       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10224          if (res < thread->buf_size)
10225             thread->buf[res++] = '\0';
10226          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
10227             thread->buf[res - 1] = '\0';
10228       }
10229 
10230       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
10231          from the real peer, not the transfer peer */
10232       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
10233           ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10234            (f.frametype != AST_FRAME_IAX))) {
10235          unsigned char x;
10236          int call_to_destroy;
10237          /* First we have to qualify that the ACKed value is within our window */
10238          if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10239             x = fr->iseqno;
10240          else 
10241             x = iaxs[fr->callno]->oseqno;
10242          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10243             /* The acknowledgement is within our window.  Time to acknowledge everything
10244                that it says to */
10245             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10246                /* Ack the packet with the given timestamp */
10247                if (iaxdebug)
10248                   ast_debug(1, "Cancelling transmission of packet %d\n", x);
10249                call_to_destroy = 0;
10250                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10251                   /* If it's our call, and our timestamp, mark -1 retries */
10252                   if (x == cur->oseqno) {
10253                      cur->retries = -1;
10254                      /* Destroy call if this is the end */
10255                      if (cur->final)
10256                         call_to_destroy = fr->callno;
10257                   }
10258                }
10259                if (call_to_destroy) {
10260                   if (iaxdebug)
10261                      ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10262                   ast_mutex_lock(&iaxsl[call_to_destroy]);
10263                   iax2_destroy(call_to_destroy);
10264                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
10265                }
10266             }
10267             /* Note how much we've received acknowledgement for */
10268             if (iaxs[fr->callno])
10269                iaxs[fr->callno]->rseqno = fr->iseqno;
10270             else {
10271                /* Stop processing now */
10272                ast_variables_destroy(ies.vars);
10273                ast_mutex_unlock(&iaxsl[fr->callno]);
10274                return 1;
10275             }
10276          } else {
10277             ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10278          }
10279       }
10280       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
10281          ((f.frametype != AST_FRAME_IAX) || 
10282           ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10283            (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10284          /* Only messages we accept from a transfer host are TXACC and TXCNT */
10285          ast_variables_destroy(ies.vars);
10286          ast_mutex_unlock(&iaxsl[fr->callno]);
10287          return 1;
10288       }
10289 
10290       /* when we receive the first full frame for a new incoming channel,
10291          it is safe to start the PBX on the channel because we have now
10292          completed a 3-way handshake with the peer */
10293       if ((f.frametype == AST_FRAME_VOICE) ||
10294           (f.frametype == AST_FRAME_VIDEO) ||
10295           (f.frametype == AST_FRAME_IAX)) {
10296          if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10297             ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10298             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL,
10299                     ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) {
10300                ast_variables_destroy(ies.vars);
10301                ast_mutex_unlock(&iaxsl[fr->callno]);
10302                return 1;
10303             }
10304          }
10305 
10306          if (ies.vars) {
10307             struct ast_datastore *variablestore = NULL;
10308             struct ast_variable *var, *prev = NULL;
10309             AST_LIST_HEAD(, ast_var_t) *varlist;
10310 
10311             iax2_lock_owner(fr->callno);
10312             if (!iaxs[fr->callno]) {
10313                ast_variables_destroy(ies.vars);
10314                ast_mutex_unlock(&iaxsl[fr->callno]);
10315                return 1;
10316             }
10317             if ((c = iaxs[fr->callno]->owner)) {
10318                varlist = ast_calloc(1, sizeof(*varlist));
10319                variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10320 
10321                if (variablestore && varlist) {
10322                   variablestore->data = varlist;
10323                   variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10324                   AST_LIST_HEAD_INIT(varlist);
10325                   ast_debug(1, "I can haz IAX vars?\n");
10326                   for (var = ies.vars; var; var = var->next) {
10327                      struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10328                      if (prev) {
10329                         ast_free(prev);
10330                      }
10331                      prev = var;
10332                      if (!newvar) {
10333                         /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
10334                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10335                      } else {
10336                         AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10337                      }
10338                   }
10339                   if (prev) {
10340                      ast_free(prev);
10341                   }
10342                   ies.vars = NULL;
10343                   ast_channel_datastore_add(c, variablestore);
10344                } else {
10345                   ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10346                   if (variablestore) {
10347                      ast_datastore_free(variablestore);
10348                   }
10349                   if (varlist) {
10350                      ast_free(varlist);
10351                   }
10352                }
10353                ast_channel_unlock(c);
10354             } else {
10355                /* No channel yet, so transfer the variables directly over to the pvt,
10356                 * for later inheritance. */
10357                ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10358                for (var = ies.vars; var && var->next; var = var->next);
10359                if (var) {
10360                   var->next = iaxs[fr->callno]->iaxvars;
10361                   iaxs[fr->callno]->iaxvars = ies.vars;
10362                   ies.vars = NULL;
10363                }
10364             }
10365          }
10366 
10367          if (ies.vars) {
10368             ast_debug(1, "I have IAX variables, but they were not processed\n");
10369          }
10370       }
10371 
10372       /* once we receive our first IAX Full Frame that is not CallToken related, send all
10373        * queued signaling frames that were being held. */
10374       if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10375          send_signaling(iaxs[fr->callno]);
10376       }
10377 
10378       if (f.frametype == AST_FRAME_VOICE) {
10379          if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10380                iaxs[fr->callno]->voiceformat = f.subclass.codec;
10381                ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10382                if (iaxs[fr->callno]->owner) {
10383                   iax2_lock_owner(fr->callno);
10384                   if (iaxs[fr->callno]) {
10385                      if (iaxs[fr->callno]->owner) {
10386                         format_t orignative;
10387 
10388                         orignative = iaxs[fr->callno]->owner->nativeformats;
10389                         iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10390                         if (iaxs[fr->callno]->owner->readformat)
10391                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10392                         iaxs[fr->callno]->owner->nativeformats = orignative;
10393                         ast_channel_unlock(iaxs[fr->callno]->owner);
10394                      }
10395                   } else {
10396                      ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10397                      /* Free remote variables (if any) */
10398                      if (ies.vars) {
10399                         ast_variables_destroy(ies.vars);
10400                         ast_debug(1, "I can haz iaxvars, but they is no good.  :-(\n");
10401                         ies.vars = NULL;
10402                      }
10403                      ast_mutex_unlock(&iaxsl[fr->callno]);
10404                      return 1;
10405                   }
10406                }
10407          }
10408       }
10409       if (f.frametype == AST_FRAME_VIDEO) {
10410          if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10411             ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10412             iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10413          }
10414       }
10415       if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10416          if (f.subclass.integer == AST_CONTROL_BUSY) {
10417             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10418          } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
10419             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10420          }
10421       }
10422       if (f.frametype == AST_FRAME_IAX) {
10423          ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10424          /* Handle the IAX pseudo frame itself */
10425          if (iaxdebug)
10426             ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10427 
10428                         /* Update last ts unless the frame's timestamp originated with us. */
10429          if (iaxs[fr->callno]->last < fr->ts &&
10430                             f.subclass.integer != IAX_COMMAND_ACK &&
10431                             f.subclass.integer != IAX_COMMAND_PONG &&
10432                             f.subclass.integer != IAX_COMMAND_LAGRP) {
10433             iaxs[fr->callno]->last = fr->ts;
10434             if (iaxdebug)
10435                ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10436          }
10437          iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10438          if (!iaxs[fr->callno]->first_iax_message) {
10439             iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10440          }
10441          switch(f.subclass.integer) {
10442          case IAX_COMMAND_ACK:
10443             /* Do nothing */
10444             break;
10445          case IAX_COMMAND_QUELCH:
10446             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10447                     /* Generate Manager Hold event, if necessary*/
10448                if (iaxs[fr->callno]->owner) {
10449                   ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10450                      "Status: On\r\n"
10451                      "Channel: %s\r\n"
10452                      "Uniqueid: %s\r\n",
10453                      iaxs[fr->callno]->owner->name,
10454                      iaxs[fr->callno]->owner->uniqueid);
10455                }
10456 
10457                ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10458                if (ies.musiconhold) {
10459                   iax2_lock_owner(fr->callno);
10460                   if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10461                      break;
10462                   }
10463                   if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10464                      const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10465 
10466                      /*
10467                       * We already hold the owner lock so we do not
10468                       * need to check iaxs[fr->callno] after it returns.
10469                       */
10470                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
10471                         S_OR(moh_suggest, NULL),
10472                         !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10473                   }
10474                   ast_channel_unlock(iaxs[fr->callno]->owner);
10475                }
10476             }
10477             break;
10478          case IAX_COMMAND_UNQUELCH:
10479             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10480                iax2_lock_owner(fr->callno);
10481                if (!iaxs[fr->callno]) {
10482                   break;
10483                }
10484                /* Generate Manager Unhold event, if necessary */
10485                if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10486                   ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10487                      "Status: Off\r\n"
10488                      "Channel: %s\r\n"
10489                      "Uniqueid: %s\r\n",
10490                      iaxs[fr->callno]->owner->name,
10491                      iaxs[fr->callno]->owner->uniqueid);
10492                }
10493 
10494                ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10495                if (!iaxs[fr->callno]->owner) {
10496                   break;
10497                }
10498                if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10499                   /*
10500                    * We already hold the owner lock so we do not
10501                    * need to check iaxs[fr->callno] after it returns.
10502                    */
10503                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10504                }
10505                ast_channel_unlock(iaxs[fr->callno]->owner);
10506             }
10507             break;
10508          case IAX_COMMAND_TXACC:
10509             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10510                /* Ack the packet with the given timestamp */
10511                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10512                   /* Cancel any outstanding txcnt's */
10513                   if (cur->transfer) {
10514                      cur->retries = -1;
10515                   }
10516                }
10517                memset(&ied1, 0, sizeof(ied1));
10518                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10519                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10520                iaxs[fr->callno]->transferring = TRANSFER_READY;
10521             }
10522             break;
10523          case IAX_COMMAND_NEW:
10524             /* Ignore if it's already up */
10525             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10526                break;
10527             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10528                ast_mutex_unlock(&iaxsl[fr->callno]);
10529                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10530                ast_mutex_lock(&iaxsl[fr->callno]);
10531                if (!iaxs[fr->callno]) {
10532                   break;
10533                }
10534             }
10535             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
10536             if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10537                int new_callno;
10538                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10539                   fr->callno = new_callno;
10540             }
10541             /* For security, always ack immediately */
10542             if (delayreject)
10543                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10544             if (check_access(fr->callno, &sin, &ies)) {
10545                /* They're not allowed on */
10546                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10547                if (authdebug)
10548                   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);
10549                break;
10550             }
10551             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10552                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10553                ast_log(LOG_WARNING, "Rejected connect attempt.  No secret present while force encrypt enabled.\n");
10554                break;
10555             }
10556             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10557                const char *context, *exten, *cid_num;
10558 
10559                context = ast_strdupa(iaxs[fr->callno]->context);
10560                exten = ast_strdupa(iaxs[fr->callno]->exten);
10561                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10562 
10563                /* This might re-enter the IAX code and need the lock */
10564                ast_mutex_unlock(&iaxsl[fr->callno]);
10565                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10566                ast_mutex_lock(&iaxsl[fr->callno]);
10567 
10568                if (!iaxs[fr->callno]) {
10569                   break;
10570                }
10571             } else
10572                exists = 0;
10573             /* Get OSP token if it does exist */
10574             save_osptoken(fr, &ies);
10575             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10576                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10577                   memset(&ied0, 0, sizeof(ied0));
10578                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10579                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10580                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10581                   if (!iaxs[fr->callno]) {
10582                      break;
10583                   }
10584                   if (authdebug)
10585                      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);
10586                } else {
10587                   /* Select an appropriate format */
10588 
10589                   if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10590                      if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10591                         using_prefs = "reqonly";
10592                      } else {
10593                         using_prefs = "disabled";
10594                      }
10595                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10596                      memset(&pref, 0, sizeof(pref));
10597                      strcpy(caller_pref_buf, "disabled");
10598                      strcpy(host_pref_buf, "disabled");
10599                   } else {
10600                      using_prefs = "mine";
10601                      /* If the information elements are in here... use them */
10602                      if (ies.codec_prefs)
10603                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10604                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10605                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
10606                         if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10607                            pref = iaxs[fr->callno]->rprefs;
10608                            using_prefs = "caller";
10609                         } else {
10610                            pref = iaxs[fr->callno]->prefs;
10611                         }
10612                      } else
10613                         pref = iaxs[fr->callno]->prefs;
10614 
10615                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10616                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10617                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10618                   }
10619                   if (!format) {
10620                      if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10621                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10622                      if (!format) {
10623                         memset(&ied0, 0, sizeof(ied0));
10624                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10625                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10626                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10627                         if (!iaxs[fr->callno]) {
10628                            break;
10629                         }
10630                         if (authdebug) {
10631                            char tmp[256], tmp2[256], tmp3[256];
10632                            if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10633                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10634                                  ast_inet_ntoa(sin.sin_addr),
10635                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10636                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10637                            } else {
10638                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10639                                  ast_inet_ntoa(sin.sin_addr),
10640                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10641                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10642                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10643                            }
10644                         }
10645                      } else {
10646                         /* Pick one... */
10647                         if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10648                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10649                               format = 0;
10650                         } else {
10651                            if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10652                               using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10653                               memset(&pref, 0, sizeof(pref));
10654                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10655                               strcpy(caller_pref_buf,"disabled");
10656                               strcpy(host_pref_buf,"disabled");
10657                            } else {
10658                               using_prefs = "mine";
10659                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10660                                  /* Do the opposite of what we tried above. */
10661                                  if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10662                                     pref = iaxs[fr->callno]->prefs;
10663                                  } else {
10664                                     pref = iaxs[fr->callno]->rprefs;
10665                                     using_prefs = "caller";
10666                                  }
10667                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10668                               } else /* if no codec_prefs IE do it the old way */
10669                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10670                            }
10671                         }
10672 
10673                         if (!format) {
10674                            char tmp[256], tmp2[256], tmp3[256];
10675                            memset(&ied0, 0, sizeof(ied0));
10676                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10677                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10678                            ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10679                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10680                            if (!iaxs[fr->callno]) {
10681                               break;
10682                            }
10683                            if (authdebug) {
10684                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10685                                  ast_inet_ntoa(sin.sin_addr),
10686                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10687                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10688                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10689                            }
10690                            ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10691                            break;
10692                         }
10693                      }
10694                   }
10695                   if (format) {
10696                      /* No authentication required, let them in */
10697                      memset(&ied1, 0, sizeof(ied1));
10698                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10699                      iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10700                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10701                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10702                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10703                         ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10704                                     "%srequested format = %s,\n"
10705                                     "%srequested prefs = %s,\n"
10706                                     "%sactual format = %s,\n"
10707                                     "%shost prefs = %s,\n"
10708                                     "%spriority = %s\n",
10709                                     ast_inet_ntoa(sin.sin_addr), 
10710                                     VERBOSE_PREFIX_4,
10711                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
10712                                     VERBOSE_PREFIX_4,
10713                                     caller_pref_buf,
10714                                     VERBOSE_PREFIX_4,
10715                                     ast_getformatname(format), 
10716                                     VERBOSE_PREFIX_4,
10717                                     host_pref_buf, 
10718                                     VERBOSE_PREFIX_4,
10719                                     using_prefs);
10720 
10721                         iaxs[fr->callno]->chosenformat = format;
10722                         ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10723                      } else {
10724                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10725                         /* If this is a TBD call, we're ready but now what...  */
10726                         ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10727                      }
10728                   }
10729                }
10730                break;
10731             }
10732             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10733                merge_encryption(iaxs[fr->callno],ies.encmethods);
10734             else
10735                iaxs[fr->callno]->encmethods = 0;
10736             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10737                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10738             break;
10739          case IAX_COMMAND_DPREQ:
10740             /* Request status in the dialplan */
10741             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10742                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10743                if (iaxcompat) {
10744                   /* Spawn a thread for the lookup */
10745                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10746                } else {
10747                   /* Just look it up */
10748                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10749                }
10750             }
10751             break;
10752          case IAX_COMMAND_HANGUP:
10753             ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10754             ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10755             /* Set hangup cause according to remote and hangupsource */
10756             if (iaxs[fr->callno]->owner) {
10757                set_hangup_source_and_cause(fr->callno, ies.causecode);
10758                if (!iaxs[fr->callno]) {
10759                   break;
10760                }
10761             }
10762 
10763             /* Send ack immediately, before we destroy */
10764             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10765             iax2_destroy(fr->callno);
10766             break;
10767          case IAX_COMMAND_REJECT:
10768             /* Set hangup cause according to remote and hangup source */
10769             if (iaxs[fr->callno]->owner) {
10770                set_hangup_source_and_cause(fr->callno, ies.causecode);
10771                if (!iaxs[fr->callno]) {
10772                   break;
10773                }
10774             }
10775 
10776             if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10777                if (iaxs[fr->callno]->owner && authdebug)
10778                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10779                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10780                      ies.cause ? ies.cause : "<Unknown>");
10781                ast_debug(1, "Immediately destroying %d, having received reject\n",
10782                   fr->callno);
10783             }
10784             /* Send ack immediately, before we destroy */
10785             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10786                          fr->ts, NULL, 0, fr->iseqno);
10787             if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10788                iaxs[fr->callno]->error = EPERM;
10789             iax2_destroy(fr->callno);
10790             break;
10791          case IAX_COMMAND_TRANSFER:
10792          {
10793             struct ast_channel *bridged_chan;
10794             struct ast_channel *owner;
10795 
10796             iax2_lock_owner(fr->callno);
10797             if (!iaxs[fr->callno]) {
10798                /* Initiating call went away before we could transfer. */
10799                break;
10800             }
10801             owner = iaxs[fr->callno]->owner;
10802             bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10803             if (bridged_chan && ies.called_number) {
10804                const char *context;
10805 
10806                context = ast_strdupa(iaxs[fr->callno]->context);
10807 
10808                ast_channel_ref(owner);
10809                ast_channel_ref(bridged_chan);
10810                ast_channel_unlock(owner);
10811                ast_mutex_unlock(&iaxsl[fr->callno]);
10812 
10813                /* Set BLINDTRANSFER channel variables */
10814                pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10815                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10816 
10817                /* DO NOT hold any locks while calling ast_parking_ext_valid() */
10818                if (ast_parking_ext_valid(ies.called_number, owner, context)) {
10819                   ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10820                   if (iax_park(bridged_chan, owner, ies.called_number, context)) {
10821                      ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10822                         bridged_chan->name);
10823                   }
10824                } else {
10825                   if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) {
10826                      ast_log(LOG_WARNING,
10827                         "Async goto of '%s' to '%s@%s' failed\n",
10828                         bridged_chan->name, ies.called_number, context);
10829                   } else {
10830                      ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10831                         bridged_chan->name, ies.called_number, context);
10832                   }
10833                }
10834                ast_channel_unref(owner);
10835                ast_channel_unref(bridged_chan);
10836 
10837                ast_mutex_lock(&iaxsl[fr->callno]);
10838             } else {
10839                ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10840                if (owner) {
10841                   ast_channel_unlock(owner);
10842                }
10843             }
10844 
10845             break;
10846          }
10847          case IAX_COMMAND_ACCEPT:
10848             /* Ignore if call is already up or needs authentication or is a TBD */
10849             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10850                break;
10851             if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10852                /* Send ack immediately, before we destroy */
10853                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10854                iax2_destroy(fr->callno);
10855                break;
10856             }
10857             if (ies.format) {
10858                iaxs[fr->callno]->peerformat = ies.format;
10859             } else {
10860                if (iaxs[fr->callno]->owner)
10861                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10862                else
10863                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10864             }
10865             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));
10866             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10867                memset(&ied0, 0, sizeof(ied0));
10868                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10869                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10870                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10871                if (!iaxs[fr->callno]) {
10872                   break;
10873                }
10874                if (authdebug) {
10875                   char tmp1[256], tmp2[256];
10876                   ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
10877                      ast_inet_ntoa(sin.sin_addr),
10878                      ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10879                      ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10880                }
10881             } else {
10882                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10883                iax2_lock_owner(fr->callno);
10884                if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10885                   /* Switch us to use a compatible format */
10886                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10887                   ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10888 
10889                   /* Setup read/write formats properly. */
10890                   if (iaxs[fr->callno]->owner->writeformat)
10891                      ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
10892                   if (iaxs[fr->callno]->owner->readformat)
10893                      ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
10894                   ast_channel_unlock(iaxs[fr->callno]->owner);
10895                }
10896             }
10897             if (iaxs[fr->callno]) {
10898                AST_LIST_LOCK(&dpcache);
10899                AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10900                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10901                      iax2_dprequest(dp, fr->callno);
10902                AST_LIST_UNLOCK(&dpcache);
10903             }
10904             break;
10905          case IAX_COMMAND_POKE:
10906             /* Send back a pong packet with the original timestamp */
10907             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10908             break;
10909          case IAX_COMMAND_PING:
10910          {
10911             struct iax_ie_data pingied;
10912             construct_rr(iaxs[fr->callno], &pingied);
10913             /* Send back a pong packet with the original timestamp */
10914             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10915          }
10916             break;
10917          case IAX_COMMAND_PONG:
10918             /* Calculate ping time */
10919             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10920             /* save RR info */
10921             save_rr(fr, &ies);
10922 
10923             /* Good time to write jb stats for this call */
10924             log_jitterstats(fr->callno);
10925 
10926             if (iaxs[fr->callno]->peerpoke) {
10927                peer = iaxs[fr->callno]->peerpoke;
10928                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
10929                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10930                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10931                      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); 
10932                      ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
10933                   }
10934                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10935                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
10936                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10937                      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); 
10938                      ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
10939                   }
10940                }
10941                peer->lastms = iaxs[fr->callno]->pingtime;
10942                if (peer->smoothing && (peer->lastms > -1))
10943                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10944                else if (peer->smoothing && peer->lastms < 0)
10945                   peer->historicms = (0 + peer->historicms) / 2;
10946                else              
10947                   peer->historicms = iaxs[fr->callno]->pingtime;
10948 
10949                /* Remove scheduled iax2_poke_noanswer */
10950                if (peer->pokeexpire > -1) {
10951                   if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10952                      peer_unref(peer);
10953                      peer->pokeexpire = -1;
10954                   }
10955                }
10956                /* Schedule the next cycle */
10957                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
10958                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10959                else
10960                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10961                if (peer->pokeexpire == -1)
10962                   peer_unref(peer);
10963                /* and finally send the ack */
10964                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10965                /* And wrap up the qualify call */
10966                iax2_destroy(fr->callno);
10967                peer->callno = 0;
10968                ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10969             }
10970             break;
10971          case IAX_COMMAND_LAGRQ:
10972          case IAX_COMMAND_LAGRP:
10973             f.src = "LAGRQ";
10974             f.mallocd = 0;
10975             f.offset = 0;
10976             f.samples = 0;
10977             iax_frame_wrap(fr, &f);
10978             if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
10979                /* Received a LAGRQ - echo back a LAGRP */
10980                fr->af.subclass.integer = IAX_COMMAND_LAGRP;
10981                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10982             } else {
10983                /* Received LAGRP in response to our LAGRQ */
10984                unsigned int ts;
10985                /* This is a reply we've been given, actually measure the difference */
10986                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10987                iaxs[fr->callno]->lag = ts - fr->ts;
10988                if (iaxdebug)
10989                   ast_debug(1, "Peer %s lag measured as %dms\n",
10990                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10991             }
10992             break;
10993          case IAX_COMMAND_AUTHREQ:
10994             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10995                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>");
10996                break;
10997             }
10998             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10999                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
11000                         .subclass.integer = AST_CONTROL_HANGUP,
11001                };
11002                ast_log(LOG_WARNING, 
11003                   "I don't know how to authenticate %s to %s\n", 
11004                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
11005                iax2_queue_frame(fr->callno, &hangup_fr);
11006             }
11007             break;
11008          case IAX_COMMAND_AUTHREP:
11009             /* For security, always ack immediately */
11010             if (delayreject)
11011                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11012             /* Ignore once we've started */
11013             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11014                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>");
11015                break;
11016             }
11017             if (authenticate_verify(iaxs[fr->callno], &ies)) {
11018                if (authdebug)
11019                   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);
11020                memset(&ied0, 0, sizeof(ied0));
11021                auth_fail(fr->callno, IAX_COMMAND_REJECT);
11022                break;
11023             }
11024             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
11025                /* This might re-enter the IAX code and need the lock */
11026                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
11027             } else
11028                exists = 0;
11029             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
11030                if (authdebug)
11031                   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);
11032                memset(&ied0, 0, sizeof(ied0));
11033                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11034                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11035                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11036                if (!iaxs[fr->callno]) {
11037                   break;
11038                }
11039             } else {
11040                /* Select an appropriate format */
11041                if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11042                   if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11043                      using_prefs = "reqonly";
11044                   } else {
11045                      using_prefs = "disabled";
11046                   }
11047                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
11048                   memset(&pref, 0, sizeof(pref));
11049                   strcpy(caller_pref_buf, "disabled");
11050                   strcpy(host_pref_buf, "disabled");
11051                } else {
11052                   using_prefs = "mine";
11053                   if (ies.codec_prefs)
11054                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11055                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11056                      if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11057                         pref = iaxs[fr->callno]->rprefs;
11058                         using_prefs = "caller";
11059                      } else {
11060                         pref = iaxs[fr->callno]->prefs;
11061                      }
11062                   } else /* if no codec_prefs IE do it the old way */
11063                      pref = iaxs[fr->callno]->prefs;
11064                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
11065                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11066                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11067                }
11068                if (!format) {
11069                   char tmp1[256], tmp2[256], tmp3[256];
11070                   if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11071                      ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11072                         ast_getformatname(iaxs[fr->callno]->peerformat),
11073                         ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
11074                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11075                   }
11076                   if (!format) {
11077                      if (authdebug) {
11078                         if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11079                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
11080                               ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11081                               ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11082                         } else {
11083                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11084                               ast_inet_ntoa(sin.sin_addr),
11085                               ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11086                               ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11087                               ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11088                         }
11089                      }
11090                      memset(&ied0, 0, sizeof(ied0));
11091                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11092                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11093                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11094                      if (!iaxs[fr->callno]) {
11095                         break;
11096                      }
11097                   } else {
11098                      /* Pick one... */
11099                      if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11100                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11101                            format = 0;
11102                      } else {
11103                         if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11104                            using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11105                            memset(&pref, 0, sizeof(pref));
11106                            format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
11107                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11108                            strcpy(caller_pref_buf,"disabled");
11109                            strcpy(host_pref_buf,"disabled");
11110                         } else {
11111                            using_prefs = "mine";
11112                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11113                               /* Do the opposite of what we tried above. */
11114                               if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11115                                  pref = iaxs[fr->callno]->prefs;
11116                               } else {
11117                                  pref = iaxs[fr->callno]->rprefs;
11118                                  using_prefs = "caller";
11119                               }
11120                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11121                            } else /* if no codec_prefs IE do it the old way */
11122                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
11123                         }
11124                      }
11125                      if (!format) {
11126                         char tmp1[256], tmp2[256], tmp3[256];
11127                         ast_log(LOG_ERROR, "No best format in %s???\n",
11128                            ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11129                         if (authdebug) {
11130                            if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11131                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11132                                  ast_inet_ntoa(sin.sin_addr),
11133                                  ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11134                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11135                            } else {
11136                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11137                                  ast_inet_ntoa(sin.sin_addr),
11138                                  ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11139                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11140                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11141                            }
11142                         }
11143                         memset(&ied0, 0, sizeof(ied0));
11144                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11145                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11146                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11147                         if (!iaxs[fr->callno]) {
11148                            break;
11149                         }
11150                      }
11151                   }
11152                }
11153                if (format) {
11154                   /* Authentication received */
11155                   memset(&ied1, 0, sizeof(ied1));
11156                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11157                   iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11158                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11159                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11160                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11161                      ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11162                                  "%srequested format = %s,\n"
11163                                  "%srequested prefs = %s,\n"
11164                                  "%sactual format = %s,\n"
11165                                  "%shost prefs = %s,\n"
11166                                  "%spriority = %s\n", 
11167                                  ast_inet_ntoa(sin.sin_addr), 
11168                                  VERBOSE_PREFIX_4,
11169                                  ast_getformatname(iaxs[fr->callno]->peerformat),
11170                                  VERBOSE_PREFIX_4,
11171                                  caller_pref_buf,
11172                                  VERBOSE_PREFIX_4,
11173                                  ast_getformatname(format),
11174                                  VERBOSE_PREFIX_4,
11175                                  host_pref_buf,
11176                                  VERBOSE_PREFIX_4,
11177                                  using_prefs);
11178 
11179                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11180                      if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1)))
11181                         iax2_destroy(fr->callno);
11182                      else if (ies.vars) {
11183                         struct ast_datastore *variablestore;
11184                         struct ast_variable *var, *prev = NULL;
11185                         AST_LIST_HEAD(, ast_var_t) *varlist;
11186                         varlist = ast_calloc(1, sizeof(*varlist));
11187                         variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11188                         if (variablestore && varlist) {
11189                            variablestore->data = varlist;
11190                            variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11191                            AST_LIST_HEAD_INIT(varlist);
11192                            ast_debug(1, "I can haz IAX vars? w00t\n");
11193                            for (var = ies.vars; var; var = var->next) {
11194                               struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11195                               if (prev)
11196                                  ast_free(prev);
11197                               prev = var;
11198                               if (!newvar) {
11199                                  /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11200                                  ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11201                               } else {
11202                                  AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11203                               }
11204                            }
11205                            if (prev)
11206                               ast_free(prev);
11207                            ies.vars = NULL;
11208                            ast_channel_datastore_add(c, variablestore);
11209                         } else {
11210                            ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11211                            if (variablestore)
11212                               ast_datastore_free(variablestore);
11213                            if (varlist)
11214                               ast_free(varlist);
11215                         }
11216                      }
11217                   } else {
11218                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11219                      /* If this is a TBD call, we're ready but now what...  */
11220                      ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11221                      if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11222                         goto immediatedial;
11223                      }
11224                   }
11225                }
11226             }
11227             break;
11228          case IAX_COMMAND_DIAL:
11229 immediatedial:
11230             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11231                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11232                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11233                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11234                   if (authdebug)
11235                      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);
11236                   memset(&ied0, 0, sizeof(ied0));
11237                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11238                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11239                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11240                   if (!iaxs[fr->callno]) {
11241                      break;
11242                   }
11243                } else {
11244                   char tmp[256];
11245                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11246                   ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11247                      ast_inet_ntoa(sin.sin_addr),
11248                      ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11249                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11250                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11251                   if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1)))
11252                      iax2_destroy(fr->callno);
11253                   else if (ies.vars) {
11254                      struct ast_datastore *variablestore;
11255                      struct ast_variable *var, *prev = NULL;
11256                      AST_LIST_HEAD(, ast_var_t) *varlist;
11257                      varlist = ast_calloc(1, sizeof(*varlist));
11258                      variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11259                      ast_debug(1, "I can haz IAX vars? w00t\n");
11260                      if (variablestore && varlist) {
11261                         variablestore->data = varlist;
11262                         variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11263                         AST_LIST_HEAD_INIT(varlist);
11264                         for (var = ies.vars; var; var = var->next) {
11265                            struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11266                            if (prev)
11267                               ast_free(prev);
11268                            prev = var;
11269                            if (!newvar) {
11270                               /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11271                               ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11272                            } else {
11273                               AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11274                            }
11275                         }
11276                         if (prev)
11277                            ast_free(prev);
11278                         ies.vars = NULL;
11279                         ast_channel_datastore_add(c, variablestore);
11280                      } else {
11281                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11282                         if (variablestore)
11283                            ast_datastore_free(variablestore);
11284                         if (varlist)
11285                            ast_free(varlist);
11286                      }
11287                   }
11288                }
11289             }
11290             break;
11291          case IAX_COMMAND_INVAL:
11292             iaxs[fr->callno]->error = ENOTCONN;
11293             ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11294             iax2_destroy(fr->callno);
11295             ast_debug(1, "Destroying call %d\n", fr->callno);
11296             break;
11297          case IAX_COMMAND_VNAK:
11298             ast_debug(1, "Received VNAK: resending outstanding frames\n");
11299             /* Force retransmission */
11300             vnak_retransmit(fr->callno, fr->iseqno);
11301             break;
11302          case IAX_COMMAND_REGREQ:
11303          case IAX_COMMAND_REGREL:
11304             /* For security, always ack immediately */
11305             if (delayreject)
11306                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11307             if (register_verify(fr->callno, &sin, &ies)) {
11308                if (!iaxs[fr->callno]) {
11309                   break;
11310                }
11311                /* Send delayed failure */
11312                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11313                break;
11314             }
11315             if (!iaxs[fr->callno]) {
11316                break;
11317             }
11318             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11319                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11320 
11321                if (f.subclass.integer == IAX_COMMAND_REGREL) {
11322                   memset(&sin, 0, sizeof(sin));
11323                   sin.sin_family = AF_INET;
11324                }
11325                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11326                   ast_log(LOG_WARNING, "Registry error\n");
11327                }
11328                if (!iaxs[fr->callno]) {
11329                   break;
11330                }
11331                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11332                   ast_mutex_unlock(&iaxsl[fr->callno]);
11333                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11334                   ast_mutex_lock(&iaxsl[fr->callno]);
11335                }
11336                break;
11337             }
11338             registry_authrequest(fr->callno);
11339             break;
11340          case IAX_COMMAND_REGACK:
11341             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
11342                ast_log(LOG_WARNING, "Registration failure\n");
11343             /* Send ack immediately, before we destroy */
11344             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11345             iax2_destroy(fr->callno);
11346             break;
11347          case IAX_COMMAND_REGREJ:
11348             if (iaxs[fr->callno]->reg) {
11349                if (authdebug) {
11350                   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));
11351                   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>");
11352                }
11353                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11354             }
11355             /* Send ack immediately, before we destroy */
11356             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11357             iax2_destroy(fr->callno);
11358             break;
11359          case IAX_COMMAND_REGAUTH:
11360             /* Authentication request */
11361             if (registry_rerequest(&ies, fr->callno, &sin)) {
11362                memset(&ied0, 0, sizeof(ied0));
11363                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11364                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11365                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11366             }
11367             break;
11368          case IAX_COMMAND_TXREJ:
11369             iaxs[fr->callno]->transferring = 0;
11370             ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11371             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11372             if (iaxs[fr->callno]->bridgecallno) {
11373                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11374                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
11375                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11376                }
11377             }
11378             break;
11379          case IAX_COMMAND_TXREADY:
11380             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
11381                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
11382                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
11383                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11384                else
11385                   iaxs[fr->callno]->transferring = TRANSFER_READY;
11386                ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11387                if (iaxs[fr->callno]->bridgecallno) {
11388                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
11389                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
11390                      /* They're both ready, now release them. */
11391                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11392                         ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11393                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11394 
11395                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11396                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11397 
11398                         memset(&ied0, 0, sizeof(ied0));
11399                         memset(&ied1, 0, sizeof(ied1));
11400                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11401                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11402                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11403                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11404                      } else {
11405                         ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11406                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11407 
11408                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11409                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11410                         ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11411                         ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11412 
11413                         /* Stop doing lag & ping requests */
11414                         stop_stuff(fr->callno);
11415                         stop_stuff(iaxs[fr->callno]->bridgecallno);
11416 
11417                         memset(&ied0, 0, sizeof(ied0));
11418                         memset(&ied1, 0, sizeof(ied1));
11419                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11420                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11421                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11422                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11423                      }
11424 
11425                   }
11426                }
11427             }
11428             break;
11429          case IAX_COMMAND_TXREQ:
11430             try_transfer(iaxs[fr->callno], &ies);
11431             break;
11432          case IAX_COMMAND_TXCNT:
11433             if (iaxs[fr->callno]->transferring)
11434                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11435             break;
11436          case IAX_COMMAND_TXREL:
11437             /* Send ack immediately, rather than waiting until we've changed addresses */
11438             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11439             complete_transfer(fr->callno, &ies);
11440             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
11441             break;   
11442          case IAX_COMMAND_TXMEDIA:
11443             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11444                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11445                   /* Cancel any outstanding frames and start anew */
11446                   if (cur->transfer) {
11447                      cur->retries = -1;
11448                   }
11449                }
11450                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
11451                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11452             }
11453             break;
11454          case IAX_COMMAND_RTKEY:
11455             if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11456                ast_log(LOG_WARNING, 
11457                   "we've been told to rotate our encryption key, "
11458                   "but this isn't an encrypted call. bad things will happen.\n"
11459                );
11460                break;
11461             }
11462 
11463             IAX_DEBUGDIGEST("Receiving", ies.challenge);
11464 
11465             ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11466             break;
11467          case IAX_COMMAND_DPREP:
11468             complete_dpreply(iaxs[fr->callno], &ies);
11469             break;
11470          case IAX_COMMAND_UNSUPPORT:
11471             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11472             break;
11473          case IAX_COMMAND_FWDOWNL:
11474             /* Firmware download */
11475             if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11476                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11477                break;
11478             }
11479             memset(&ied0, 0, sizeof(ied0));
11480             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11481             if (res < 0)
11482                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11483             else if (res > 0)
11484                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11485             else
11486                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11487             break;
11488          case IAX_COMMAND_CALLTOKEN:
11489          {
11490             struct iax_frame *cur;
11491             /* find last sent frame */
11492             if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11493                resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11494             }
11495             break;
11496          }
11497          default:
11498             ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11499             memset(&ied0, 0, sizeof(ied0));
11500             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11501             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11502          }
11503          /* Free remote variables (if any) */
11504          if (ies.vars) {
11505             ast_variables_destroy(ies.vars);
11506             ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11507             ies.vars = NULL;
11508          }
11509 
11510          /* Don't actually pass these frames along */
11511          if ((f.subclass.integer != IAX_COMMAND_ACK) && 
11512            (f.subclass.integer != IAX_COMMAND_TXCNT) && 
11513            (f.subclass.integer != IAX_COMMAND_TXACC) && 
11514            (f.subclass.integer != IAX_COMMAND_INVAL) &&
11515            (f.subclass.integer != IAX_COMMAND_VNAK)) { 
11516             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11517                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11518          }
11519          ast_mutex_unlock(&iaxsl[fr->callno]);
11520          return 1;
11521       }
11522       /* Unless this is an ACK or INVAL frame, ack it */
11523       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11524          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11525    } else if (minivid) {
11526       f.frametype = AST_FRAME_VIDEO;
11527       if (iaxs[fr->callno]->videoformat > 0) 
11528          f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11529       else {
11530          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11531          iax2_vnak(fr->callno);
11532          ast_variables_destroy(ies.vars);
11533          ast_mutex_unlock(&iaxsl[fr->callno]);
11534          return 1;
11535       }
11536       f.datalen = res - sizeof(*vh);
11537       if (f.datalen)
11538          f.data.ptr = thread->buf + sizeof(*vh);
11539       else
11540          f.data.ptr = NULL;
11541 #ifdef IAXTESTS
11542       if (test_resync) {
11543          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11544       } else
11545 #endif /* IAXTESTS */
11546          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11547    } else {
11548       /* A mini frame */
11549       f.frametype = AST_FRAME_VOICE;
11550       if (iaxs[fr->callno]->voiceformat > 0)
11551          f.subclass.codec = iaxs[fr->callno]->voiceformat;
11552       else {
11553          ast_debug(1, "Received mini frame before first full voice frame\n");
11554          iax2_vnak(fr->callno);
11555          ast_variables_destroy(ies.vars);
11556          ast_mutex_unlock(&iaxsl[fr->callno]);
11557          return 1;
11558       }
11559       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11560       if (f.datalen < 0) {
11561          ast_log(LOG_WARNING, "Datalen < 0?\n");
11562          ast_variables_destroy(ies.vars);
11563          ast_mutex_unlock(&iaxsl[fr->callno]);
11564          return 1;
11565       }
11566       if (f.datalen)
11567          f.data.ptr = thread->buf + sizeof(*mh);
11568       else
11569          f.data.ptr = NULL;
11570 #ifdef IAXTESTS
11571       if (test_resync) {
11572          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11573       } else
11574 #endif /* IAXTESTS */
11575       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11576       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
11577    }
11578    /* Don't pass any packets until we're started */
11579    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11580       ast_variables_destroy(ies.vars);
11581       ast_mutex_unlock(&iaxsl[fr->callno]);
11582       return 1;
11583    }
11584    /* Don't allow connected line updates unless we are configured to */
11585    if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) {
11586       struct ast_party_connected_line connected;
11587 
11588       if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11589          ast_variables_destroy(ies.vars);
11590          ast_mutex_unlock(&iaxsl[fr->callno]);
11591          return 1;
11592       }
11593 
11594       /* Initialize defaults */
11595       ast_party_connected_line_init(&connected);
11596       connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11597       connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11598 
11599       if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11600          ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11601          ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11602          iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11603 
11604          iax2_lock_owner(fr->callno);
11605          if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
11606             ast_set_callerid(iaxs[fr->callno]->owner,
11607                S_COR(connected.id.number.valid, connected.id.number.str, ""),
11608                S_COR(connected.id.name.valid, connected.id.name.str, ""),
11609                NULL);
11610             iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11611             iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11612             ast_channel_unlock(iaxs[fr->callno]->owner);
11613          }
11614       }
11615       ast_party_connected_line_free(&connected);
11616    }
11617    /* Common things */
11618    f.src = "IAX2";
11619    f.mallocd = 0;
11620    f.offset = 0;
11621    f.len = 0;
11622    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11623       f.samples = ast_codec_get_samples(&f);
11624       /* We need to byteswap incoming slinear samples from network byte order */
11625       if (f.subclass.codec == AST_FORMAT_SLINEAR)
11626          ast_frame_byteswap_be(&f);
11627    } else
11628       f.samples = 0;
11629    iax_frame_wrap(fr, &f);
11630 
11631    /* If this is our most recent packet, use it as our basis for timestamping */
11632    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11633       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
11634       fr->outoforder = 0;
11635    } else {
11636       if (iaxdebug && iaxs[fr->callno])
11637          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);
11638       fr->outoforder = -1;
11639    }
11640    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11641    duped_fr = iaxfrdup2(fr);
11642    if (duped_fr) {
11643       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11644    }
11645    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11646       iaxs[fr->callno]->last = fr->ts;
11647 #if 1
11648       if (iaxdebug)
11649          ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11650 #endif
11651    }
11652 
11653    /* Always run again */
11654    ast_variables_destroy(ies.vars);
11655    ast_mutex_unlock(&iaxsl[fr->callno]);
11656    return 1;
11657 }

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

09696 {
09697    unsigned char metatype;
09698    struct ast_iax2_meta_trunk_mini *mtm;
09699    struct ast_iax2_meta_trunk_hdr *mth;
09700    struct ast_iax2_meta_trunk_entry *mte;
09701    struct iax2_trunk_peer *tpeer;
09702    unsigned int ts;
09703    void *ptr;
09704    struct timeval rxtrunktime;
09705    struct ast_frame f = { 0, };
09706 
09707    if (packet_len < sizeof(*meta)) {
09708       ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 
09709          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09710       return 1;
09711    }
09712 
09713    if (meta->metacmd != IAX_META_TRUNK)
09714       return 1;
09715 
09716    if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09717       ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09718          (int) (sizeof(*meta) + sizeof(*mth)));
09719       return 1;
09720    }
09721    mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09722    ts = ntohl(mth->ts);
09723    metatype = meta->cmddata;
09724    packet_len -= (sizeof(*meta) + sizeof(*mth));
09725    ptr = mth->data;
09726    tpeer = find_tpeer(sin, sockfd);
09727    if (!tpeer) {
09728       ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 
09729          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09730       return 1;
09731    }
09732    tpeer->trunkact = ast_tvnow();
09733    if (!ts || ast_tvzero(tpeer->rxtrunktime))
09734       tpeer->rxtrunktime = tpeer->trunkact;
09735    rxtrunktime = tpeer->rxtrunktime;
09736    ast_mutex_unlock(&tpeer->lock);
09737    while (packet_len >= sizeof(*mte)) {
09738       /* Process channels */
09739       unsigned short callno, trunked_ts, len;
09740 
09741       if (metatype == IAX_META_TRUNK_MINI) {
09742          mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09743          ptr += sizeof(*mtm);
09744          packet_len -= sizeof(*mtm);
09745          len = ntohs(mtm->len);
09746          callno = ntohs(mtm->mini.callno);
09747          trunked_ts = ntohs(mtm->mini.ts);
09748       } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09749          mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09750          ptr += sizeof(*mte);
09751          packet_len -= sizeof(*mte);
09752          len = ntohs(mte->len);
09753          callno = ntohs(mte->callno);
09754          trunked_ts = 0;
09755       } else {
09756          ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09757          break;
09758       }
09759       /* Stop if we don't have enough data */
09760       if (len > packet_len)
09761          break;
09762       fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09763       if (!fr->callno)
09764          continue;
09765 
09766       /* If it's a valid call, deliver the contents.  If not, we
09767          drop it, since we don't have a scallno to use for an INVAL */
09768       /* Process as a mini frame */
09769       memset(&f, 0, sizeof(f));
09770       f.frametype = AST_FRAME_VOICE;
09771       if (!iaxs[fr->callno]) {
09772          /* drop it */
09773       } else if (iaxs[fr->callno]->voiceformat == 0) {
09774          ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09775          iax2_vnak(fr->callno);
09776       } else {
09777          f.subclass.codec = iaxs[fr->callno]->voiceformat;
09778          f.datalen = len;
09779          if (f.datalen >= 0) {
09780             if (f.datalen)
09781                f.data.ptr = ptr;
09782             else
09783                f.data.ptr = NULL;
09784             if (trunked_ts)
09785                fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09786             else
09787                fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09788             /* Don't pass any packets until we're started */
09789             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09790                struct iax_frame *duped_fr;
09791 
09792                /* Common things */
09793                f.src = "IAX2";
09794                f.mallocd = 0;
09795                f.offset = 0;
09796                if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
09797                   f.samples = ast_codec_get_samples(&f);
09798                else
09799                   f.samples = 0;
09800                fr->outoforder = 0;
09801                iax_frame_wrap(fr, &f);
09802                duped_fr = iaxfrdup2(fr);
09803                if (duped_fr)
09804                   schedule_delivery(duped_fr, 1, 1, &fr->ts);
09805                if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09806                   iaxs[fr->callno]->last = fr->ts;
09807             }
09808          } else {
09809             ast_log(LOG_WARNING, "Datalen < 0?\n");
09810          }
09811       }
09812       ast_mutex_unlock(&iaxsl[fr->callno]);
09813       ptr += len;
09814       packet_len -= len;
09815    }
09816 
09817    return 1;
09818 }

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

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

09616 {
09617    struct iax2_thread *thread;
09618    socklen_t len;
09619    time_t t;
09620    static time_t last_errtime = 0;
09621    struct ast_iax2_full_hdr *fh;
09622 
09623    if (!(thread = find_idle_thread())) {
09624       time(&t);
09625       if (t != last_errtime)
09626          ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09627       last_errtime = t;
09628       usleep(1);
09629       return 1;
09630    }
09631 
09632    len = sizeof(thread->iosin);
09633    thread->iofd = fd;
09634    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09635    thread->buf_size = sizeof(thread->readbuf);
09636    thread->buf = thread->readbuf;
09637    if (thread->buf_len < 0) {
09638       if (errno != ECONNREFUSED && errno != EAGAIN)
09639          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09640       handle_error();
09641       thread->iostate = IAX_IOSTATE_IDLE;
09642       signal_condition(&thread->lock, &thread->cond);
09643       return 1;
09644    }
09645    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
09646       thread->iostate = IAX_IOSTATE_IDLE;
09647       signal_condition(&thread->lock, &thread->cond);
09648       return 1;
09649    }
09650    
09651    /* Determine if this frame is a full frame; if so, and any thread is currently
09652       processing a full frame for the same callno from this peer, then drop this
09653       frame (and the peer will retransmit it) */
09654    fh = (struct ast_iax2_full_hdr *) thread->buf;
09655    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09656       struct iax2_thread *cur = NULL;
09657       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09658       
09659       AST_LIST_LOCK(&active_list);
09660       AST_LIST_TRAVERSE(&active_list, cur, list) {
09661          if ((cur->ffinfo.callno == callno) &&
09662              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09663             break;
09664       }
09665       if (cur) {
09666          /* we found another thread processing a full frame for this call,
09667             so queue it up for processing later. */
09668          defer_full_frame(thread, cur);
09669          AST_LIST_UNLOCK(&active_list);
09670          thread->iostate = IAX_IOSTATE_IDLE;
09671          signal_condition(&thread->lock, &thread->cond);
09672          return 1;
09673       } else {
09674          /* this thread is going to process this frame, so mark it */
09675          thread->ffinfo.callno = callno;
09676          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09677          thread->ffinfo.type = fh->type;
09678          thread->ffinfo.csub = fh->csub;
09679          AST_LIST_INSERT_HEAD(&active_list, thread, list);
09680       }
09681       AST_LIST_UNLOCK(&active_list);
09682    }
09683    
09684    /* Mark as ready and send on its way */
09685    thread->iostate = IAX_IOSTATE_READY;
09686 #ifdef DEBUG_SCHED_MULTITHREAD
09687    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09688 #endif
09689    signal_condition(&thread->lock, &thread->cond);
09690 
09691    return 1;
09692 }

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

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

09286 {
09287    pthread_t newthread;
09288    struct dpreq_data *dpr;
09289    
09290    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09291       return;
09292 
09293    dpr->callno = callno;
09294    ast_copy_string(dpr->context, context, sizeof(dpr->context));
09295    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09296    if (callerid)
09297       dpr->callerid = ast_strdup(callerid);
09298    if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09299       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09300    }
09301 }

static int start_network_thread ( void   )  [static]

Definition at line 12220 of file chan_iax2.c.

References ast_calloc, ast_cond_destroy, ast_cond_init, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, ast_pthread_create_background, ast_verb, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, LOG_ERROR, LOG_WARNING, network_thread(), and thread.

Referenced by load_module().

12221 {
12222    struct iax2_thread *thread;
12223    int threadcount = 0;
12224    int x;
12225    for (x = 0; x < iaxthreadcount; x++) {
12226       thread = ast_calloc(1, sizeof(*thread));
12227       if (thread) {
12228          thread->type = IAX_THREAD_TYPE_POOL;
12229          thread->threadnum = ++threadcount;
12230          ast_mutex_init(&thread->lock);
12231          ast_cond_init(&thread->cond, NULL);
12232          ast_mutex_init(&thread->init_lock);
12233          ast_cond_init(&thread->init_cond, NULL);
12234          if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12235             ast_log(LOG_WARNING, "Failed to create new thread!\n");
12236             ast_mutex_destroy(&thread->lock);
12237             ast_cond_destroy(&thread->cond);
12238             ast_mutex_destroy(&thread->init_lock);
12239             ast_cond_destroy(&thread->init_cond);
12240             ast_free(thread);
12241             thread = NULL;
12242             continue;
12243          }
12244          AST_LIST_LOCK(&idle_list);
12245          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12246          AST_LIST_UNLOCK(&idle_list);
12247       }
12248    }
12249    if (ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL)) {
12250       ast_log(LOG_ERROR, "Failed to create new thread!\n");
12251       return -1;
12252    }
12253    ast_verb(2, "%d helper threads started\n", threadcount);
12254    return 0;
12255 }

static void stop_stuff ( int  callno  )  [static]

Definition at line 8988 of file chan_iax2.c.

References iax2_destroy_helper(), and iaxs.

Referenced by socket_process().

08989 {
08990    iax2_destroy_helper(iaxs[callno]);
08991 }

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

09172 {
09173    int res, processed = 0, totalcalls = 0;
09174    struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09175    struct timeval now = ast_tvnow();
09176 
09177    if (iaxtrunkdebug)
09178       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09179 
09180    if (timer) {
09181       if (ast_timer_ack(timer, 1) < 0) {
09182          ast_log(LOG_ERROR, "Timer failed acknowledge\n");
09183          return 0;
09184       }
09185    }
09186 
09187    /* For each peer that supports trunking... */
09188    AST_LIST_LOCK(&tpeers);
09189    AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09190       processed++;
09191       res = 0;
09192       ast_mutex_lock(&tpeer->lock);
09193       /* We can drop a single tpeer per pass.  That makes all this logic
09194          substantially easier */
09195       if (!drop && iax2_trunk_expired(tpeer, &now)) {
09196          /* Take it out of the list, but don't free it yet, because it
09197             could be in use */
09198          AST_LIST_REMOVE_CURRENT(list);
09199          drop = tpeer;
09200       } else {
09201          res = send_trunk(tpeer, &now);
09202          trunk_timed++; 
09203          if (iaxtrunkdebug)
09204             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);
09205       }     
09206       totalcalls += res;   
09207       res = 0;
09208       ast_mutex_unlock(&tpeer->lock);
09209    }
09210    AST_LIST_TRAVERSE_SAFE_END;
09211    AST_LIST_UNLOCK(&tpeers);
09212 
09213    if (drop) {
09214       ast_mutex_lock(&drop->lock);
09215       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
09216          because by the time they could get tpeerlock, we've already grabbed it */
09217       ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09218       if (drop->trunkdata) {
09219          ast_free(drop->trunkdata);
09220          drop->trunkdata = NULL;
09221       }
09222       ast_mutex_unlock(&drop->lock);
09223       ast_mutex_destroy(&drop->lock);
09224       ast_free(drop);
09225       
09226    }
09227 
09228    if (iaxtrunkdebug)
09229       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09230    iaxtrunkdebug = 0;
09231 
09232    return 1;
09233 }

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

Definition at line 14482 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, and match().

Referenced by load_objects().

14483 {
14484    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14485 
14486    /* The frames_received field is used to hold whether we're matching
14487     * against a full frame or not ... */
14488 
14489    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14490       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14491 }

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

Definition at line 14475 of file chan_iax2.c.

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

14476 {
14477    const struct chan_iax2_pvt *pvt = obj;
14478 
14479    return pvt->transfercallno;
14480 }

static int transmit_frame ( void *  data  )  [static]

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

04258 {
04259    struct iax_frame *fr = data;
04260 
04261    ast_mutex_lock(&iaxsl[fr->callno]);
04262 
04263    fr->sentyet = 1;
04264 
04265    if (iaxs[fr->callno]) {
04266       send_packet(fr);
04267    }
04268 
04269    if (fr->retries < 0) {
04270       ast_mutex_unlock(&iaxsl[fr->callno]);
04271       /* No retransmit requested */
04272       iax_frame_free(fr);
04273    } else {
04274       /* We need reliable delivery.  Schedule a retransmission */
04275       AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04276       fr->retries++;
04277       fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04278       ast_mutex_unlock(&iaxsl[fr->callno]);
04279    }
04280 
04281    return 0;
04282 }

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

08307 {
08308    int newcall = 0;
08309    char newip[256];
08310    struct iax_ie_data ied;
08311    struct sockaddr_in new = { 0, };
08312 
08313    memset(&ied, 0, sizeof(ied));
08314    if (ies->apparent_addr)
08315       memmove(&new, ies->apparent_addr, sizeof(new));
08316    if (ies->callno)
08317       newcall = ies->callno;
08318    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08319       ast_log(LOG_WARNING, "Invalid transfer request\n");
08320       return -1;
08321    }
08322    pvt->transfercallno = newcall;
08323    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08324    inet_aton(newip, &pvt->transfer.sin_addr);
08325    pvt->transfer.sin_family = AF_INET;
08326    pvt->transferid = ies->transferid;
08327    /* only store by transfercallno if this is a new transfer,
08328     * just in case we get a duplicate TXREQ */
08329    if (pvt->transferring == TRANSFER_NONE) {
08330       store_by_transfercallno(pvt);
08331    }
08332    pvt->transferring = TRANSFER_BEGIN;
08333 
08334    if (ies->transferid)
08335       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08336    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08337    return 0;
08338 }

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

08601 {
08602    if (peer->expire > -1) {
08603       if (!ast_sched_thread_del(sched, peer->expire)) {
08604          peer->expire = -1;
08605          peer_unref(peer);
08606       }
08607    }
08608 
08609    if (peer->pokeexpire > -1) {
08610       if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08611          peer->pokeexpire = -1;
08612          peer_unref(peer);
08613       }
08614    }
08615 
08616    ao2_unlink(peers, peer);
08617 }

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

Definition at line 5465 of file chan_iax2.c.

References ast_mutex_unlock, and iaxsl.

Referenced by iax2_bridge().

05466 {
05467    ast_mutex_unlock(&iaxsl[callno1]);
05468    ast_mutex_unlock(&iaxsl[callno0]);
05469 }

static void unwrap_timestamp ( struct iax_frame fr  )  [static]

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

04011 {
04012    /* Video mini frames only encode the lower 15 bits of the session
04013     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
04014    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
04015    const int lower_mask = (1 << ts_shift) - 1;
04016    const int upper_mask = ~lower_mask;
04017    const int last_upper = iaxs[fr->callno]->last & upper_mask;
04018 
04019    if ( (fr->ts & upper_mask) == last_upper ) {
04020       const int x = fr->ts - iaxs[fr->callno]->last;
04021       const int threshold = (ts_shift == 15) ? 25000 : 50000;
04022 
04023       if (x < -threshold) {
04024          /* Sudden big jump backwards in timestamp:
04025             What likely happened here is that miniframe timestamp has circled but we haven't
04026             gotten the update from the main packet.  We'll just pretend that we did, and
04027             update the timestamp appropriately. */
04028          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04029          if (iaxdebug)
04030             ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04031       } else if (x > threshold) {
04032          /* Sudden apparent big jump forwards in timestamp:
04033             What's likely happened is this is an old miniframe belonging to the previous
04034             top 15 or 16-bit timestamp that has turned up out of order.
04035             Adjust the timestamp appropriately. */
04036          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04037          if (iaxdebug)
04038             ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04039       }
04040    }
04041 }

static void update_jbsched ( struct chan_iax2_pvt pvt  )  [static]

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

04046 {
04047    int when;
04048    
04049    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04050    
04051    when = jb_next(pvt->jb) - when;
04052 
04053    if (when <= 0) {
04054       /* XXX should really just empty until when > 0.. */
04055       when = 1;
04056    }
04057    
04058    pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 
04059       CALLNO_TO_PTR(pvt->callno));
04060 }

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

08721 {
08722    /* Called from IAX thread only, with proper iaxsl lock */
08723    struct iax_ie_data ied = {
08724       .pos = 0,
08725    };
08726    struct iax2_peer *p;
08727    int msgcount;
08728    char data[80];
08729    int version;
08730    const char *peer_name;
08731    int res = -1;
08732    struct ast_sockaddr sockaddr;
08733 
08734    ast_sockaddr_from_sin(&sockaddr, sin);
08735 
08736    peer_name = ast_strdupa(iaxs[callno]->peer);
08737 
08738    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
08739    ast_mutex_unlock(&iaxsl[callno]);
08740    if (!(p = find_peer(peer_name, 1))) {
08741       ast_mutex_lock(&iaxsl[callno]);
08742       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08743       return -1;
08744    }
08745    ast_mutex_lock(&iaxsl[callno]);
08746    if (!iaxs[callno])
08747       goto return_unref;
08748 
08749    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08750       if (sin->sin_addr.s_addr) {
08751          time_t nowtime;
08752          time(&nowtime);
08753          realtime_update_peer(peer_name, &sockaddr, nowtime);
08754       } else {
08755          realtime_update_peer(peer_name, &sockaddr, 0);
08756       }
08757    }
08758 
08759    if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08760       if (iax2_regfunk) {
08761          iax2_regfunk(p->name, 1);
08762       }
08763 
08764       /* modify entry in peercnts table as _not_ registered */
08765       peercnt_modify(0, 0, &p->addr);
08766 
08767       /* Stash the IP address from which they registered */
08768       ast_sockaddr_from_sin(&p->addr, sin);
08769 
08770       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08771       if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08772          ast_db_put("IAX/Registry", p->name, data);
08773          ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08774                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08775          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08776          register_peer_exten(p, 1);
08777          ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
08778       } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08779          ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08780                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08781          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08782          register_peer_exten(p, 0);
08783          ast_db_del("IAX/Registry", p->name);
08784          ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
08785       }
08786       /* Update the host */
08787       /* Verify that the host is really there */
08788       iax2_poke_peer(p, callno);
08789    }
08790 
08791    /* modify entry in peercnts table as registered */
08792    if (p->maxcallno) {
08793       peercnt_modify(1, p->maxcallno, &p->addr);
08794    }
08795 
08796    /* Make sure our call still exists, an INVAL at the right point may make it go away */
08797    if (!iaxs[callno]) {
08798       res = -1;
08799       goto return_unref;
08800    }
08801 
08802    /* Store socket fd */
08803    p->sockfd = fd;
08804    /* Setup the expiry */
08805    if (p->expire > -1) {
08806       if (!ast_sched_thread_del(sched, p->expire)) {
08807          p->expire = -1;
08808          peer_unref(p);
08809       }
08810    }
08811    /* treat an unspecified refresh interval as the minimum */
08812    if (!refresh)
08813       refresh = min_reg_expire;
08814    if (refresh > max_reg_expire) {
08815       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08816          p->name, max_reg_expire, refresh);
08817       p->expiry = max_reg_expire;
08818    } else if (refresh < min_reg_expire) {
08819       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08820          p->name, min_reg_expire, refresh);
08821       p->expiry = min_reg_expire;
08822    } else {
08823       p->expiry = refresh;
08824    }
08825    if (p->expiry && sin->sin_addr.s_addr) {
08826       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08827       if (p->expire == -1)
08828          peer_unref(p);
08829    }
08830    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08831    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08832    if (sin->sin_addr.s_addr) {
08833       struct sockaddr_in peer_addr;
08834 
08835       ast_sockaddr_to_sin(&p->addr, &peer_addr);
08836 
08837       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08838       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08839       if (!ast_strlen_zero(p->mailbox)) {
08840          struct ast_event *event;
08841          int new, old;
08842          char *mailbox, *context;
08843 
08844          context = mailbox = ast_strdupa(p->mailbox);
08845          strsep(&context, "@");
08846          if (ast_strlen_zero(context))
08847             context = "default";
08848 
08849          event = ast_event_get_cached(AST_EVENT_MWI,
08850             AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08851             AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08852             AST_EVENT_IE_END);
08853          if (event) {
08854             new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08855             old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08856             ast_event_destroy(event);
08857          } else { /* Fall back on checking the mailbox directly */
08858             ast_app_inboxcount(p->mailbox, &new, &old);
08859          }
08860 
08861          if (new > 255) {
08862             new = 255;
08863          }
08864          if (old > 255) {
08865             old = 255;
08866          }
08867          msgcount = (old << 8) | new;
08868 
08869          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08870       }
08871       if (ast_test_flag64(p, IAX_HASCALLERID)) {
08872          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08873          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08874       }
08875    }
08876    version = iax_check_version(devtype);
08877    if (version) 
08878       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08879 
08880    res = 0;
08881 
08882 return_unref:
08883    peer_unref(p);
08884 
08885    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08886 }

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

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

12962 {
12963    struct iax2_user *user = obj;
12964 
12965    ast_set_flag64(user, IAX_DELME);
12966 
12967    return 0;
12968 }

static void user_destructor ( void *  obj  )  [static]

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

12687 {
12688    struct iax2_user *user = obj;
12689 
12690    ast_free_ha(user->ha);
12691    free_context(user->contexts);
12692    if(user->vars) {
12693       ast_variables_destroy(user->vars);
12694       user->vars = NULL;
12695    }
12696    ast_string_field_free_memory(user);
12697 }

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

14647 {
14648    struct ast_data *data_user, *data_authmethods, *data_enum_node;
14649    struct iax2_user *user;
14650    struct ao2_iterator i;
14651    char auth[90];
14652    char *pstr = "";
14653 
14654    i = ao2_iterator_init(users, 0);
14655    for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
14656       data_user = ast_data_add_node(data_root, "user");
14657       if (!data_user) {
14658          continue;
14659       }
14660 
14661       ast_data_add_structure(iax2_user, data_user, user);
14662 
14663       ast_data_add_codecs(data_user, "codecs", user->capability);
14664 
14665       if (!ast_strlen_zero(user->secret)) {
14666          ast_copy_string(auth, user->secret, sizeof(auth));
14667       } else if (!ast_strlen_zero(user->inkeys)) {
14668          snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14669       } else {
14670          ast_copy_string(auth, "no secret", sizeof(auth));
14671       }
14672       ast_data_add_password(data_user, "secret", auth);
14673 
14674       ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14675 
14676       /* authmethods */
14677       data_authmethods = ast_data_add_node(data_user, "authmethods");
14678       if (!data_authmethods) {
14679          ast_data_remove_node(data_root, data_user);
14680          continue;
14681       }
14682       ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14683       ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14684       ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14685 
14686       /* amaflags */
14687       data_enum_node = ast_data_add_node(data_user, "amaflags");
14688       if (!data_enum_node) {
14689          ast_data_remove_node(data_root, data_user);
14690          continue;
14691       }
14692       ast_data_add_int(data_enum_node, "value", user->amaflags);
14693       ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14694 
14695       ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14696 
14697       if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14698          pstr = "REQ only";
14699       } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14700          pstr = "disabled";
14701       } else {
14702          pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14703       }
14704       ast_data_add_str(data_user, "codec-preferences", pstr);
14705 
14706       if (!ast_data_search_match(search, data_user)) {
14707          ast_data_remove_node(data_root, data_user);
14708       }
14709    }
14710    ao2_iterator_destroy(&i);
14711 
14712    return 0;
14713 }

static void vnak_retransmit ( int  callno,
int  last 
) [static]

Definition at line 9089 of file chan_iax2.c.

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

Referenced by socket_process().

09090 {
09091    struct iax_frame *f;
09092 
09093    AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09094       /* Send a copy immediately */
09095       if (((unsigned char) (f->oseqno - last) < 128) &&
09096             (f->retries >= 0)) {
09097          send_packet(f);
09098       }
09099    }
09100 }

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

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

05276 {
05277    unsigned short callno = pvt->callno;
05278 
05279    if (!pvt->peercallno) {
05280       /* We don't know the remote side's call number, yet.  :( */
05281       int count = 10;
05282       while (count-- && pvt && !pvt->peercallno) {
05283          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05284          pvt = iaxs[callno];
05285       }
05286       if (!pvt || !pvt->peercallno) {
05287          return -1;
05288       }
05289    }
05290 
05291    return 0;
05292 }


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 14185 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 14725 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 14071 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 13991 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 9887 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 11925 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

Initial value:

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


Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1