Mon Mar 19 11:30:39 2012

Asterisk developer's documentation


chan_iax2.c File Reference

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

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

Go to the source code of this file.

Data Structures

struct  active_list
struct  addr_range
struct  callno_entry
struct  chan_iax2_pvt
struct  chan_iax2_pvt::signaling_queue
struct  create_addr_info
struct  dpcache
struct  dpreq_data
struct  dynamic_list
struct  firmwares
struct  iax2_context
struct  iax2_dpcache
struct  iax2_peer
struct  iax2_pkt_buf
struct  iax2_registry
struct  iax2_thread
struct  iax2_trunk_peer
struct  iax2_user
struct  iax_dual
struct  iax_firmware
struct  iax_rr
struct  idle_list
struct  parsed_dial_string
struct  peercnt
struct  registrations
struct  signaling_queue_entry
struct  tpeers

Defines

#define ACN_FORMAT1   "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
#define ACN_FORMAT2   "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
#define CALLNO_TO_PTR(a)   ((void *)(unsigned long)(a))
#define CALLTOKEN_HASH_FORMAT   "%s%d%u%d"
#define CALLTOKEN_IE_FORMAT   "%u?%s"
#define DATA_EXPORT_IAX2_PEER(MEMBER)
#define DATA_EXPORT_IAX2_USER(MEMBER)
#define DEBUG_SCHED_MULTITHREAD
#define DEBUG_SUPPORT
#define DEFAULT_CONTEXT   "default"
#define DEFAULT_DROP   3
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAX_THREAD_COUNT   100
#define DEFAULT_MAXMS   2000
#define DEFAULT_RETRY_TIME   1000
#define DEFAULT_THREAD_COUNT   10
#define DEFAULT_TRUNKDATA   640 * 10
#define DONT_RESCHEDULE   -2
#define FORMAT   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n"
#define FORMAT   "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
#define FORMAT   "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-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

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 void __reg_module (void)
static int __schedule_action (void(*func)(const void *data), const void *data, const char *funcname)
static int __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final)
static void __send_lagrq (const void *data)
static void __send_ping (const void *data)
static int __unload_module (void)
static void __unreg_module (void)
static int acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen)
static int acf_iaxvar_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int acf_iaxvar_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
static int add_calltoken_ignore (const char *addr)
static void add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
static int addr_range_cmp_cb (void *obj, void *arg, int flags)
static int addr_range_delme_cb (void *obj, void *arg, int flags)
static int addr_range_hash_cb (const void *obj, const int flags)
static int addr_range_match_address_cb (void *obj, void *arg, int flags)
static int apply_context (struct iax2_context *con, const char *context)
static int ast_cli_netstats (struct mansession *s, int fd, int limit_fmt)
 AST_DATA_STRUCTURE (iax2_user, DATA_EXPORT_IAX2_USER)
 AST_DATA_STRUCTURE (iax2_peer, DATA_EXPORT_IAX2_PEER)
static struct ast_channelast_iax2_new (int callno, int state, format_t capability, const char *linkedid)
 Create new call, interface with the PBX core.
static int attempt_transmit (const void *data)
static int auth_fail (int callno, int failcode)
static int auth_reject (const void *data)
static int authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt)
static int authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
static int authenticate_request (int call_num)
static int authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies)
static int auto_congest (const void *data)
static int auto_hangup (const void *data)
static void build_callno_limits (struct ast_variable *v)
static struct iax2_contextbuild_context (const char *context)
static void build_ecx_key (const unsigned char *digest, struct chan_iax2_pvt *pvt)
static void build_encryption_keys (const unsigned char *digest, struct chan_iax2_pvt *pvt)
static struct iax2_peerbuild_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
 Create peer structure based on configuration.
static void build_rand_pad (unsigned char *buf, ssize_t len)
static struct iax2_userbuild_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
 Create in-memory user structure from configuration.
static int cache_get_callno_locked (const char *data)
static unsigned int calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset)
static unsigned int calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
static unsigned int calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
static int callno_hash (const void *obj, const int flags)
static int calltoken_required (struct sockaddr_in *sin, const char *name, int subclass)
static int check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies)
static int check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
static int check_srcaddr (struct sockaddr *sa, socklen_t salen)
 Check if address can be used as packet source.
static void cleanup_thread_list (void *head)
static int complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static char * complete_iax2_peers (const char *line, const char *word, int pos, int state, uint64_t flags)
static char * complete_iax2_unregister (const char *line, const char *word, int pos, int state)
static int complete_transfer (int callno, struct iax_ies *ies)
static unsigned char compress_subclass (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 void update_max_nontrunk (void)
static void update_max_trunk (void)
static int update_packet (struct iax_frame *f)
static int update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
static int user_cmp_cb (void *obj, void *arg, int flags)
static int user_delme_cb (void *obj, void *arg, int flags)
static void user_destructor (void *obj)
static int user_hash_cb (const void *obj, const int flags)
static struct iax2_useruser_ref (struct iax2_user *user)
static struct iax2_useruser_unref (struct iax2_user *user)
static int users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root)
static void vnak_retransmit (int callno, int last)
static int wait_for_peercallno (struct chan_iax2_pvt *pvt)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", }
static char accountcode [AST_MAX_ACCOUNT_CODE]
static int adsi = 0
static int amaflags = 0
static struct ast_module_infoast_module_info = &__mod_info
static int authdebug = 1
static int autokill = 0
static struct ao2_containercallno_limits
static struct ao2_containercallno_pool
static const unsigned int CALLNO_POOL_BUCKETS = 2699
static struct ao2_containercallno_pool_trunk
static struct ao2_containercalltoken_ignores
static struct ast_cli_entry cli_iax2 []
static struct sockaddr_in debugaddr
static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048
static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192
static char default_parkinglot [AST_MAX_CONTEXT]
static int defaultsockfd = -1
static int delayreject = 0
struct {
   iax_frame *   first
   iax_frame *   last
frame_queue [IAX_MAX_CALLS+1]
 a list of frames that may need to be retransmitted
static int global_max_trunk_mtu
static uint16_t global_maxcallno
static uint16_t global_maxcallno_nonval
static int global_rtautoclear = 120
static struct ast_flags64 globalflags = { 0 }
static 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+1]
 an array of iax2 pvt structures
static ast_mutex_t iaxsl [ARRAY_LEN(iaxs)]
 chan_iax2_pvt structure locks
static int iaxthreadcount = DEFAULT_THREAD_COUNT
static int iaxtrunkdebug = 0
static struct ast_custom_function iaxvar_function
static struct io_contextio
static int jittertargetextra = 40
static int lagrq_time = 10
static char language [MAX_LANGUAGE] = ""
static int last_authmethod = 0
static const time_t MAX_CALLTOKEN_DELAY = 10
static int max_reg_expire
static int max_retries = 4
static int maxauthreq = 3
static int maxjitterbuffer = 1000
static int maxjitterinterps = 10
static int maxnontrunkcall = 1
static int maxtrunkcall = TRUNK_CALL_START
static int min_reg_expire
static char mohinterpret [MAX_MUSICCLASS]
static char mohsuggest [MAX_MUSICCLASS]
static struct ast_netsock_listnetsock
static pthread_t netthreadid = AST_PTHREADT_NULL
static int network_change_event_sched_id = -1
static struct ast_event_subnetwork_change_event_subscription
static struct ast_netsock_listoutsock
static char * papp = "IAX2Provision"
static struct ao2_containerpeercnts
static struct ao2_containerpeers
static struct ast_data_handler peers_data_provider
static int ping_time = 21
static struct ast_codec_pref prefs
struct {
   unsigned int   cos
   unsigned int   tos
qos
static int randomcalltokendata
static char regcontext [AST_MAX_CONTEXT] = ""
static int resyncthreshold = 1000
static struct ast_sched_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 uint16_t total_nonval_callno_used = 0
static struct ast_taskprocessortransmit_processor
static int trunk_maxmtu
static int trunk_nmaxmtu
static int trunk_timed
static int trunk_untimed
static int trunkfreq = 20
static int trunkmaxsize = MAX_TRUNKDATA
static struct ao2_containerusers
static struct ast_data_handler users_data_provider


Detailed Description

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

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

Definition in file chan_iax2.c.


Define Documentation

#define ACN_FORMAT1   "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"

Referenced by ast_cli_netstats().

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

Referenced by ast_cli_netstats().

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

Definition at line 239 of file chan_iax2.c.

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

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

Referenced by handle_call_token().

#define CALLTOKEN_IE_FORMAT   "%u?%s"

Referenced by handle_call_token().

#define DATA_EXPORT_IAX2_PEER ( MEMBER   ) 

Definition at line 14473 of file chan_iax2.c.

#define DATA_EXPORT_IAX2_USER ( MEMBER   ) 

Definition at line 14550 of file chan_iax2.c.

#define DEBUG_SCHED_MULTITHREAD

Definition at line 231 of file chan_iax2.c.

#define DEBUG_SUPPORT

Definition at line 247 of file chan_iax2.c.

#define DEFAULT_CONTEXT   "default"

Definition at line 266 of file chan_iax2.c.

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

#define DEFAULT_DROP   3

Definition at line 245 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

Definition at line 341 of file chan_iax2.c.

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

#define DEFAULT_FREQ_OK   60 * 1000

Definition at line 340 of file chan_iax2.c.

Referenced by build_peer().

#define DEFAULT_MAX_THREAD_COUNT   100

Definition at line 242 of file chan_iax2.c.

#define DEFAULT_MAXMS   2000

Definition at line 339 of file chan_iax2.c.

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

#define DEFAULT_RETRY_TIME   1000

Definition at line 243 of file chan_iax2.c.

Referenced by __find_callno(), and complete_transfer().

#define DEFAULT_THREAD_COUNT   10

Definition at line 241 of file chan_iax2.c.

#define DEFAULT_TRUNKDATA   640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 620 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

#define DONT_RESCHEDULE   -2

Definition at line 363 of file chan_iax2.c.

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

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

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

#define FORMAT   "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-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 252 of file chan_iax2.c.

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

Definition at line 541 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

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

Allow the FWDOWNL command?

Definition at line 429 of file chan_iax2.c.

Referenced by set_config(), and socket_process().

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

Already disconnected

Definition at line 412 of file chan_iax2.c.

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

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

Definition at line 344 of file chan_iax2.c.

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

#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF

Definition at line 318 of file chan_iax2.c.

Referenced by cache_get_callno_locked(), and set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH

Value:

Definition at line 330 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWFREE

Value:

Definition at line 335 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH

Definition at line 320 of file chan_iax2.c.

Referenced by set_config().

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

only consider requested format and ignore capabilities

Definition at line 419 of file chan_iax2.c.

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

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

Force old behaviour by turning off prefs

Definition at line 418 of file chan_iax2.c.

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

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

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

Definition at line 417 of file chan_iax2.c.

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

#define IAX_DEBUGDIGEST ( msg,
key   ) 

Definition at line 347 of file chan_iax2.c.

Referenced by iax2_key_rotate(), and socket_process().

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

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

Definition at line 428 of file chan_iax2.c.

Referenced by socket_process().

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

Needs to be deleted

Definition at line 404 of file chan_iax2.c.

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

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

dynamic peer

Definition at line 409 of file chan_iax2.c.

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

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

Whether we should assume encrypted tx/rx

Definition at line 415 of file chan_iax2.c.

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

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

Forces call encryption, if encryption not possible hangup

Definition at line 433 of file chan_iax2.c.

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

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

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

Definition at line 423 of file chan_iax2.c.

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

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

CallerID has been specified

Definition at line 403 of file chan_iax2.c.

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

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

Allow immediate off-hook to extension s

Definition at line 430 of file chan_iax2.c.

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

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

Whether we have a key populated

Definition at line 416 of file chan_iax2.c.

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

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

Maximum outstanding AUTHREQ restriction is in place

Definition at line 427 of file chan_iax2.c.

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

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

Don't native bridge

Definition at line 407 of file chan_iax2.c.

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

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

This is a provisioning request

Definition at line 413 of file chan_iax2.c.

Referenced by iax2_provision(), and socket_process().

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

Whether or not we quelch audio

Definition at line 414 of file chan_iax2.c.

Referenced by iax2_write(), and socket_process().

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

Allow receiving of connected line updates

Definition at line 432 of file chan_iax2.c.

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

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

erase me on expire

Definition at line 422 of file chan_iax2.c.

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

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

let realtime stay till your reload

Definition at line 420 of file chan_iax2.c.

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

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

When using realtime, ignore registration expiration

Definition at line 424 of file chan_iax2.c.

Referenced by set_config().

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

Save Systname on Realtime Updates

Definition at line 411 of file chan_iax2.c.

Referenced by realtime_update_peer(), and set_config().

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

Send a realtime update

Definition at line 421 of file chan_iax2.c.

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

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

Send ANI along with CallerID

Definition at line 410 of file chan_iax2.c.

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

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

Allow sending of connected line updates

Definition at line 431 of file chan_iax2.c.

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

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

Turn on and off caller id shrinking

Definition at line 434 of file chan_iax2.c.

Referenced by check_access(), and set_config().

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

Temporary (realtime)

Definition at line 405 of file chan_iax2.c.

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

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

When doing IAX2 transfers, transfer media only

Definition at line 426 of file chan_iax2.c.

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

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

Treat as a trunk

Definition at line 406 of file chan_iax2.c.

Referenced by __iax2_show_peers(), build_peer(), build_user(), check_access(), create_addr(), handle_cli_iax2_show_peer(), iax2_getpeertrunk(), iax2_request(), iax2_send(), manager_iax2_show_peer_list(), peers_data_provider_get(), and socket_process().

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

Send trunk timestamps

Definition at line 425 of file chan_iax2.c.

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

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

Use jitter buffer

Definition at line 408 of file chan_iax2.c.

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

#define MARK_IAX_SUBCLASS_TX   0x8000

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

#define MAX_PEER_BUCKETS   563

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

Definition at line 879 of file chan_iax2.c.

Referenced by load_objects().

#define MAX_RETRY_TIME   10000

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

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

#define MAX_TRUNK_MTU   1240

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

Definition at line 261 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_mtu(), and set_config().

#define MAX_TRUNKDATA   640 * 200

40ms, uncompressed linear * 200 channels

Definition at line 285 of file chan_iax2.c.

Referenced by set_config(), and set_config_destroy().

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

Definition at line 883 of file chan_iax2.c.

Referenced by load_module(), and load_objects().

#define MEMORY_SIZE   100

Definition at line 244 of file chan_iax2.c.

#define MIN_JITTER_BUFFER   10

Definition at line 618 of file chan_iax2.c.

#define MIN_RETRY_TIME   100

Definition at line 614 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME   60

Definition at line 249 of file chan_iax2.c.

Referenced by make_trunk(), and sched_delay_remove().

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

Definition at line 238 of file chan_iax2.c.

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

#define SCHED_MULTITHREADED

Definition at line 227 of file chan_iax2.c.

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

Definition at line 1485 of file chan_iax2.c.

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

#define TRUNK_CALL_START   IAX_MAX_CALLS / 2

Definition at line 1094 of file chan_iax2.c.

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

#define TS_GAP_FOR_JB_RESYNC   5000

Definition at line 625 of file chan_iax2.c.


Enumeration Type Documentation

anonymous enum

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

Definition at line 939 of file chan_iax2.c.

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

anonymous enum

Enumerator:
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 1972 of file chan_iax2.c.

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

enum calltoken_peer_enum

Call token validation settings.

Enumerator:
CALLTOKEN_DEFAULT  Default calltoken required unless the ip is in the ignorelist.
CALLTOKEN_YES  Require call token validation.
CALLTOKEN_AUTO  Require call token validation after a successful registration using call token validation occurs.
CALLTOKEN_NO  Do not require call token validation.

Definition at line 442 of file chan_iax2.c.

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

enum iax2_state

Enumerator:
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 391 of file chan_iax2.c.

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

enum iax2_thread_iostate

Enumerator:
IAX_IOSTATE_IDLE 
IAX_IOSTATE_READY 
IAX_IOSTATE_PROCESSING 
IAX_IOSTATE_SCHEDREADY 

Definition at line 980 of file chan_iax2.c.

enum iax2_thread_type

Enumerator:
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 987 of file chan_iax2.c.

00987                       {
00988    IAX_THREAD_TYPE_POOL,
00989    IAX_THREAD_TYPE_DYNAMIC,
00990 };

enum iax_reg_state

Enumerator:
REG_STATE_UNREGISTERED 
REG_STATE_REGSENT 
REG_STATE_AUTHSENT 
REG_STATE_REGISTERED 
REG_STATE_REJECTED 
REG_STATE_TIMEOUT 
REG_STATE_NOAUTH 

Definition at line 573 of file chan_iax2.c.

enum iax_transfer_state

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

Definition at line 583 of file chan_iax2.c.


Function Documentation

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

Definition at line 3466 of file chan_iax2.c.

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

Referenced by attempt_transmit().

03467 {
03468    /* Attempt to transmit the frame to the remote peer...
03469       Called without iaxsl held. */
03470    struct iax_frame *f = (struct iax_frame *)data;
03471    int freeme = 0;
03472    int callno = f->callno;
03473    /* Make sure this call is still active */
03474    if (callno) 
03475       ast_mutex_lock(&iaxsl[callno]);
03476    if (callno && iaxs[callno]) {
03477       if ((f->retries < 0) /* Already ACK'd */ ||
03478           (f->retries >= max_retries) /* Too many attempts */) {
03479             /* Record an error if we've transmitted too many times */
03480             if (f->retries >= max_retries) {
03481                if (f->transfer) {
03482                   /* Transfer timeout */
03483                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03484                } else if (f->final) {
03485                   iax2_destroy(callno);
03486                } else {
03487                   if (iaxs[callno]->owner)
03488                      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);
03489                   iaxs[callno]->error = ETIMEDOUT;
03490                   if (iaxs[callno]->owner) {
03491                      struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03492                      /* Hangup the fd */
03493                      iax2_queue_frame(callno, &fr); /* XXX */
03494                      /* Remember, owner could disappear */
03495                      if (iaxs[callno] && iaxs[callno]->owner)
03496                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03497                   } else {
03498                      if (iaxs[callno]->reg) {
03499                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03500                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03501                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03502                      }
03503                      iax2_destroy(callno);
03504                   }
03505                }
03506 
03507             }
03508             freeme = 1;
03509       } else {
03510          /* Update it if it needs it */
03511          update_packet(f);
03512          /* Attempt transmission */
03513          send_packet(f);
03514          f->retries++;
03515          /* Try again later after 10 times as long */
03516          f->retrytime *= 10;
03517          if (f->retrytime > MAX_RETRY_TIME)
03518             f->retrytime = MAX_RETRY_TIME;
03519          /* Transfer messages max out at one second */
03520          if (f->transfer && (f->retrytime > 1000))
03521             f->retrytime = 1000;
03522          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03523       }
03524    } else {
03525       /* Make sure it gets freed */
03526       f->retries = -1;
03527       freeme = 1;
03528    }
03529 
03530    if (freeme) {
03531       /* Don't attempt delivery, just remove it from the queue */
03532       AST_LIST_REMOVE(&frame_queue[callno], f, list);
03533       ast_mutex_unlock(&iaxsl[callno]);
03534       f->retrans = -1; /* this is safe because this is the scheduled function */
03535       /* Free the IAX frame */
03536       iax2_frame_free(f);
03537    } else if (callno) {
03538       ast_mutex_unlock(&iaxsl[callno]);
03539    }
03540 }

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

Definition at line 8953 of file chan_iax2.c.

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

Referenced by auth_reject().

08954 {
08955    /* Called from IAX thread only, without iaxs lock */
08956    int callno = (int)(long)(nothing);
08957    struct iax_ie_data ied;
08958    ast_mutex_lock(&iaxsl[callno]);
08959    if (iaxs[callno]) {
08960       memset(&ied, 0, sizeof(ied));
08961       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08962          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08963          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08964       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08965          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08966          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08967       }
08968       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08969    }
08970    ast_mutex_unlock(&iaxsl[callno]);
08971 }

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

Definition at line 4638 of file chan_iax2.c.

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

Referenced by auto_congest().

04639 {
04640    int callno = PTR_TO_CALLNO(nothing);
04641    struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04642    ast_mutex_lock(&iaxsl[callno]);
04643    if (iaxs[callno]) {
04644       iaxs[callno]->initid = -1;
04645       iax2_queue_frame(callno, &f);
04646       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04647    }
04648    ast_mutex_unlock(&iaxsl[callno]);
04649 }

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

Definition at line 9002 of file chan_iax2.c.

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

Referenced by auto_hangup().

09003 {
09004    /* Called from IAX thread only, without iaxs lock */
09005    int callno = (int)(long)(nothing);
09006    struct iax_ie_data ied;
09007    ast_mutex_lock(&iaxsl[callno]);
09008    if (iaxs[callno]) {
09009       memset(&ied, 0, sizeof(ied));
09010       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09011       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09012       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09013    }
09014    ast_mutex_unlock(&iaxsl[callno]);
09015 }

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

03253 {
03254    /* Just deliver the packet by using queueing.  This is called by
03255      the IAX thread with the iaxsl lock held. */
03256    struct iax_frame *fr = data;
03257    fr->retrans = -1;
03258    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03259    if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03260       iax2_queue_frame(fr->callno, &fr->af);
03261    /* Free our iax frame */
03262    iax2_frame_free(fr);
03263    /* And don't run again */
03264    return 0;
03265 }

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

Definition at line 8580 of file chan_iax2.c.

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

Referenced by expire_registry().

08581 {
08582    struct iax2_peer *peer = (struct iax2_peer *) data;
08583 
08584    if (!peer)
08585       return;
08586    if (peer->expire == -1) {
08587       /* Removed already (possibly through CLI), ignore */
08588       return;
08589    }
08590 
08591    peer->expire = -1;
08592 
08593    ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08594    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08595       realtime_update_peer(peer->name, &peer->addr, 0);
08596    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08597    /* modify entry in peercnts table as _not_ registered */
08598    peercnt_modify(0, 0, &peer->addr);
08599    /* Reset the address */
08600    memset(&peer->addr, 0, sizeof(peer->addr));
08601    /* Reset expiry value */
08602    peer->expiry = min_reg_expire;
08603    if (!ast_test_flag64(peer, IAX_TEMPONLY))
08604       ast_db_del("IAX/Registry", peer->name);
08605    register_peer_exten(peer, 0);
08606    ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
08607    if (iax2_regfunk)
08608       iax2_regfunk(peer->name, 0);
08609 
08610    if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08611       unlink_peer(peer);
08612 
08613    peer_unref(peer);
08614 }

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 2755 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, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), globalflags, iax2_getpeername(), iax2_sched_add(), IAX_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(), sched, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), chan_iax2_pvt::transfer, TRUNK_CALL_START, and update_max_nontrunk().

Referenced by find_callno(), and find_callno_locked().

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

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

Definition at line 4043 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, iax2_trunk_peer::next, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.

Referenced by get_from_jb().

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

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

Definition at line 8250 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

08251 {
08252    struct iax2_registry *reg = (struct iax2_registry *)data;
08253    reg->expire = -1;
08254    iax2_do_register(reg);
08255 }

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

Definition at line 11941 of file chan_iax2.c.

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

Referenced by iax2_poke_noanswer().

11942 {
11943    struct iax2_peer *peer = (struct iax2_peer *)data;
11944    int callno;
11945 
11946    if (peer->lastms > -1) {
11947       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11948       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11949       ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
11950    }
11951    if ((callno = peer->callno) > 0) {
11952       ast_mutex_lock(&iaxsl[callno]);
11953       iax2_destroy(callno);
11954       ast_mutex_unlock(&iaxsl[callno]);
11955    }
11956    peer->callno = 0;
11957    peer->lastms = -1;
11958    /* Try again quickly */
11959    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11960    if (peer->pokeexpire == -1)
11961       peer_unref(peer);
11962 }

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

Definition at line 9062 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

09063 {
09064    struct iax2_peer *peer = (struct iax2_peer *)data;
09065    iax2_poke_peer(peer, 0);
09066    peer_unref(peer);
09067 }

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

Definition at line 6616 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, iax2_peer::name, name, peer_status(), peer_unref(), peers, RESULT_SHOWUSAGE, RESULT_SUCCESS, status, and iax2_peer::username.

Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().

06617 {
06618    regex_t regexbuf;
06619    int havepattern = 0;
06620    int total_peers = 0;
06621    int online_peers = 0;
06622    int offline_peers = 0;
06623    int unmonitored_peers = 0;
06624    struct ao2_iterator i;
06625 
06626 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s\n"
06627 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s\n"
06628 
06629    struct iax2_peer *peer = NULL;
06630    char name[256];
06631    struct ast_str *encmethods = ast_str_alloca(256);
06632    int registeredonly=0;
06633    char idtext[256] = "";
06634    switch (argc) {
06635    case 6:
06636       if (!strcasecmp(argv[3], "registered"))
06637          registeredonly = 1;
06638       else
06639          return RESULT_SHOWUSAGE;
06640       if (!strcasecmp(argv[4], "like")) {
06641          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06642             return RESULT_SHOWUSAGE;
06643          havepattern = 1;
06644       } else
06645          return RESULT_SHOWUSAGE;
06646       break;
06647    case 5:
06648       if (!strcasecmp(argv[3], "like")) {
06649          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06650             return RESULT_SHOWUSAGE;
06651          havepattern = 1;
06652       } else
06653          return RESULT_SHOWUSAGE;
06654       break;
06655    case 4:
06656       if (!strcasecmp(argv[3], "registered"))
06657          registeredonly = 1;
06658       else
06659          return RESULT_SHOWUSAGE;
06660       break;
06661    case 3:
06662       break;
06663    default:
06664       return RESULT_SHOWUSAGE;
06665    }
06666 
06667 
06668    if (!s)
06669       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status");
06670 
06671    i = ao2_iterator_init(peers, 0);
06672    for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
06673       char nm[20];
06674       char status[20];
06675       int retstatus;
06676       struct sockaddr_in peer_addr;
06677 
06678       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06679 
06680       if (registeredonly && !peer_addr.sin_addr.s_addr) {
06681          continue;
06682       }
06683       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0)) {
06684          continue;
06685       }
06686 
06687       if (!ast_strlen_zero(peer->username))
06688          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06689       else
06690          ast_copy_string(name, peer->name, sizeof(name));
06691 
06692       encmethods_to_str(peer->encmethods, encmethods);
06693       retstatus = peer_status(peer, status, sizeof(status));
06694       if (retstatus > 0)
06695          online_peers++;
06696       else if (!retstatus)
06697          offline_peers++;
06698       else
06699          unmonitored_peers++;
06700 
06701       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06702 
06703       if (s) {
06704          astman_append(s,
06705             "Event: PeerEntry\r\n%s"
06706             "Channeltype: IAX2\r\n"
06707             "ObjectName: %s\r\n"
06708             "ChanObjectType: peer\r\n"
06709             "IPaddress: %s\r\n"
06710             "IPport: %d\r\n"
06711             "Dynamic: %s\r\n"
06712             "Trunk: %s\r\n"
06713             "Encryption: %s\r\n"
06714             "Status: %s\r\n\r\n",
06715             idtext,
06716             name,
06717             ast_sockaddr_stringify_addr(&peer->addr),
06718             ast_sockaddr_port(&peer->addr),
06719             ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06720             ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06721             peer->encmethods ? ast_str_buffer(encmethods) : "no",
06722             status);
06723       } else {
06724          ast_cli(fd, FORMAT, name,
06725             ast_sockaddr_stringify_addr(&peer->addr),
06726             ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06727             nm,
06728             ast_sockaddr_port(&peer->addr),
06729             ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : "   ",
06730             peer->encmethods ? "(E)" : "   ",
06731             status);
06732       }
06733       total_peers++;
06734    }
06735    ao2_iterator_destroy(&i);
06736 
06737    if (!s)
06738       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06739          total_peers, online_peers, offline_peers, unmonitored_peers);
06740 
06741    if (havepattern)
06742       regfree(&regexbuf);
06743 
06744    if (total)
06745       *total = total_peers;
06746 
06747    return RESULT_SUCCESS;
06748 #undef FORMAT
06749 #undef FORMAT2
06750 }

static void __reg_module ( void   )  [static]

Definition at line 14775 of file chan_iax2.c.

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

Definition at line 1460 of file chan_iax2.c.

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

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

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

Definition at line 7442 of file chan_iax2.c.

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

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

07444 {
07445    struct ast_frame f = { 0, };
07446    int res = 0;
07447 
07448    f.frametype = type;
07449    f.subclass.integer = command;
07450    f.datalen = datalen;
07451    f.src = __FUNCTION__;
07452    f.data.ptr = (void *) data;
07453 
07454    if ((res = queue_signalling(i, &f)) <= 0) {
07455       return res;
07456    }
07457 
07458    return iax2_send(i, &f, ts, seqno, now, transfer, final);
07459 }

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

Definition at line 1571 of file chan_iax2.c.

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

Referenced by send_lagrq().

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

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

Definition at line 1504 of file chan_iax2.c.

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

Referenced by send_ping().

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

static int __unload_module ( void   )  [static]

Definition at line 14278 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(), callno_limits, calltoken_ignores, cleanup_thread_list(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, iax_peercallno_pvts, iax_provision_unload(), iax_transfercallno_pvts, iaxs, iaxsl, netsock, network_change_event_unsubscribe(), outsock, papp, peercnts, peers, reload_firmware(), sched, timer, and users.

14279 {
14280    struct ast_context *con;
14281    int x;
14282 
14283    network_change_event_unsubscribe();
14284 
14285    ast_manager_unregister("IAXpeers");
14286    ast_manager_unregister("IAXpeerlist");
14287    ast_manager_unregister("IAXnetstats");
14288    ast_manager_unregister("IAXregistry");
14289    ast_unregister_application(papp);
14290    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14291    ast_unregister_switch(&iax2_switch);
14292    ast_channel_unregister(&iax2_tech);
14293 
14294    if (netthreadid != AST_PTHREADT_NULL) {
14295       pthread_cancel(netthreadid);
14296       pthread_kill(netthreadid, SIGURG);
14297       pthread_join(netthreadid, NULL);
14298    }
14299 
14300    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14301       if (iaxs[x]) {
14302          iax2_destroy(x);
14303       }
14304    }
14305 
14306    /* Call for all threads to halt */
14307    cleanup_thread_list(&idle_list);
14308    cleanup_thread_list(&active_list);
14309    cleanup_thread_list(&dynamic_list);
14310 
14311    ast_netsock_release(netsock);
14312    ast_netsock_release(outsock);
14313    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14314       if (iaxs[x]) {
14315          iax2_destroy(x);
14316       }
14317    }
14318    ast_manager_unregister( "IAXpeers" );
14319    ast_manager_unregister( "IAXpeerlist" );
14320    ast_manager_unregister( "IAXnetstats" );
14321    ast_manager_unregister( "IAXregistry" );
14322    ast_unregister_application(papp);
14323 #ifdef TEST_FRAMEWORK
14324    AST_TEST_UNREGISTER(test_iax2_peers_get);
14325    AST_TEST_UNREGISTER(test_iax2_users_get);
14326 #endif
14327    ast_data_unregister(NULL);
14328    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14329    ast_unregister_switch(&iax2_switch);
14330    ast_channel_unregister(&iax2_tech);
14331    delete_users();
14332    iax_provision_unload();
14333    reload_firmware(1);
14334 
14335    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14336       ast_mutex_destroy(&iaxsl[x]);
14337    }
14338 
14339    ao2_ref(peers, -1);
14340    ao2_ref(users, -1);
14341    ao2_ref(iax_peercallno_pvts, -1);
14342    ao2_ref(iax_transfercallno_pvts, -1);
14343    ao2_ref(peercnts, -1);
14344    ao2_ref(callno_limits, -1);
14345    ao2_ref(calltoken_ignores, -1);
14346    ao2_ref(callno_pool, -1);
14347    ao2_ref(callno_pool_trunk, -1);
14348    if (timer) {
14349       ast_timer_close(timer);
14350    }
14351    transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14352    sched = ast_sched_thread_destroy(sched);
14353 
14354    con = ast_context_find(regcontext);
14355    if (con)
14356       ast_context_destroy(con, "IAX2");
14357    ast_unload_realtime("iaxpeers");
14358    return 0;
14359 }

static void __unreg_module ( void   )  [static]

Definition at line 14775 of file chan_iax2.c.

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

Definition at line 13918 of file chan_iax2.c.

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

13919 {
13920    struct chan_iax2_pvt *pvt;
13921    unsigned int callno;
13922    int res = 0;
13923 
13924    if (!chan || chan->tech != &iax2_tech) {
13925       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13926       return -1;
13927    }
13928 
13929    callno = PTR_TO_CALLNO(chan->tech_pvt);
13930    ast_mutex_lock(&iaxsl[callno]);
13931    if (!(pvt = iaxs[callno])) {
13932       ast_mutex_unlock(&iaxsl[callno]);
13933       return -1;
13934    }
13935 
13936    if (!strcasecmp(args, "osptoken")) {
13937       ast_copy_string(buf, pvt->osptoken, buflen);
13938    } else if (!strcasecmp(args, "peerip")) {
13939       ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13940    } else if (!strcasecmp(args, "peername")) {
13941       ast_copy_string(buf, pvt->username, buflen);
13942    } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
13943       snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
13944    } else {
13945       res = -1;
13946    }
13947 
13948    ast_mutex_unlock(&iaxsl[callno]);
13949 
13950    return res;
13951 }

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

Definition at line 9777 of file chan_iax2.c.

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

09778 {
09779    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09780    AST_LIST_HEAD(, ast_var_t) *varlist;
09781    struct ast_var_t *var;
09782 
09783    if (!variablestore) {
09784       *buf = '\0';
09785       return 0;
09786    }
09787    varlist = variablestore->data;
09788 
09789    AST_LIST_LOCK(varlist);
09790    AST_LIST_TRAVERSE(varlist, var, entries) {
09791       if (strcmp(var->name, data) == 0) {
09792          ast_copy_string(buf, var->value, len);
09793          break;
09794       }
09795    }
09796    AST_LIST_UNLOCK(varlist);
09797    return 0;
09798 }

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

Definition at line 9800 of file chan_iax2.c.

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

09801 {
09802    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09803    AST_LIST_HEAD(, ast_var_t) *varlist;
09804    struct ast_var_t *var;
09805 
09806    if (!variablestore) {
09807       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09808       if (!variablestore) {
09809          ast_log(LOG_ERROR, "Memory allocation error\n");
09810          return -1;
09811       }
09812       varlist = ast_calloc(1, sizeof(*varlist));
09813       if (!varlist) {
09814          ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09815          return -1;
09816       }
09817 
09818       AST_LIST_HEAD_INIT(varlist);
09819       variablestore->data = varlist;
09820       variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09821       ast_channel_datastore_add(chan, variablestore);
09822    } else
09823       varlist = variablestore->data;
09824 
09825    AST_LIST_LOCK(varlist);
09826    AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09827       if (strcmp(var->name, data) == 0) {
09828          AST_LIST_REMOVE_CURRENT(entries);
09829          ast_var_delete(var);
09830          break;
09831       }
09832    }
09833    AST_LIST_TRAVERSE_SAFE_END;
09834    var = ast_var_assign(data, value);
09835    if (var)
09836       AST_LIST_INSERT_TAIL(varlist, var, entries);
09837    else
09838       ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09839    AST_LIST_UNLOCK(varlist);
09840    return 0;
09841 }

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

Definition at line 2496 of file chan_iax2.c.

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

Referenced by set_config().

02497 {
02498    struct addr_range tmp;
02499    struct addr_range *addr_range = NULL;
02500    struct ast_ha *ha = NULL;
02501    int error = 0;
02502 
02503    if (ast_strlen_zero(addr)) {
02504       ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02505       return -1;
02506    }
02507 
02508    ha = ast_append_ha("permit", addr, NULL, &error);
02509 
02510    /* check for valid config information */
02511    if (error) {
02512       ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02513       return -1;
02514    }
02515 
02516    ast_copy_ha(ha, &tmp.ha);
02517    /* find or create the addr_range */
02518    if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02519       ao2_lock(addr_range);
02520       addr_range->delme = 0;
02521       ao2_unlock(addr_range);
02522    } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02523       /* copy over config data into addr_range object */
02524       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
02525       ao2_link(calltoken_ignores, addr_range);
02526    } else {
02527       ast_free_ha(ha);
02528       return -1;
02529    }
02530 
02531    ast_free_ha(ha);
02532    ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02533 
02534    return 0;
02535 }

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

Definition at line 4712 of file chan_iax2.c.

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

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

04713 {
04714    /* first make sure their are two empty bytes left in ied->buf */
04715    if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04716       ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;  /* type */
04717       ied->buf[ied->pos++] = 0;   /* data size,  ZERO in this case */
04718       pvt->calltoken_ie_len = 2;
04719    }
04720 }

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

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

02149 {
02150    struct addr_range *lim1 = obj, *lim2 = arg;
02151    return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
02152          !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
02153          CMP_MATCH | CMP_STOP : 0;
02154 }

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

Definition at line 2133 of file chan_iax2.c.

References addr_range::delme.

Referenced by set_config_destroy().

02134 {
02135    struct addr_range *lim = obj;
02136    lim->delme = 1;
02137    return 0;
02138 }

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

Definition at line 2140 of file chan_iax2.c.

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

Referenced by load_objects().

02141 {
02142    const struct addr_range *lim = obj;
02143    struct sockaddr_in sin;
02144    ast_sockaddr_to_sin(&lim->ha.addr, &sin);
02145    return abs((int) sin.sin_addr.s_addr);
02146 }

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

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

02169 {
02170    struct addr_range *addr_range = obj;
02171    struct sockaddr_in *sin = arg;
02172    struct sockaddr_in ha_netmask_sin;
02173    struct sockaddr_in ha_addr_sin;
02174 
02175    ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin);
02176    ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin);
02177 
02178    if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) {
02179       return CMP_MATCH | CMP_STOP;
02180    }
02181    return 0;
02182 }

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

Definition at line 7500 of file chan_iax2.c.

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

Referenced by check_access().

07501 {
07502    while(con) {
07503       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07504          return -1;
07505       con = con->next;
07506    }
07507    return 0;
07508 }

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

Definition at line 7201 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, iax_rr::delay, iax_rr::dropped, chan_iax2_pvt::first_iax_message, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, chan_iax2_pvt::last_iax_message, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, MARK_IAX_SUBCLASS_TX, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, and chan_iax2_pvt::remote_rr.

Referenced by handle_cli_iax2_show_netstats(), and manager_iax2_show_netstats().

07202 {
07203    int x;
07204    int numchans = 0;
07205    char first_message[10] = { 0, };
07206    char last_message[10] = { 0, };
07207 #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"
07208 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07209    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07210       ast_mutex_lock(&iaxsl[x]);
07211       if (iaxs[x]) {
07212          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07213          jb_info jbinfo;
07214          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07215          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07216 
07217          if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07218             jb_getinfo(iaxs[x]->jb, &jbinfo);
07219             localjitter = jbinfo.jitter;
07220             localdelay = jbinfo.current - jbinfo.min;
07221             locallost = jbinfo.frames_lost;
07222             locallosspct = jbinfo.losspct/1000;
07223             localdropped = jbinfo.frames_dropped;
07224             localooo = jbinfo.frames_ooo;
07225          } else {
07226             localjitter = -1;
07227             localdelay = 0;
07228             locallost = -1;
07229             locallosspct = -1;
07230             localdropped = 0;
07231             localooo = -1;
07232          }
07233          if (s)
07234             astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07235                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07236                iaxs[x]->pingtime,
07237                localjitter,
07238                localdelay,
07239                locallost,
07240                locallosspct,
07241                localdropped,
07242                localooo,
07243                iaxs[x]->frames_received/1000,
07244                iaxs[x]->remote_rr.jitter,
07245                iaxs[x]->remote_rr.delay,
07246                iaxs[x]->remote_rr.losscnt,
07247                iaxs[x]->remote_rr.losspct,
07248                iaxs[x]->remote_rr.dropped,
07249                iaxs[x]->remote_rr.ooo,
07250                iaxs[x]->remote_rr.packets/1000,
07251                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07252                first_message,
07253                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07254                last_message);
07255          else
07256             ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07257                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07258                iaxs[x]->pingtime,
07259                localjitter,
07260                localdelay,
07261                locallost,
07262                locallosspct,
07263                localdropped,
07264                localooo,
07265                iaxs[x]->frames_received/1000,
07266                iaxs[x]->remote_rr.jitter,
07267                iaxs[x]->remote_rr.delay,
07268                iaxs[x]->remote_rr.losscnt,
07269                iaxs[x]->remote_rr.losspct,
07270                iaxs[x]->remote_rr.dropped,
07271                iaxs[x]->remote_rr.ooo,
07272                iaxs[x]->remote_rr.packets/1000,
07273                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07274                first_message,
07275                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07276                last_message);
07277          numchans++;
07278       }
07279       ast_mutex_unlock(&iaxsl[x]);
07280    }
07281 
07282    return numchans;
07283 }

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 
) [static]

Create new call, interface with the PBX core.

Definition at line 5695 of file chan_iax2.c.

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

Referenced by iax2_request(), and socket_process().

05696 {
05697    struct ast_channel *tmp;
05698    struct chan_iax2_pvt *i;
05699    struct ast_variable *v = NULL;
05700 
05701    if (!(i = iaxs[callno])) {
05702       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05703       return NULL;
05704    }
05705 
05706    /* Don't hold call lock */
05707    ast_mutex_unlock(&iaxsl[callno]);
05708    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);
05709    ast_mutex_lock(&iaxsl[callno]);
05710    if (i != iaxs[callno]) {
05711       if (tmp) {
05712          /* unlock and relock iaxsl[callno] to preserve locking order */
05713          ast_mutex_unlock(&iaxsl[callno]);
05714          tmp = ast_channel_release(tmp);
05715          ast_mutex_lock(&iaxsl[callno]);
05716       }
05717       return NULL;
05718    }
05719    iax2_ami_channelupdate(i);
05720    if (!tmp)
05721       return NULL;
05722    tmp->tech = &iax2_tech;
05723    /* We can support any format by default, until we get restricted */
05724    tmp->nativeformats = capability;
05725    tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05726    tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05727    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05728 
05729    if (!ast_strlen_zero(i->parkinglot))
05730       ast_string_field_set(tmp, parkinglot, i->parkinglot);
05731    /* Don't use ast_set_callerid() here because it will
05732     * generate a NewCallerID event before the NewChannel event */
05733    if (!ast_strlen_zero(i->ani)) {
05734       tmp->caller.ani.number.valid = 1;
05735       tmp->caller.ani.number.str = ast_strdup(i->ani);
05736    } else if (!ast_strlen_zero(i->cid_num)) {
05737       tmp->caller.ani.number.valid = 1;
05738       tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05739    }
05740    tmp->dialed.number.str = ast_strdup(i->dnid);
05741    if (!ast_strlen_zero(i->rdnis)) {
05742       tmp->redirecting.from.number.valid = 1;
05743       tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05744    }
05745    tmp->caller.id.name.presentation = i->calling_pres;
05746    tmp->caller.id.number.presentation = i->calling_pres;
05747    tmp->caller.id.number.plan = i->calling_ton;
05748    tmp->dialed.transit_network_select = i->calling_tns;
05749    if (!ast_strlen_zero(i->language))
05750       ast_string_field_set(tmp, language, i->language);
05751    if (!ast_strlen_zero(i->accountcode))
05752       ast_string_field_set(tmp, accountcode, i->accountcode);
05753    if (i->amaflags)
05754       tmp->amaflags = i->amaflags;
05755    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05756    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05757    if (i->adsi)
05758       tmp->adsicpe = i->peeradsicpe;
05759    else
05760       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05761    i->owner = tmp;
05762    i->capability = capability;
05763 
05764    /* Set inherited variables */
05765    if (i->vars) {
05766       for (v = i->vars ; v ; v = v->next)
05767          pbx_builtin_setvar_helper(tmp, v->name, v->value);
05768    }
05769    if (i->iaxvars) {
05770       struct ast_datastore *variablestore;
05771       struct ast_variable *var, *prev = NULL;
05772       AST_LIST_HEAD(, ast_var_t) *varlist;
05773       ast_debug(1, "Loading up the channel with IAXVARs\n");
05774       varlist = ast_calloc(1, sizeof(*varlist));
05775       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05776       if (variablestore && varlist) {
05777          variablestore->data = varlist;
05778          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05779          AST_LIST_HEAD_INIT(varlist);
05780          for (var = i->iaxvars; var; var = var->next) {
05781             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05782             if (prev)
05783                ast_free(prev);
05784             prev = var;
05785             if (!newvar) {
05786                /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
05787                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05788             } else {
05789                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05790             }
05791          }
05792          if (prev)
05793             ast_free(prev);
05794          i->iaxvars = NULL;
05795          ast_channel_datastore_add(i->owner, variablestore);
05796       } else {
05797          if (variablestore) {
05798             ast_datastore_free(variablestore);
05799          }
05800          if (varlist) {
05801             ast_free(varlist);
05802          }
05803       }
05804    }
05805 
05806    if (state != AST_STATE_DOWN) {
05807       if (ast_pbx_start(tmp)) {
05808          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05809          ast_hangup(tmp);
05810          i->owner = NULL;
05811          return NULL;
05812       }
05813    }
05814 
05815    ast_module_ref(ast_module_info->self);
05816    return tmp;
05817 }

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

Definition at line 3542 of file chan_iax2.c.

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and transmit_frame().

03543 {
03544 #ifdef SCHED_MULTITHREADED
03545    if (schedule_action(__attempt_transmit, data))
03546 #endif      
03547       __attempt_transmit(data);
03548    return 0;
03549 }

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

Definition at line 8987 of file chan_iax2.c.

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

Referenced by socket_process().

08988 {
08989    /* Schedule sending the authentication failure in one second, to prevent
08990       guessing */
08991    if (iaxs[callno]) {
08992       iaxs[callno]->authfail = failcode;
08993       if (delayreject) {
08994          iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 
08995             sched, 1000, auth_reject, (void *)(long)callno);
08996       } else
08997          auth_reject((void *)(long)callno);
08998    }
08999    return 0;
09000 }

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

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

08974 {
08975    int callno = (int)(long)(data);
08976    ast_mutex_lock(&iaxsl[callno]);
08977    if (iaxs[callno])
08978       iaxs[callno]->authid = -1;
08979    ast_mutex_unlock(&iaxsl[callno]);
08980 #ifdef SCHED_MULTITHREADED
08981    if (schedule_action(__auth_reject, data))
08982 #endif      
08983       __auth_reject(data);
08984    return 0;
08985 }

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

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

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

08073 {
08074    int res = -1;
08075    int x;
08076    if (!ast_strlen_zero(keyn)) {
08077       if (!(authmethods & IAX_AUTH_RSA)) {
08078          if (ast_strlen_zero(secret)) 
08079             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));
08080       } else if (ast_strlen_zero(challenge)) {
08081          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08082       } else {
08083          char sig[256];
08084          struct ast_key *key;
08085          key = ast_key_get(keyn, AST_KEY_PRIVATE);
08086          if (!key) {
08087             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08088          } else {
08089             if (ast_sign(key, (char*)challenge, sig)) {
08090                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08091                res = -1;
08092             } else {
08093                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08094                res = 0;
08095             }
08096          }
08097       }
08098    } 
08099    /* Fall back */
08100    if (res && !ast_strlen_zero(secret)) {
08101       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08102          struct MD5Context md5;
08103          unsigned char digest[16];
08104          char digres[128];
08105          MD5Init(&md5);
08106          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08107          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08108          MD5Final(digest, &md5);
08109          /* If they support md5, authenticate with it.  */
08110          for (x=0;x<16;x++)
08111             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
08112          if (pvt) {
08113             build_encryption_keys(digest, pvt);
08114          }
08115          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08116          res = 0;
08117       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08118          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08119          res = 0;
08120       } else
08121          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08122    }
08123    return res;
08124 }

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 8130 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, chan_iax2_pvt::callno, iax_ies::challenge, ast_datastore::data, DATASTORE_INHERIT_FOREVER, iax_ies::encmethods, ast_var_t::entries, iax2_variable_datastore_info, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_FORCE_ENCRYPT, IAX_KEYPOPULATED, iaxs, iaxsl, ast_datastore::inheritance, LOG_ERROR, LOG_NOTICE, iax2_peer::mask, merge_encryption(), iax2_peer::name, iax2_peer::outkey, peer_unref(), peers, realtime_peer(), iax2_peer::secret, send_command(), iax2_peer::username, iax_ies::username, var, and iax_ies::vars.

Referenced by socket_process().

08131 {
08132    struct iax2_peer *peer = NULL;
08133    /* Start pessimistic */
08134    int res = -1;
08135    int authmethods = 0;
08136    struct iax_ie_data ied;
08137    uint16_t callno = p->callno;
08138 
08139    memset(&ied, 0, sizeof(ied));
08140    
08141    if (ies->username)
08142       ast_string_field_set(p, username, ies->username);
08143    if (ies->challenge)
08144       ast_string_field_set(p, challenge, ies->challenge);
08145    if (ies->authmethods)
08146       authmethods = ies->authmethods;
08147    if (authmethods & IAX_AUTH_MD5)
08148       merge_encryption(p, ies->encmethods);
08149    else
08150       p->encmethods = 0;
08151 
08152    /* Check for override RSA authentication first */
08153    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08154       /* Normal password authentication */
08155       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08156    } else {
08157       struct ao2_iterator i = ao2_iterator_init(peers, 0);
08158       while ((peer = ao2_iterator_next(&i))) {
08159          struct sockaddr_in peer_addr;
08160 
08161          ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08162 
08163          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
08164              /* No peer specified at our end, or this is the peer */
08165              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08166              /* No username specified in peer rule, or this is the right username */
08167              && (!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)))
08168              /* No specified host, or this is our host */
08169             ) {
08170             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08171             if (!res) {
08172                peer_unref(peer);
08173                break;
08174             }
08175          }
08176          peer_unref(peer);
08177       }
08178       ao2_iterator_destroy(&i);
08179       if (!peer) {
08180          /* We checked our list and didn't find one.  It's unlikely, but possible, 
08181             that we're trying to authenticate *to* a realtime peer */
08182          const char *peer_name = ast_strdupa(p->peer);
08183          ast_mutex_unlock(&iaxsl[callno]);
08184          if ((peer = realtime_peer(peer_name, NULL))) {
08185             ast_mutex_lock(&iaxsl[callno]);
08186             if (!(p = iaxs[callno])) {
08187                peer_unref(peer);
08188                return -1;
08189             }
08190             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08191             peer_unref(peer);
08192          }
08193          if (!peer) {
08194             ast_mutex_lock(&iaxsl[callno]);
08195             if (!(p = iaxs[callno]))
08196                return -1;
08197          }
08198       }
08199    }
08200 
08201    if (ies->encmethods) {
08202       ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08203    } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08204       ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
08205       return -1;             /* if force encryption is yes, and no encryption methods, then return -1 to hangup */
08206    }
08207    if (!res) {
08208       struct ast_datastore *variablestore;
08209       struct ast_variable *var, *prev = NULL;
08210       AST_LIST_HEAD(, ast_var_t) *varlist;
08211       varlist = ast_calloc(1, sizeof(*varlist));
08212       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08213       if (variablestore && varlist && p->owner) {
08214          variablestore->data = varlist;
08215          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08216          AST_LIST_HEAD_INIT(varlist);
08217          for (var = ies->vars; var; var = var->next) {
08218             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08219             if (prev)
08220                ast_free(prev);
08221             prev = var;
08222             if (!newvar) {
08223                /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */
08224                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08225             } else {
08226                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08227             }
08228          }
08229          if (prev)
08230             ast_free(prev);
08231          ies->vars = NULL;
08232          ast_channel_datastore_add(p->owner, variablestore);
08233       } else {
08234          if (p->owner)
08235             ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08236          if (variablestore)
08237             ast_datastore_free(variablestore);
08238          if (varlist)
08239             ast_free(varlist);
08240       }
08241    }
08242 
08243    if (!res)
08244       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08245    return res;
08246 }

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 7778 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, chan_iax2_pvt::challenge, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, iaxs, OBJ_POINTER, send_command(), send_command_final(), user, user_unref(), chan_iax2_pvt::username, and users.

Referenced by socket_process().

07779 {
07780    struct iax_ie_data ied;
07781    int res = -1, authreq_restrict = 0;
07782    char challenge[10];
07783    struct chan_iax2_pvt *p = iaxs[call_num];
07784 
07785    memset(&ied, 0, sizeof(ied));
07786 
07787    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
07788    if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07789       struct iax2_user *user, tmp_user = {
07790          .name = p->username, 
07791       };
07792 
07793       user = ao2_find(users, &tmp_user, OBJ_POINTER);
07794       if (user) {
07795          if (user->curauthreq == user->maxauthreq)
07796             authreq_restrict = 1;
07797          else
07798             user->curauthreq++;
07799          user = user_unref(user);
07800       }
07801    }
07802 
07803    /* If the AUTHREQ limit test failed, send back an error */
07804    if (authreq_restrict) {
07805       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07806       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07807       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07808       return 0;
07809    }
07810 
07811    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07812    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07813       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07814       ast_string_field_set(p, challenge, challenge);
07815       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
07816       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07817    }
07818    if (p->encmethods)
07819       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07820 
07821    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07822 
07823    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07824 
07825    if (p->encmethods)
07826       ast_set_flag64(p, IAX_ENCRYPTED);
07827 
07828    return res;
07829 }

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

Definition at line 7831 of file chan_iax2.c.

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

Referenced by socket_process().

07832 {
07833    char requeststr[256];
07834    char md5secret[256] = "";
07835    char secret[256] = "";
07836    char rsasecret[256] = "";
07837    int res = -1; 
07838    int x;
07839    struct iax2_user *user, tmp_user = {
07840       .name = p->username, 
07841    };
07842 
07843    if (p->authrej) {
07844       return res;
07845    }
07846    user = ao2_find(users, &tmp_user, OBJ_POINTER);
07847    if (user) {
07848       if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07849          ast_atomic_fetchadd_int(&user->curauthreq, -1);
07850          ast_clear_flag64(p, IAX_MAXAUTHREQ);
07851       }
07852       ast_string_field_set(p, host, user->name);
07853       user = user_unref(user);
07854    }
07855    if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 
07856       ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.");
07857       return res;
07858    }
07859    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07860       return res;
07861    if (ies->password)
07862       ast_copy_string(secret, ies->password, sizeof(secret));
07863    if (ies->md5_result)
07864       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07865    if (ies->rsa_result)
07866       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07867    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07868       struct ast_key *key;
07869       char *keyn;
07870       char tmpkey[256];
07871       char *stringp=NULL;
07872       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07873       stringp=tmpkey;
07874       keyn = strsep(&stringp, ":");
07875       while(keyn) {
07876          key = ast_key_get(keyn, AST_KEY_PUBLIC);
07877          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07878             res = 0;
07879             break;
07880          } else if (!key)
07881             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07882          keyn = strsep(&stringp, ":");
07883       }
07884    } else if (p->authmethods & IAX_AUTH_MD5) {
07885       struct MD5Context md5;
07886       unsigned char digest[16];
07887       char *tmppw, *stringp;
07888       
07889       tmppw = ast_strdupa(p->secret);
07890       stringp = tmppw;
07891       while((tmppw = strsep(&stringp, ";"))) {
07892          MD5Init(&md5);
07893          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07894          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07895          MD5Final(digest, &md5);
07896          /* If they support md5, authenticate with it.  */
07897          for (x=0;x<16;x++)
07898             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
07899          if (!strcasecmp(requeststr, md5secret)) {
07900             res = 0;
07901             break;
07902          }
07903       }
07904    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07905       if (!strcmp(secret, p->secret))
07906          res = 0;
07907    }
07908    return res;
07909 }

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

Definition at line 4651 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

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

04652 {
04653 #ifdef SCHED_MULTITHREADED
04654    if (schedule_action(__auto_congest, data))
04655 #endif      
04656       __auto_congest(data);
04657    return 0;
04658 }

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

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

09018 {
09019    int callno = (int)(long)(data);
09020    ast_mutex_lock(&iaxsl[callno]);
09021    if (iaxs[callno]) {
09022       iaxs[callno]->autoid = -1;
09023    }
09024    ast_mutex_unlock(&iaxsl[callno]);
09025 #ifdef SCHED_MULTITHREADED
09026    if (schedule_action(__auto_hangup, data))
09027 #endif      
09028       __auto_hangup(data);
09029    return 0;
09030 }

static void build_callno_limits ( struct ast_variable v  )  [static]

Definition at line 2441 of file chan_iax2.c.

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

Referenced by set_config().

02442 {
02443    struct addr_range *addr_range = NULL;
02444    struct addr_range tmp;
02445    struct ast_ha *ha;
02446    int limit;
02447    int error;
02448    int found;
02449 
02450    for (; v; v = v->next) {
02451       limit = -1;
02452       error = 0;
02453       found = 0;
02454       ha = ast_append_ha("permit", v->name, NULL, &error);
02455 
02456       /* check for valid config information */
02457       if (error) {
02458          ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02459          continue;
02460       } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02461          ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02462          ast_free_ha(ha);
02463          continue;
02464       }
02465 
02466       ast_copy_ha(ha, &tmp.ha);
02467       /* find or create the addr_range */
02468       if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02469          ao2_lock(addr_range);
02470          found = 1;
02471       } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02472          ast_free_ha(ha);
02473          return; /* out of memory */
02474       }
02475 
02476       /* copy over config data into addr_range object */
02477       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
02478       ast_free_ha(ha); /* cleanup the tmp ha */
02479       addr_range->limit = limit;
02480       addr_range->delme = 0;
02481 
02482       /* cleanup */
02483       if (found) {
02484          ao2_unlock(addr_range);
02485       } else {
02486          ao2_link(callno_limits, addr_range);
02487       }
02488       ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02489    }
02490 }

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

Definition at line 12195 of file chan_iax2.c.

References ast_calloc, and ast_copy_string().

Referenced by build_user().

12196 {
12197    struct iax2_context *con;
12198 
12199    if ((con = ast_calloc(1, sizeof(*con))))
12200       ast_copy_string(con->context, context, sizeof(con->context));
12201    
12202    return con;
12203 }

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

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

06160 {
06161    /* it is required to hold the corresponding decrypt key to our encrypt key
06162     * in the pvt struct because queued frames occasionally need to be decrypted and
06163     * re-encrypted when updated for a retransmission */
06164    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06165    ast_aes_set_encrypt_key(digest, &pvt->ecx);
06166    ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06167 }

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

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

06154 {
06155    build_ecx_key(digest, pvt);
06156    ast_aes_set_decrypt_key(digest, &pvt->dcx);
06157 }

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

Create peer structure based on configuration.

Definition at line 12346 of file chan_iax2.c.

References 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(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cid_name, cid_num, context, iax2_peer::dbsecret, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, inet_aton(), ast_variable::lineno, LOG_WARNING, mailbox, mwi_event_cb(), ast_variable::name, iax2_peer::name, ast_variable::next, OBJ_POINTER, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), iax2_peer::peercontext, peers, prefs, S_OR, sched, secret, ast_sockaddr::ss, strsep(), timer, unlink_peer(), ast_variable::value, and zonetag.

12347 {
12348    struct iax2_peer *peer = NULL;
12349    struct ast_ha *oldha = NULL;
12350    int maskfound = 0;
12351    int found = 0;
12352    int firstpass = 1;
12353    struct iax2_peer tmp_peer = {
12354       .name = name,
12355    };
12356 
12357    if (!temponly) {
12358       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
12359       if (peer && !ast_test_flag64(peer, IAX_DELME))
12360          firstpass = 0;
12361    }
12362 
12363    if (peer) {
12364       found++;
12365       if (firstpass) {
12366          oldha = peer->ha;
12367          peer->ha = NULL;
12368       }
12369       unlink_peer(peer);
12370    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12371       peer->expire = -1;
12372       peer->pokeexpire = -1;
12373       peer->sockfd = defaultsockfd;
12374       peer->addr.ss.ss_family = AF_INET;
12375       if (ast_string_field_init(peer, 32))
12376          peer = peer_unref(peer);
12377    }
12378 
12379    if (peer) {
12380       if (firstpass) {
12381          ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12382          peer->encmethods = iax2_encryption;
12383          peer->adsi = adsi;
12384          ast_string_field_set(peer,secret,"");
12385          if (!found) {
12386             ast_string_field_set(peer, name, name);
12387             ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12388             peer->expiry = min_reg_expire;
12389          }
12390          peer->prefs = prefs;
12391          peer->capability = iax2_capability;
12392          peer->smoothing = 0;
12393          peer->pokefreqok = DEFAULT_FREQ_OK;
12394          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12395          peer->maxcallno = 0;
12396          peercnt_modify(0, 0, &peer->addr);
12397          peer->calltoken_required = CALLTOKEN_DEFAULT;
12398          ast_string_field_set(peer,context,"");
12399          ast_string_field_set(peer,peercontext,"");
12400          ast_clear_flag64(peer, IAX_HASCALLERID);
12401          ast_string_field_set(peer, cid_name, "");
12402          ast_string_field_set(peer, cid_num, "");
12403          ast_string_field_set(peer, mohinterpret, mohinterpret);
12404          ast_string_field_set(peer, mohsuggest, mohsuggest);
12405       }
12406 
12407       if (!v) {
12408          v = alt;
12409          alt = NULL;
12410       }
12411       while(v) {
12412          if (!strcasecmp(v->name, "secret")) {
12413             ast_string_field_set(peer, secret, v->value);
12414          } else if (!strcasecmp(v->name, "mailbox")) {
12415             ast_string_field_set(peer, mailbox, v->value);
12416          } else if (!strcasecmp(v->name, "hasvoicemail")) {
12417             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12418                ast_string_field_set(peer, mailbox, name);
12419             }
12420          } else if (!strcasecmp(v->name, "mohinterpret")) {
12421             ast_string_field_set(peer, mohinterpret, v->value);
12422          } else if (!strcasecmp(v->name, "mohsuggest")) {
12423             ast_string_field_set(peer, mohsuggest, v->value);
12424          } else if (!strcasecmp(v->name, "dbsecret")) {
12425             ast_string_field_set(peer, dbsecret, v->value);
12426          } else if (!strcasecmp(v->name, "trunk")) {
12427             ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 
12428             if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12429                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12430                ast_clear_flag64(peer, IAX_TRUNK);
12431             }
12432          } else if (!strcasecmp(v->name, "auth")) {
12433             peer->authmethods = get_auth_methods(v->value);
12434          } else if (!strcasecmp(v->name, "encryption")) {
12435             peer->encmethods |= get_encrypt_methods(v->value);
12436             if (!peer->encmethods) {
12437                ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12438             }
12439          } else if (!strcasecmp(v->name, "forceencryption")) {
12440             if (ast_false(v->value)) {
12441                ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12442             } else {
12443                peer->encmethods |= get_encrypt_methods(v->value);
12444                if (peer->encmethods) {
12445                   ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12446                }
12447             }
12448          } else if (!strcasecmp(v->name, "transfer")) {
12449             if (!strcasecmp(v->value, "mediaonly")) {
12450                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12451             } else if (ast_true(v->value)) {
12452                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12453             } else
12454                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12455          } else if (!strcasecmp(v->name, "jitterbuffer")) {
12456             ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12457          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12458             ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12459          } else if (!strcasecmp(v->name, "host")) {
12460             if (!strcasecmp(v->value, "dynamic")) {
12461                /* They'll register with us */
12462                ast_set_flag64(peer, IAX_DYNAMIC);
12463                if (!found) {
12464                   /* Initialize stuff iff we're not found, otherwise
12465                      we keep going with what we had */
12466                   if (ast_sockaddr_port(&peer->addr)) {
12467                      peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12468                   }
12469                   ast_sockaddr_setnull(&peer->addr);
12470                }
12471             } else {
12472                /* Non-dynamic.  Make sure we become that way if we're not */
12473                ast_sched_thread_del(sched, peer->expire);
12474                ast_clear_flag64(peer, IAX_DYNAMIC);
12475                if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12476                   return peer_unref(peer);
12477                if (!ast_sockaddr_port(&peer->addr)) {
12478                   ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12479                }
12480             }
12481             if (!maskfound)
12482                inet_aton("255.255.255.255", &peer->mask);
12483          } else if (!strcasecmp(v->name, "defaultip")) {
12484             struct ast_sockaddr peer_defaddr_tmp;
12485 
12486             peer_defaddr_tmp.ss.ss_family = AF_INET;
12487             if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12488                return peer_unref(peer);
12489             }
12490             ast_sockaddr_to_sin(&peer_defaddr_tmp,
12491                       &peer->defaddr);
12492          } else if (!strcasecmp(v->name, "sourceaddress")) {
12493             peer_set_srcaddr(peer, v->value);
12494          } else if (!strcasecmp(v->name, "permit") ||
12495                   !strcasecmp(v->name, "deny")) {
12496             peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12497          } else if (!strcasecmp(v->name, "mask")) {
12498             maskfound++;
12499             inet_aton(v->value, &peer->mask);
12500          } else if (!strcasecmp(v->name, "context")) {
12501             ast_string_field_set(peer, context, v->value);
12502          } else if (!strcasecmp(v->name, "regexten")) {
12503             ast_string_field_set(peer, regexten, v->value);
12504          } else if (!strcasecmp(v->name, "peercontext")) {
12505             ast_string_field_set(peer, peercontext, v->value);
12506          } else if (!strcasecmp(v->name, "port")) {
12507             if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12508                peer->defaddr.sin_port = htons(atoi(v->value));
12509             } else {
12510                ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12511             }
12512          } else if (!strcasecmp(v->name, "username")) {
12513             ast_string_field_set(peer, username, v->value);
12514          } else if (!strcasecmp(v->name, "allow")) {
12515             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12516          } else if (!strcasecmp(v->name, "disallow")) {
12517             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12518          } else if (!strcasecmp(v->name, "callerid")) {
12519             if (!ast_strlen_zero(v->value)) {
12520                char name2[80];
12521                char num2[80];
12522                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12523                ast_string_field_set(peer, cid_name, name2);
12524                ast_string_field_set(peer, cid_num, num2);
12525             } else {
12526                ast_string_field_set(peer, cid_name, "");
12527                ast_string_field_set(peer, cid_num, "");
12528             }
12529             ast_set_flag64(peer, IAX_HASCALLERID);
12530          } else if (!strcasecmp(v->name, "fullname")) {
12531             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12532             ast_set_flag64(peer, IAX_HASCALLERID);
12533          } else if (!strcasecmp(v->name, "cid_number")) {
12534             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12535             ast_set_flag64(peer, IAX_HASCALLERID);
12536          } else if (!strcasecmp(v->name, "sendani")) {
12537             ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12538          } else if (!strcasecmp(v->name, "inkeys")) {
12539             ast_string_field_set(peer, inkeys, v->value);
12540          } else if (!strcasecmp(v->name, "outkey")) {
12541             ast_string_field_set(peer, outkey, v->value);
12542          } else if (!strcasecmp(v->name, "qualify")) {
12543             if (!strcasecmp(v->value, "no")) {
12544                peer->maxms = 0;
12545             } else if (!strcasecmp(v->value, "yes")) {
12546                peer->maxms = DEFAULT_MAXMS;
12547             } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12548                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);
12549                peer->maxms = 0;
12550             }
12551          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12552             peer->smoothing = ast_true(v->value);
12553          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12554             if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12555                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);
12556             }
12557          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12558             if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12559                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);
12560             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
12561          } else if (!strcasecmp(v->name, "timezone")) {
12562             ast_string_field_set(peer, zonetag, v->value);
12563          } else if (!strcasecmp(v->name, "adsi")) {
12564             peer->adsi = ast_true(v->value);
12565          } else if (!strcasecmp(v->name, "connectedline")) {
12566             if (ast_true(v->value)) {
12567                ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12568             } else if (!strcasecmp(v->value, "send")) {
12569                ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12570                ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12571             } else if (!strcasecmp(v->value, "receive")) {
12572                ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12573                ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12574             } else {
12575                ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12576             }
12577          } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12578             if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12579                ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12580             } else {
12581                peercnt_modify(1, peer->maxcallno, &peer->addr);
12582             }
12583          } else if (!strcasecmp(v->name, "requirecalltoken")) {
12584             /* default is required unless in optional ip list */
12585             if (ast_false(v->value)) {
12586                peer->calltoken_required = CALLTOKEN_NO;
12587             } else if (!strcasecmp(v->value, "auto")) {
12588                peer->calltoken_required = CALLTOKEN_AUTO;
12589             } else if (ast_true(v->value)) {
12590                peer->calltoken_required = CALLTOKEN_YES;
12591             } else {
12592                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12593             }
12594          } /* else if (strcasecmp(v->name,"type")) */
12595          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
12596          v = v->next;
12597          if (!v) {
12598             v = alt;
12599             alt = NULL;
12600          }
12601       }
12602       if (!peer->authmethods)
12603          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12604       ast_clear_flag64(peer, IAX_DELME);
12605    }
12606 
12607    if (oldha)
12608       ast_free_ha(oldha);
12609 
12610    if (!ast_strlen_zero(peer->mailbox)) {
12611       char *mailbox, *context;
12612       context = mailbox = ast_strdupa(peer->mailbox);
12613       strsep(&context, "@");
12614       if (ast_strlen_zero(context))
12615          context = "default";
12616       peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12617          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12618          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12619          AST_EVENT_IE_END);
12620    }
12621 
12622    return peer;
12623 }

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

Definition at line 6143 of file chan_iax2.c.

References ast_random().

Referenced by build_ecx_key(), and update_packet().

06144 {
06145    long tmp;
06146    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06147       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06148       buf += sizeof(tmp);
06149       len -= sizeof(tmp);
06150    }
06151 }

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

Create in-memory user structure from configuration.

Definition at line 12639 of file chan_iax2.c.

References 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(), build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cid_name, cid_num, cleanup(), iax2_user::dbsecret, format, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_IMMEDIATE, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, ast_variable::lineno, LOG_WARNING, ast_variable::name, iax2_user::name, ast_variable::next, OBJ_POINTER, parkinglot, prefs, secret, timer, user, user_destructor(), user_unref(), users, and ast_variable::value.

12640 {
12641    struct iax2_user *user = NULL;
12642    struct iax2_context *con, *conl = NULL;
12643    struct ast_ha *oldha = NULL;
12644    struct iax2_context *oldcon = NULL;
12645    int format;
12646    int firstpass=1;
12647    int oldcurauthreq = 0;
12648    char *varname = NULL, *varval = NULL;
12649    struct ast_variable *tmpvar = NULL;
12650    struct iax2_user tmp_user = {
12651       .name = name,
12652    };
12653 
12654    if (!temponly) {
12655       user = ao2_find(users, &tmp_user, OBJ_POINTER);
12656       if (user && !ast_test_flag64(user, IAX_DELME))
12657          firstpass = 0;
12658    }
12659 
12660    if (user) {
12661       if (firstpass) {
12662          oldcurauthreq = user->curauthreq;
12663          oldha = user->ha;
12664          oldcon = user->contexts;
12665          user->ha = NULL;
12666          user->contexts = NULL;
12667       }
12668       /* Already in the list, remove it and it will be added back (or FREE'd) */
12669       ao2_unlink(users, user);
12670    } else {
12671       user = ao2_alloc(sizeof(*user), user_destructor);
12672    }
12673    
12674    if (user) {
12675       if (firstpass) {
12676          ast_string_field_free_memory(user);
12677          memset(user, 0, sizeof(struct iax2_user));
12678          if (ast_string_field_init(user, 32)) {
12679             user = user_unref(user);
12680             goto cleanup;
12681          }
12682          user->maxauthreq = maxauthreq;
12683          user->curauthreq = oldcurauthreq;
12684          user->prefs = prefs;
12685          user->capability = iax2_capability;
12686          user->encmethods = iax2_encryption;
12687          user->adsi = adsi;
12688          user->calltoken_required = CALLTOKEN_DEFAULT;
12689          ast_string_field_set(user, name, name);
12690          ast_string_field_set(user, language, language);
12691          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);
12692          ast_clear_flag64(user, IAX_HASCALLERID);
12693          ast_string_field_set(user, cid_name, "");
12694          ast_string_field_set(user, cid_num, "");
12695          ast_string_field_set(user, accountcode, accountcode);
12696          ast_string_field_set(user, mohinterpret, mohinterpret);
12697          ast_string_field_set(user, mohsuggest, mohsuggest);
12698       }
12699       if (!v) {
12700          v = alt;
12701          alt = NULL;
12702       }
12703       while(v) {
12704          if (!strcasecmp(v->name, "context")) {
12705             con = build_context(v->value);
12706             if (con) {
12707                if (conl)
12708                   conl->next = con;
12709                else
12710                   user->contexts = con;
12711                conl = con;
12712             }
12713          } else if (!strcasecmp(v->name, "permit") ||
12714                   !strcasecmp(v->name, "deny")) {
12715             user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12716          } else if (!strcasecmp(v->name, "setvar")) {
12717             varname = ast_strdupa(v->value);
12718             if (varname && (varval = strchr(varname,'='))) {
12719                *varval = '\0';
12720                varval++;
12721                if((tmpvar = ast_variable_new(varname, varval, ""))) {
12722                   tmpvar->next = user->vars; 
12723                   user->vars = tmpvar;
12724                }
12725             }
12726          } else if (!strcasecmp(v->name, "allow")) {
12727             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12728          } else if (!strcasecmp(v->name, "disallow")) {
12729             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12730          } else if (!strcasecmp(v->name, "trunk")) {
12731             ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 
12732             if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
12733                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12734                ast_clear_flag64(user, IAX_TRUNK);
12735             }
12736          } else if (!strcasecmp(v->name, "auth")) {
12737             user->authmethods = get_auth_methods(v->value);
12738          } else if (!strcasecmp(v->name, "encryption")) {
12739             user->encmethods |= get_encrypt_methods(v->value);
12740             if (!user->encmethods) {
12741                ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12742             }
12743          } else if (!strcasecmp(v->name, "forceencryption")) {
12744             if (ast_false(v->value)) {
12745                ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12746             } else {
12747                user->encmethods |= get_encrypt_methods(v->value);
12748                if (user->encmethods) {
12749                   ast_set_flag64(user, IAX_FORCE_ENCRYPT);
12750                }
12751             }
12752          } else if (!strcasecmp(v->name, "transfer")) {
12753             if (!strcasecmp(v->value, "mediaonly")) {
12754                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12755             } else if (ast_true(v->value)) {
12756                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12757             } else
12758                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12759          } else if (!strcasecmp(v->name, "codecpriority")) {
12760             if(!strcasecmp(v->value, "caller"))
12761                ast_set_flag64(user, IAX_CODEC_USER_FIRST);
12762             else if(!strcasecmp(v->value, "disabled"))
12763                ast_set_flag64(user, IAX_CODEC_NOPREFS);
12764             else if(!strcasecmp(v->value, "reqonly")) {
12765                ast_set_flag64(user, IAX_CODEC_NOCAP);
12766                ast_set_flag64(user, IAX_CODEC_NOPREFS);
12767             }
12768          } else if (!strcasecmp(v->name, "immediate")) {
12769             ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
12770          } else if (!strcasecmp(v->name, "jitterbuffer")) {
12771             ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
12772          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12773             ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12774          } else if (!strcasecmp(v->name, "dbsecret")) {
12775             ast_string_field_set(user, dbsecret, v->value);
12776          } else if (!strcasecmp(v->name, "secret")) {
12777             if (!ast_strlen_zero(user->secret)) {
12778                char *old = ast_strdupa(user->secret);
12779 
12780                ast_string_field_build(user, secret, "%s;%s", old, v->value);
12781             } else
12782                ast_string_field_set(user, secret, v->value);
12783          } else if (!strcasecmp(v->name, "callerid")) {
12784             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12785                char name2[80];
12786                char num2[80];
12787                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12788                ast_string_field_set(user, cid_name, name2);
12789                ast_string_field_set(user, cid_num, num2);
12790                ast_set_flag64(user, IAX_HASCALLERID);
12791             } else {
12792                ast_clear_flag64(user, IAX_HASCALLERID);
12793                ast_string_field_set(user, cid_name, "");
12794                ast_string_field_set(user, cid_num, "");
12795             }
12796          } else if (!strcasecmp(v->name, "fullname")) {
12797             if (!ast_strlen_zero(v->value)) {
12798                ast_string_field_set(user, cid_name, v->value);
12799                ast_set_flag64(user, IAX_HASCALLERID);
12800             } else {
12801                ast_string_field_set(user, cid_name, "");
12802                if (ast_strlen_zero(user->cid_num))
12803                   ast_clear_flag64(user, IAX_HASCALLERID);
12804             }
12805          } else if (!strcasecmp(v->name, "cid_number")) {
12806             if (!ast_strlen_zero(v->value)) {
12807                ast_string_field_set(user, cid_num, v->value);
12808                ast_set_flag64(user, IAX_HASCALLERID);
12809             } else {
12810                ast_string_field_set(user, cid_num, "");
12811                if (ast_strlen_zero(user->cid_name))
12812                   ast_clear_flag64(user, IAX_HASCALLERID);
12813             }
12814          } else if (!strcasecmp(v->name, "accountcode")) {
12815             ast_string_field_set(user, accountcode, v->value);
12816          } else if (!strcasecmp(v->name, "mohinterpret")) {
12817             ast_string_field_set(user, mohinterpret, v->value);
12818          } else if (!strcasecmp(v->name, "mohsuggest")) {
12819             ast_string_field_set(user, mohsuggest, v->value);
12820          } else if (!strcasecmp(v->name, "parkinglot")) {
12821             ast_string_field_set(user, parkinglot, v->value);
12822          } else if (!strcasecmp(v->name, "language")) {
12823             ast_string_field_set(user, language, v->value);
12824          } else if (!strcasecmp(v->name, "amaflags")) {
12825             format = ast_cdr_amaflags2int(v->value);
12826             if (format < 0) {
12827                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12828             } else {
12829                user->amaflags = format;
12830             }
12831          } else if (!strcasecmp(v->name, "inkeys")) {
12832             ast_string_field_set(user, inkeys, v->value);
12833          } else if (!strcasecmp(v->name, "maxauthreq")) {
12834             user->maxauthreq = atoi(v->value);
12835             if (user->maxauthreq < 0)
12836                user->maxauthreq = 0;
12837          } else if (!strcasecmp(v->name, "adsi")) {
12838             user->adsi = ast_true(v->value);
12839          } else if (!strcasecmp(v->name, "connectedline")) {
12840             if (ast_true(v->value)) {
12841                ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12842             } else if (!strcasecmp(v->value, "send")) {
12843                ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
12844                ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
12845             } else if (!strcasecmp(v->value, "receive")) {
12846                ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
12847                ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
12848             } else {
12849                ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12850             }
12851          } else if (!strcasecmp(v->name, "requirecalltoken")) {
12852             /* default is required unless in optional ip list */
12853             if (ast_false(v->value)) {
12854                user->calltoken_required = CALLTOKEN_NO;
12855             } else if (!strcasecmp(v->value, "auto")) {
12856                user->calltoken_required = CALLTOKEN_AUTO;
12857             } else if (ast_true(v->value)) {
12858                user->calltoken_required = CALLTOKEN_YES;
12859             } else {
12860                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12861             }
12862          } /* else if (strcasecmp(v->name,"type")) */
12863          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
12864          v = v->next;
12865          if (!v) {
12866             v = alt;
12867             alt = NULL;
12868          }
12869       }
12870       if (!user->authmethods) {
12871          if (!ast_strlen_zero(user->secret)) {
12872             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12873             if (!ast_strlen_zero(user->inkeys))
12874                user->authmethods |= IAX_AUTH_RSA;
12875          } else if (!ast_strlen_zero(user->inkeys)) {
12876             user->authmethods = IAX_AUTH_RSA;
12877          } else {
12878             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12879          }
12880       }
12881       ast_clear_flag64(user, IAX_DELME);
12882    }
12883 cleanup:
12884    if (oldha)
12885       ast_free_ha(oldha);
12886    if (oldcon)
12887       free_context(oldcon);
12888    return user;
12889 }

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

Definition at line 13523 of file chan_iax2.c.

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

Referenced by find_cache().

13524 {
13525    struct sockaddr_in sin;
13526    int x;
13527    int callno;
13528    struct iax_ie_data ied;
13529    struct create_addr_info cai;
13530    struct parsed_dial_string pds;
13531    char *tmpstr;
13532 
13533    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13534       /* Look for an *exact match* call.  Once a call is negotiated, it can only
13535          look up entries for a single context */
13536       if (!ast_mutex_trylock(&iaxsl[x])) {
13537          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13538             return x;
13539          ast_mutex_unlock(&iaxsl[x]);
13540       }
13541    }
13542 
13543    /* No match found, we need to create a new one */
13544 
13545    memset(&cai, 0, sizeof(cai));
13546    memset(&ied, 0, sizeof(ied));
13547    memset(&pds, 0, sizeof(pds));
13548 
13549    tmpstr = ast_strdupa(data);
13550    parse_dial_string(tmpstr, &pds);
13551 
13552    if (ast_strlen_zero(pds.peer)) {
13553       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13554       return -1;
13555    }
13556 
13557    /* Populate our address from the given */
13558    if (create_addr(pds.peer, NULL, &sin, &cai))
13559       return -1;
13560 
13561    ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13562       pds.peer, pds.username, pds.password, pds.context);
13563 
13564    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13565    if (callno < 1) {
13566       ast_log(LOG_WARNING, "Unable to create call\n");
13567       return -1;
13568    }
13569 
13570    ast_string_field_set(iaxs[callno], dproot, data);
13571    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13572 
13573    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13574    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13575    /* the string format is slightly different from a standard dial string,
13576       because the context appears in the 'exten' position
13577    */
13578    if (pds.exten)
13579       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13580    if (pds.username)
13581       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13582    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13583    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13584    /* Keep password handy */
13585    if (pds.password)
13586       ast_string_field_set(iaxs[callno], secret, pds.password);
13587    if (pds.key)
13588       ast_string_field_set(iaxs[callno], outkey, pds.key);
13589    /* Start the call going */
13590    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
13591    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13592 
13593    return callno;
13594 }

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

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

05997 {
05998    /* Returns where in "receive time" we are.  That is, how many ms
05999       since we received (or would have received) the frame with timestamp 0 */
06000    int ms;
06001 #ifdef IAXTESTS
06002    int jit;
06003 #endif /* IAXTESTS */
06004    /* Setup rxcore if necessary */
06005    if (ast_tvzero(p->rxcore)) {
06006       p->rxcore = ast_tvnow();
06007       if (iaxdebug)
06008          ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
06009                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06010       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06011 #if 1
06012       if (iaxdebug)
06013          ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06014                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06015 #endif
06016    }
06017 
06018    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06019 #ifdef IAXTESTS
06020    if (test_jit) {
06021       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06022          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06023          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06024             jit = -jit;
06025          ms += jit;
06026       }
06027    }
06028    if (test_late) {
06029       ms += test_late;
06030       test_late = 0;
06031    }
06032 #endif /* IAXTESTS */
06033    return ms;
06034 }

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

Definition at line 5863 of file chan_iax2.c.

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

Referenced by iax2_send(), and socket_process().

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

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

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

05820 {
05821    unsigned long int mssincetx; /* unsigned to handle overflows */
05822    long int ms, pred;
05823 
05824    tpeer->trunkact = *now;
05825    mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05826    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05827       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
05828       tpeer->txtrunktime = *now;
05829       tpeer->lastsent = 999999;
05830    }
05831    /* Update last transmit time now */
05832    tpeer->lasttxtime = *now;
05833    
05834    /* Calculate ms offset */
05835    ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05836    /* Predict from last value */
05837    pred = tpeer->lastsent + sampms;
05838    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05839       ms = pred;
05840    
05841    /* We never send the same timestamp twice, so fudge a little if we must */
05842    if (ms == tpeer->lastsent)
05843       ms = tpeer->lastsent + 1;
05844    tpeer->lastsent = ms;
05845    return ms;
05846 }

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

Definition at line 2658 of file chan_iax2.c.

References ast_random().

Referenced by create_callno_pools().

02659 {
02660    return abs(ast_random());
02661 }

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

Definition at line 2189 of file chan_iax2.c.

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

Referenced by handle_call_token().

02190 {
02191    struct addr_range *addr_range;
02192    struct iax2_peer *peer = NULL;
02193    struct iax2_user *user = NULL;
02194    /* if no username is given, check for guest accounts */
02195    const char *find = S_OR(name, "guest");
02196    int res = 1;  /* required by default */
02197    int optional = 0;
02198    enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02199    /* There are only two cases in which calltoken validation is not required.
02200     * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
02201     *         the peer definition has not set the requirecalltoken option.
02202     * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
02203     */
02204 
02205    /* ----- Case 1 ----- */
02206    if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02207       ao2_ref(addr_range, -1);
02208       optional = 1;
02209    }
02210 
02211    /* ----- Case 2 ----- */
02212    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02213       calltoken_required = user->calltoken_required;
02214    } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02215       calltoken_required = user->calltoken_required;
02216    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02217       calltoken_required = peer->calltoken_required;
02218    } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02219       calltoken_required = peer->calltoken_required;
02220    }
02221 
02222    if (peer) {
02223       peer_unref(peer);
02224    }
02225    if (user) {
02226       user_unref(user);
02227    }
02228 
02229    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);
02230    if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02231       (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02232       res = 0;
02233    }
02234 
02235    return res;
02236 }

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

Definition at line 7511 of file chan_iax2.c.

References chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags64, ast_db_get(), ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag64, ast_set_flag64, ast_shrink_phone_number(), ast_sockaddr_from_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_variable_new(), chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, chan_iax2_pvt::capability, iax_ies::capability, cid_name, cid_num, iax_ies::codec_prefs, chan_iax2_pvt::context, context, DEFAULT_CONTEXT, iax_ies::dnid, chan_iax2_pvt::encmethods, exten, ast_variable::file, iax_ies::format, globalflags, iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_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, ast_variable::name, ast_variable::next, parkinglot, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, chan_iax2_pvt::prefs, prefs, iax_ies::rdnis, realtime_user(), secret, user, user_unref(), iax_ies::username, users, ast_variable::value, chan_iax2_pvt::vars, iax_ies::version, and version.

Referenced by socket_process().

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

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

Definition at line 9384 of file chan_iax2.c.

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

Referenced by socket_process().

09385 {
09386    unsigned int ourver;
09387    char rsi[80];
09388    snprintf(rsi, sizeof(rsi), "si-%s", si);
09389    if (iax_provision_version(&ourver, rsi, 1))
09390       return 0;
09391    ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09392    if (ourver != ver) 
09393       iax2_provision(sin, sockfd, NULL, rsi, 1);
09394    return 0;
09395 }

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

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

Referenced by peer_set_srcaddr().

12222 {
12223    int sd;
12224    int res;
12225    
12226    sd = socket(AF_INET, SOCK_DGRAM, 0);
12227    if (sd < 0) {
12228       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12229       return -1;
12230    }
12231 
12232    res = bind(sd, sa, salen);
12233    if (res < 0) {
12234       ast_debug(1, "Can't bind: %s\n", strerror(errno));
12235       close(sd);
12236       return 1;
12237    }
12238 
12239    close(sd);
12240    return 0;
12241 }

static void cleanup_thread_list ( void *  head  )  [static]

Definition at line 14258 of file chan_iax2.c.

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

Referenced by __unload_module().

14259 {
14260    AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14261    struct iax2_thread_list *list_head = head;
14262    struct iax2_thread *thread;
14263 
14264    AST_LIST_LOCK(list_head);
14265    while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
14266       pthread_t thread_id = thread->threadid;
14267 
14268       thread->stop = 1;
14269       signal_condition(&thread->lock, &thread->cond);
14270 
14271       AST_LIST_UNLOCK(list_head);
14272       pthread_join(thread_id, NULL);
14273       AST_LIST_LOCK(list_head);
14274    }
14275    AST_LIST_UNLOCK(list_head);
14276 }

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

Definition at line 8301 of file chan_iax2.c.

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

Referenced by socket_process().

08302 {
08303    char exten[256] = "";
08304    int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08305    struct iax2_dpcache *dp = NULL;
08306    
08307    if (ies->called_number)
08308       ast_copy_string(exten, ies->called_number, sizeof(exten));
08309    
08310    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08311       status = CACHE_FLAG_EXISTS;
08312    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08313       status = CACHE_FLAG_CANEXIST;
08314    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08315       status = CACHE_FLAG_NONEXISTENT;
08316 
08317    if (ies->refresh)
08318       expiry = ies->refresh;
08319    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08320       matchmore = CACHE_FLAG_MATCHMORE;
08321    
08322    AST_LIST_LOCK(&dpcache);
08323    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08324       if (strcmp(dp->exten, exten))
08325          continue;
08326       AST_LIST_REMOVE_CURRENT(peer_list);
08327       dp->callno = 0;
08328       dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08329       if (dp->flags & CACHE_FLAG_PENDING) {
08330          dp->flags &= ~CACHE_FLAG_PENDING;
08331          dp->flags |= status;
08332          dp->flags |= matchmore;
08333       }
08334       /* Wake up waiters */
08335       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08336          if (dp->waiters[x] > -1) {
08337             if (write(dp->waiters[x], "asdf", 4) < 0) {
08338             }
08339          }
08340       }
08341    }
08342    AST_LIST_TRAVERSE_SAFE_END;
08343    AST_LIST_UNLOCK(&dpcache);
08344 
08345    return 0;
08346 }

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

Definition at line 3809 of file chan_iax2.c.

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

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

03810 {
03811    int which = 0;
03812    struct iax2_peer *peer;
03813    char *res = NULL;
03814    int wordlen = strlen(word);
03815    struct ao2_iterator i;
03816 
03817    i = ao2_iterator_init(peers, 0);
03818    while ((peer = ao2_iterator_next(&i))) {
03819       if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03820          && (!flags || ast_test_flag64(peer, flags))) {
03821          res = ast_strdup(peer->name);
03822          peer_unref(peer);
03823          break;
03824       }
03825       peer_unref(peer);
03826    }
03827    ao2_iterator_destroy(&i);
03828 
03829    return res;
03830 }

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

Definition at line 6864 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_unregister().

06865 {
06866    int which = 0;
06867    struct iax2_peer *p = NULL;
06868    char *res = NULL;
06869    int wordlen = strlen(word);
06870 
06871    /* 0 - iax2; 1 - unregister; 2 - <peername> */
06872    if (pos == 2) {
06873       struct ao2_iterator i = ao2_iterator_init(peers, 0);
06874       while ((p = ao2_iterator_next(&i))) {
06875          if (!strncasecmp(p->name, word, wordlen) && 
06876             ++which > state && p->expire > 0) {
06877             res = ast_strdup(p->name);
06878             peer_unref(p);
06879             break;
06880          }
06881          peer_unref(p);
06882       }
06883       ao2_iterator_destroy(&i);
06884    }
06885 
06886    return res;
06887 }

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

Definition at line 8348 of file chan_iax2.c.

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

Referenced by socket_process().

08349 {
08350    int peercallno = 0;
08351    struct chan_iax2_pvt *pvt = iaxs[callno];
08352    struct iax_frame *cur;
08353    jb_frame frame;
08354 
08355    if (ies->callno)
08356       peercallno = ies->callno;
08357 
08358    if (peercallno < 1) {
08359       ast_log(LOG_WARNING, "Invalid transfer request\n");
08360       return -1;
08361    }
08362    remove_by_transfercallno(pvt);
08363    /* since a transfer has taken place, the address will change.
08364     * This must be accounted for in the peercnts table.  Remove
08365     * the old address and add the new one */
08366    peercnt_remove_by_addr(&pvt->addr);
08367    peercnt_add(&pvt->transfer);
08368    /* now copy over the new address */
08369    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08370    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08371    /* Reset sequence numbers */
08372    pvt->oseqno = 0;
08373    pvt->rseqno = 0;
08374    pvt->iseqno = 0;
08375    pvt->aseqno = 0;
08376 
08377    if (pvt->peercallno) {
08378       remove_by_peercallno(pvt);
08379    }
08380    pvt->peercallno = peercallno;
08381    /*this is where the transfering call swiches hash tables */
08382    store_by_peercallno(pvt);
08383    pvt->transferring = TRANSFER_NONE;
08384    pvt->svoiceformat = -1;
08385    pvt->voiceformat = 0;
08386    pvt->svideoformat = -1;
08387    pvt->videoformat = 0;
08388    pvt->transfercallno = 0;
08389    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08390    memset(&pvt->offset, 0, sizeof(pvt->offset));
08391    /* reset jitterbuffer */
08392    while(jb_getall(pvt->jb,&frame) == JB_OK)
08393       iax2_frame_free(frame.data);
08394    jb_reset(pvt->jb);
08395    pvt->lag = 0;
08396    pvt->last = 0;
08397    pvt->lastsent = 0;
08398    pvt->nextpred = 0;
08399    pvt->pingtime = DEFAULT_RETRY_TIME;
08400    AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08401       /* We must cancel any packets that would have been transmitted
08402          because now we're talking to someone new.  It's okay, they
08403          were transmitted to someone that didn't care anyway. */
08404       cur->retries = -1;
08405    }
08406    return 0;
08407 }

static unsigned char compress_subclass ( format_t  subclass  )  [static]

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

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

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

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

09398 {
09399    jb_info stats;
09400    jb_getinfo(pvt->jb, &stats);
09401    
09402    memset(iep, 0, sizeof(*iep));
09403 
09404    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09405    if(stats.frames_in == 0) stats.frames_in = 1;
09406    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09407    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09408    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09409    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09410    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09411 }

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

Definition at line 4537 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, iax2_peer::cid_name, create_addr_info::cid_name, iax2_peer::cid_num, create_addr_info::cid_num, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, IAX_DEFAULT_PORTNO, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::mohinterpret, create_addr_info::mohinterpret, iax2_peer::mohsuggest, create_addr_info::mohsuggest, ast_channel::nativeformats, iax2_peer::outkey, create_addr_info::outkey, peer_unref(), iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, ast_sockaddr::ss, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.

04538 {
04539    struct iax2_peer *peer;
04540    int res = -1;
04541    struct ast_codec_pref ourprefs;
04542    struct sockaddr_in peer_addr;
04543 
04544    ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04545    cai->sockfd = defaultsockfd;
04546    cai->maxtime = 0;
04547    sin->sin_family = AF_INET;
04548 
04549    if (!(peer = find_peer(peername, 1))) {
04550       struct ast_sockaddr sin_tmp;
04551 
04552       cai->found = 0;
04553       sin_tmp.ss.ss_family = AF_INET;
04554       if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
04555          ast_log(LOG_WARNING, "No such host: %s\n", peername);
04556          return -1;
04557       }
04558       ast_sockaddr_to_sin(&sin_tmp, sin);
04559       if (sin->sin_port == 0) {
04560          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04561       }
04562       /* use global iax prefs for unknown peer/user */
04563       /* But move the calling channel's native codec to the top of the preference list */
04564       memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04565       if (c)
04566          ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04567       ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04568       return 0;
04569    }
04570 
04571    cai->found = 1;
04572 
04573    ast_sockaddr_to_sin(&peer->addr, &peer_addr);
04574 
04575    /* if the peer has no address (current or default), return failure */
04576    if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
04577       goto return_unref;
04578    }
04579 
04580    /* if the peer is being monitored and is currently unreachable, return failure */
04581    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04582       goto return_unref;
04583 
04584    ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04585    cai->maxtime = peer->maxms;
04586    cai->capability = peer->capability;
04587    cai->encmethods = peer->encmethods;
04588    cai->sockfd = peer->sockfd;
04589    cai->adsi = peer->adsi;
04590    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04591    /* Move the calling channel's native codec to the top of the preference list */
04592    if (c) {
04593       ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
04594       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04595    }
04596    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04597    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04598    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04599    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04600    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04601    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04602    ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04603    ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04604    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04605    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04606    if (ast_strlen_zero(peer->dbsecret)) {
04607       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04608    } else {
04609       char *family;
04610       char *key = NULL;
04611 
04612       family = ast_strdupa(peer->dbsecret);
04613       key = strchr(family, '/');
04614       if (key)
04615          *key++ = '\0';
04616       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04617          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04618          goto return_unref;
04619       }
04620    }
04621 
04622    if (peer_addr.sin_addr.s_addr) {
04623       sin->sin_addr = peer_addr.sin_addr;
04624       sin->sin_port = peer_addr.sin_port;
04625    } else {
04626       sin->sin_addr = peer->defaddr.sin_addr;
04627       sin->sin_port = peer->defaddr.sin_port;
04628    }
04629 
04630    res = 0;
04631 
04632 return_unref:
04633    peer_unref(peer);
04634 
04635    return res;
04636 }

static int create_callno_pools ( void   )  [static]

Definition at line 2663 of file chan_iax2.c.

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

Referenced by load_objects().

02664 {
02665    uint16_t i;
02666 
02667    if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02668       return -1;
02669    }
02670 
02671    if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02672       return -1;
02673    }
02674 
02675    /* start at 2, 0 and 1 are reserved */
02676    for (i = 2; i <= IAX_MAX_CALLS; i++) {
02677       struct callno_entry *callno_entry;
02678 
02679       if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02680          return -1;
02681       }
02682 
02683       callno_entry->callno = i;
02684 
02685       if (i < TRUNK_CALL_START) {
02686          ao2_link(callno_pool, callno_entry);
02687       } else {
02688          ao2_link(callno_pool_trunk, callno_entry);
02689       }
02690 
02691       ao2_ref(callno_entry, -1);
02692    }
02693 
02694    return 0;
02695 }

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

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

Referenced by decrypt_frame(), and update_packet().

06218 {
06219    int padding;
06220    unsigned char *workspace;
06221 
06222    workspace = alloca(*datalen);
06223    memset(f, 0, sizeof(*f));
06224    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06225       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06226       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06227          return -1;
06228       /* Decrypt */
06229       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06230 
06231       padding = 16 + (workspace[15] & 0x0f);
06232       if (iaxdebug)
06233          ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06234       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06235          return -1;
06236 
06237       *datalen -= padding;
06238       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06239       f->frametype = fh->type;
06240       if (f->frametype == AST_FRAME_VIDEO) {
06241          f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06242       } else if (f->frametype == AST_FRAME_VOICE) {
06243          f->subclass.codec = uncompress_subclass(fh->csub);
06244       } else {
06245          f->subclass.integer = uncompress_subclass(fh->csub);
06246       }
06247    } else {
06248       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06249       if (iaxdebug)
06250          ast_debug(1, "Decoding mini with length %d\n", *datalen);
06251       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06252          return -1;
06253       /* Decrypt */
06254       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06255       padding = 16 + (workspace[15] & 0x0f);
06256       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06257          return -1;
06258       *datalen -= padding;
06259       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06260    }
06261    return 0;
06262 }

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

Definition at line 6305 of file chan_iax2.c.

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

Referenced by socket_process().

06306 {
06307    int res=-1;
06308    if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06309       /* Search for possible keys, given secrets */
06310       struct MD5Context md5;
06311       unsigned char digest[16];
06312       char *tmppw, *stringp;
06313       
06314       tmppw = ast_strdupa(iaxs[callno]->secret);
06315       stringp = tmppw;
06316       while ((tmppw = strsep(&stringp, ";"))) {
06317          MD5Init(&md5);
06318          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06319          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06320          MD5Final(digest, &md5);
06321          build_encryption_keys(digest, iaxs[callno]);
06322          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06323          if (!res) {
06324             ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06325             break;
06326          }
06327       }
06328    } else 
06329       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06330    return res;
06331 }

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

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

Referenced by socket_read().

09545 {
09546    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09547    struct ast_iax2_full_hdr *fh, *cur_fh;
09548 
09549    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09550       return;
09551 
09552    pkt_buf->len = from_here->buf_len;
09553    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09554 
09555    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09556    ast_mutex_lock(&to_here->lock);
09557    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09558       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09559       if (fh->oseqno < cur_fh->oseqno) {
09560          AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09561          break;
09562       }
09563    }
09564    AST_LIST_TRAVERSE_SAFE_END
09565 
09566    if (!cur_pkt_buf)
09567       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09568    
09569    ast_mutex_unlock(&to_here->lock);
09570 }

static void delete_users ( void   )  [static]

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

12910 {
12911    struct iax2_registry *reg;
12912 
12913    ao2_callback(users, 0, user_delme_cb, NULL);
12914 
12915    AST_LIST_LOCK(&registrations);
12916    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
12917       if (sched) {
12918          ast_sched_thread_del(sched, reg->expire);
12919       }
12920       if (reg->callno) {
12921          int callno = reg->callno;
12922          ast_mutex_lock(&iaxsl[callno]);
12923          if (iaxs[callno]) {
12924             iaxs[callno]->reg = NULL;
12925             iax2_destroy(callno);
12926          }
12927          ast_mutex_unlock(&iaxsl[callno]);
12928       }
12929       if (reg->dnsmgr)
12930          ast_dnsmgr_release(reg->dnsmgr);
12931       ast_free(reg);
12932    }
12933    AST_LIST_UNLOCK(&registrations);
12934 
12935    ao2_callback(peers, 0, peer_delme_cb, NULL);
12936 }

static void destroy_firmware ( struct iax_firmware cur  )  [static]

Definition at line 2993 of file chan_iax2.c.

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

Referenced by reload_firmware().

02994 {
02995    /* Close firmware */
02996    if (cur->fwh) {
02997       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02998    }
02999    close(cur->fd);
03000    ast_free(cur);
03001 }

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

Definition at line 9199 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_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, and send_command().

Referenced by dp_lookup_thread(), and socket_process().

09200 {
09201    unsigned short dpstatus = 0;
09202    struct iax_ie_data ied1;
09203    int mm;
09204 
09205    memset(&ied1, 0, sizeof(ied1));
09206    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09207    /* Must be started */
09208    if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09209       dpstatus = IAX_DPSTATUS_EXISTS;
09210    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09211       dpstatus = IAX_DPSTATUS_CANEXIST;
09212    } else {
09213       dpstatus = IAX_DPSTATUS_NONEXISTENT;
09214    }
09215    if (ast_ignore_pattern(context, callednum))
09216       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09217    if (mm)
09218       dpstatus |= IAX_DPSTATUS_MATCHMORE;
09219    if (!skiplock)
09220       ast_mutex_lock(&iaxsl[callno]);
09221    if (iaxs[callno]) {
09222       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09223       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09224       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09225       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09226    }
09227    if (!skiplock)
09228       ast_mutex_unlock(&iaxsl[callno]);
09229 }

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

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

09232 {
09233    /* Look up for dpreq */
09234    struct dpreq_data *dpr = data;
09235    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09236    if (dpr->callerid)
09237       ast_free(dpr->callerid);
09238    ast_free(dpr);
09239    return NULL;
09240 }

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

Definition at line 1541 of file chan_iax2.c.

References ast_str_append(), ast_str_set(), ast_str_strlen(), iax2_thread::buf, 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().

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

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

Definition at line 6264 of file chan_iax2.c.

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

Referenced by iax2_send(), and update_packet().

06265 {
06266    int padding;
06267    unsigned char *workspace;
06268    workspace = alloca(*datalen + 32);
06269    if (!workspace)
06270       return -1;
06271    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06272       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06273       if (iaxdebug)
06274          ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06275       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06276       padding = 16 + (padding & 0xf);
06277       memcpy(workspace, poo, padding);
06278       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06279       workspace[15] &= 0xf0;
06280       workspace[15] |= (padding & 0xf);
06281       if (iaxdebug)
06282          ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06283       *datalen += padding;
06284       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06285       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06286          memcpy(poo, workspace + *datalen - 32, 32);
06287    } else {
06288       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06289       if (iaxdebug)
06290          ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06291       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06292       padding = 16 + (padding & 0xf);
06293       memcpy(workspace, poo, padding);
06294       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06295       workspace[15] &= 0xf0;
06296       workspace[15] |= (padding & 0x0f);
06297       *datalen += padding;
06298       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06299       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06300          memcpy(poo, workspace + *datalen - 32, 32);
06301    }
06302    return 0;
06303 }

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

Definition at line 8616 of file chan_iax2.c.

References __expire_registry(), and schedule_action.

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

08617 {
08618 #ifdef SCHED_MULTITHREADED
08619    if (schedule_action(__expire_registry, data))
08620 #endif      
08621       __expire_registry(data);
08622    return 0;
08623 }

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

Definition at line 13596 of file chan_iax2.c.

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

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

13597 {
13598    struct iax2_dpcache *dp = NULL;
13599    struct timeval now = ast_tvnow();
13600    int x, com[2], timeout, old = 0, outfd, doabort, callno;
13601    struct ast_channel *c = NULL;
13602    struct ast_frame *f = NULL;
13603 
13604    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13605       if (ast_tvcmp(now, dp->expiry) > 0) {
13606          AST_LIST_REMOVE_CURRENT(cache_list);
13607          if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13608             ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13609          else
13610             ast_free(dp);
13611          continue;
13612       }
13613       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13614          break;
13615    }
13616    AST_LIST_TRAVERSE_SAFE_END;
13617 
13618    if (!dp) {
13619       /* No matching entry.  Create a new one. */
13620       /* First, can we make a callno? */
13621       if ((callno = cache_get_callno_locked(data)) < 0) {
13622          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13623          return NULL;
13624       }
13625       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13626          ast_mutex_unlock(&iaxsl[callno]);
13627          return NULL;
13628       }
13629       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13630       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13631       dp->expiry = ast_tvnow();
13632       dp->orig = dp->expiry;
13633       /* Expires in 30 mins by default */
13634       dp->expiry.tv_sec += iaxdefaultdpcache;
13635       dp->flags = CACHE_FLAG_PENDING;
13636       for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13637          dp->waiters[x] = -1;
13638       /* Insert into the lists */
13639       AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13640       AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13641       /* Send the request if we're already up */
13642       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13643          iax2_dprequest(dp, callno);
13644       ast_mutex_unlock(&iaxsl[callno]);
13645    }
13646 
13647    /* By here we must have a dp */
13648    if (dp->flags & CACHE_FLAG_PENDING) {
13649       /* Okay, here it starts to get nasty.  We need a pipe now to wait
13650          for a reply to come back so long as it's pending */
13651       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13652          /* Find an empty slot */
13653          if (dp->waiters[x] < 0)
13654             break;
13655       }
13656       if (x >= ARRAY_LEN(dp->waiters)) {
13657          ast_log(LOG_WARNING, "No more waiter positions available\n");
13658          return NULL;
13659       }
13660       if (pipe(com)) {
13661          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13662          return NULL;
13663       }
13664       dp->waiters[x] = com[1];
13665       /* Okay, now we wait */
13666       timeout = iaxdefaulttimeout * 1000;
13667       /* Temporarily unlock */
13668       AST_LIST_UNLOCK(&dpcache);
13669       /* Defer any dtmf */
13670       if (chan)
13671          old = ast_channel_defer_dtmf(chan);
13672       doabort = 0;
13673       while(timeout) {
13674          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
13675          if (outfd > -1)
13676             break;
13677          if (!c)
13678             continue;
13679          if (!(f = ast_read(c))) {
13680             doabort = 1;
13681             break;
13682          }
13683          ast_frfree(f);
13684       }
13685       if (!timeout) {
13686          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13687       }
13688       AST_LIST_LOCK(&dpcache);
13689       dp->waiters[x] = -1;
13690       close(com[1]);
13691       close(com[0]);
13692       if (doabort) {
13693          /* Don't interpret anything, just abort.  Not sure what th epoint
13694            of undeferring dtmf on a hung up channel is but hey whatever */
13695          if (!old && chan)
13696             ast_channel_undefer_dtmf(chan);
13697          return NULL;
13698       }
13699       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13700          /* Now to do non-independent analysis the results of our wait */
13701          if (dp->flags & CACHE_FLAG_PENDING) {
13702             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
13703                pending.  Don't let it take as long to timeout. */
13704             dp->flags &= ~CACHE_FLAG_PENDING;
13705             dp->flags |= CACHE_FLAG_TIMEOUT;
13706             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
13707                systems without leaving it unavailable once the server comes back online */
13708             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13709             for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13710                if (dp->waiters[x] > -1) {
13711                   if (write(dp->waiters[x], "asdf", 4) < 0) {
13712                      ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13713                   }
13714                }
13715             }
13716          }
13717       }
13718       /* Our caller will obtain the rest */
13719       if (!old && chan)
13720          ast_channel_undefer_dtmf(chan);
13721    }
13722    return dp;  
13723 }

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

References __find_callno().

Referenced by iax2_poke_peer(), and socket_process().

02918                                                                                                                                     { 
02919    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02920 }

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

02922                                                                                                                                            {
02923 
02924    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02925 }

static struct iax2_thread* find_idle_thread ( void   )  [static]

Definition at line 1393 of file chan_iax2.c.

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

Referenced by __schedule_action(), and socket_read().

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

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

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

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

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

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

Definition at line 6036 of file chan_iax2.c.

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

Referenced by iax2_trunk_queue(), and socket_process_meta().

06037 {
06038    struct iax2_trunk_peer *tpeer = NULL;
06039    
06040    /* Finds and locks trunk peer */
06041    AST_LIST_LOCK(&tpeers);
06042 
06043    AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06044       if (!inaddrcmp(&tpeer->addr, sin)) {
06045          ast_mutex_lock(&tpeer->lock);
06046          break;
06047       }
06048    }
06049 
06050    if (!tpeer) {
06051       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06052          ast_mutex_init(&tpeer->lock);
06053          tpeer->lastsent = 9999;
06054          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06055          tpeer->trunkact = ast_tvnow();
06056          ast_mutex_lock(&tpeer->lock);
06057          tpeer->sockfd = fd;
06058 #ifdef SO_NO_CHECK
06059          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06060 #endif
06061          ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06062          AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06063       }
06064    }
06065 
06066    AST_LIST_UNLOCK(&tpeers);
06067 
06068    return tpeer;
06069 }

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

Definition at line 1713 of file chan_iax2.c.

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

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

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

Definition at line 5848 of file chan_iax2.c.

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

Referenced by socket_process_meta().

05849 {
05850    long ms; /* NOT unsigned */
05851    if (ast_tvzero(iaxs[callno]->rxcore)) {
05852       /* Initialize rxcore time if appropriate */
05853       iaxs[callno]->rxcore = ast_tvnow();
05854       /* Round to nearest 20ms so traces look pretty */
05855       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05856    }
05857    /* Calculate difference between trunk and channel */
05858    ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05859    /* Return as the sum of trunk time and the difference between trunk and real time */
05860    return ms + ts;
05861 }

static void free_context ( struct iax2_context con  )  [static]

Definition at line 12055 of file chan_iax2.c.

References ast_free, and iax2_context::next.

Referenced by build_user(), and user_destructor().

12056 {
12057    struct iax2_context *conl;
12058    while(con) {
12059       conl = con;
12060       con = con->next;
12061       ast_free(conl);
12062    }
12063 }

static void free_signaling_queue_entry ( struct signaling_queue_entry s  )  [static]

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

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

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

Definition at line 13846 of file chan_iax2.c.

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

13847 {
13848    struct iax2_peer *peer;
13849    char *peername, *colname;
13850 
13851    peername = ast_strdupa(data);
13852 
13853    /* if our channel, return the IP address of the endpoint of current channel */
13854    if (!strcmp(peername,"CURRENTCHANNEL")) {
13855            unsigned short callno;
13856       if (chan->tech != &iax2_tech)
13857          return -1;
13858       callno = PTR_TO_CALLNO(chan->tech_pvt);   
13859       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13860       return 0;
13861    }
13862 
13863    if ((colname = strchr(peername, ',')))
13864       *colname++ = '\0';
13865    else
13866       colname = "ip";
13867 
13868    if (!(peer = find_peer(peername, 1)))
13869       return -1;
13870 
13871    if (!strcasecmp(colname, "ip")) {
13872       ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
13873    } else  if (!strcasecmp(colname, "status")) {
13874       peer_status(peer, buf, len); 
13875    } else  if (!strcasecmp(colname, "mailbox")) {
13876       ast_copy_string(buf, peer->mailbox, len);
13877    } else  if (!strcasecmp(colname, "context")) {
13878       ast_copy_string(buf, peer->context, len);
13879    } else  if (!strcasecmp(colname, "expire")) {
13880       snprintf(buf, len, "%d", peer->expire);
13881    } else  if (!strcasecmp(colname, "dynamic")) {
13882       ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13883    } else  if (!strcasecmp(colname, "callerid_name")) {
13884       ast_copy_string(buf, peer->cid_name, len);
13885    } else  if (!strcasecmp(colname, "callerid_num")) {
13886       ast_copy_string(buf, peer->cid_num, len);
13887    } else  if (!strcasecmp(colname, "codecs")) {
13888       ast_getformatname_multiple(buf, len -1, peer->capability);
13889    } else  if (!strncasecmp(colname, "codec[", 6)) {
13890       char *codecnum, *ptr;
13891       int codec = 0;
13892       
13893       codecnum = strchr(colname, '[');
13894       *codecnum = '\0';
13895       codecnum++;
13896       if ((ptr = strchr(codecnum, ']'))) {
13897          *ptr = '\0';
13898       }
13899       if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13900          ast_copy_string(buf, ast_getformatname(codec), len);
13901       } else {
13902          buf[0] = '\0';
13903       }
13904    } else {
13905       buf[0] = '\0';
13906    }
13907 
13908    peer_unref(peer);
13909 
13910    return 0;
13911 }

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

Definition at line 12205 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

12206 {
12207    int methods = 0;
12208    if (strstr(value, "rsa"))
12209       methods |= IAX_AUTH_RSA;
12210    if (strstr(value, "md5"))
12211       methods |= IAX_AUTH_MD5;
12212    if (strstr(value, "plaintext"))
12213       methods |= IAX_AUTH_PLAINTEXT;
12214    return methods;
12215 }

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

Definition at line 1557 of file chan_iax2.c.

References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.

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

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

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

Definition at line 4119 of file chan_iax2.c.

References __get_from_jb(), and schedule_action.

Referenced by update_jbsched().

04120 {
04121 #ifdef SCHED_MULTITHREADED
04122    if (schedule_action(__get_from_jb, data))
04123 #endif      
04124       __get_from_jb(data);
04125    return 0;
04126 }

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

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

02597 {
02598    struct callno_entry *callno_entry = NULL;
02599    if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02600       ast_log(LOG_WARNING, "Out of CallNumbers\n");
02601       /* Minor optimization for the extreme case. */
02602       return NULL;
02603    }
02604 
02605    /* the callno_pool container is locked here primarily to ensure thread
02606     * safety of the total_nonval_callno_used check and increment */
02607    ao2_lock(callno_pool);
02608 
02609    /* only a certain number of nonvalidated call numbers should be allocated.
02610     * If there ever is an attack, this separates the calltoken validating
02611     * users from the non calltoken validating users. */
02612    if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02613       ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02614       ao2_unlock(callno_pool);
02615       return NULL;
02616    }
02617 
02618    /* unlink the object from the container, taking over ownership
02619     * of the reference the container had to the object */
02620    callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02621 
02622    if (callno_entry) {
02623       callno_entry->validated = validated;
02624       if (!validated) {
02625          total_nonval_callno_used++;
02626       }
02627    }
02628 
02629    ao2_unlock(callno_pool);
02630    return callno_entry;
02631 }

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

04846 {
04847 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"  /* address + port + ts + randomcalldata */
04848 #define CALLTOKEN_IE_FORMAT   "%u?%s"     /* time + ? + (40 char hash) */
04849    struct ast_str *buf = ast_str_alloca(256);
04850    time_t t = time(NULL);
04851    char hash[41]; /* 40 char sha1 hash */
04852    int subclass = uncompress_subclass(fh->csub);
04853 
04854    /* ----- Case 1 ----- */
04855    if (ies->calltoken && !ies->calltokendata) {  /* empty calltoken is provided, client supports calltokens */
04856       struct iax_ie_data ied = {
04857          .buf = { 0 },
04858          .pos = 0,
04859       };
04860 
04861       /* create the hash with their address data and our timestamp */
04862       ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04863       ast_sha1_hash(hash, ast_str_buffer(buf));
04864 
04865       ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04866       iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04867       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04868 
04869       return 1;
04870 
04871    /* ----- Case 2 ----- */
04872    } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */
04873       char *rec_hash = NULL;    /* the received hash, make sure it matches with ours. */
04874       char *rec_ts = NULL;      /* received timestamp */
04875       unsigned int rec_time;  /* received time_t */
04876 
04877       /* split the timestamp from the hash data */
04878       rec_hash = strchr((char *) ies->calltokendata, '?');
04879       if (rec_hash) {
04880          *rec_hash++ = '\0';
04881          rec_ts = (char *) ies->calltokendata;
04882       }
04883 
04884       /* check that we have valid data before we do any comparisons */
04885       if (!rec_hash || !rec_ts) {
04886          goto reject;
04887       } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04888          goto reject;
04889       }
04890 
04891       /* create a hash with their address and the _TOKEN'S_ timestamp */
04892       ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04893       ast_sha1_hash(hash, ast_str_buffer(buf));
04894 
04895       /* compare hashes and then check timestamp delay */
04896       if (strcmp(hash, rec_hash)) {
04897          ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04898          goto reject; /* received hash does not match ours, reject */
04899       } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04900          ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04901          goto reject; /* too much delay, reject */
04902       }
04903 
04904       /* at this point the call token is valid, returning 0 
04905        * will allow socket_process to continue as usual */
04906       requirecalltoken_mark_auto(ies->username, subclass);
04907       return 0;
04908 
04909    /* ----- Case 3 ----- */
04910    } else { /* calltokens are not supported for this client, how do we respond? */
04911       if (calltoken_required(sin, ies->username, subclass)) {
04912          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"));
04913          goto reject;
04914       }
04915       return 0; /* calltoken is not required for this addr, so permit it. */
04916    }
04917 
04918 reject:
04919    /* received frame has failed calltoken inspection, send apathetic reject messages */
04920    if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04921       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04922    } else {
04923       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04924    }
04925 
04926    return 1;
04927 }

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

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

11903 {
11904    int force = 0;
11905    int res;
11906 
11907    switch (cmd) {
11908    case CLI_INIT:
11909       e->command = "iax2 provision";
11910       e->usage = 
11911          "Usage: iax2 provision <host> <template> [forced]\n"
11912          "       Provisions the given peer or IP address using a template\n"
11913          "       matching either 'template' or '*' if the template is not\n"
11914          "       found.  If 'forced' is specified, even empty provisioning\n"
11915          "       fields will be provisioned as empty fields.\n";
11916       return NULL;
11917    case CLI_GENERATE:
11918       if (a->pos == 3)
11919          return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11920       return NULL;
11921    }
11922 
11923    if (a->argc < 4)
11924       return CLI_SHOWUSAGE;
11925    if (a->argc > 4) {
11926       if (!strcasecmp(a->argv[4], "forced"))
11927          force = 1;
11928       else
11929          return CLI_SHOWUSAGE;
11930    }
11931    res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11932    if (res < 0)
11933       ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11934    else if (res < 1)
11935       ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11936    else
11937       ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11938    return CLI_SUCCESS;
11939 }

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

Definition at line 3551 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, user_unref(), users, and ast_cli_args::word.

03552 {
03553    struct iax2_peer *peer = NULL;
03554    struct iax2_user *user = NULL;
03555    static const char * const choices[] = { "all", NULL };
03556    char *cmplt;
03557 
03558    switch (cmd) {
03559    case CLI_INIT:
03560       e->command = "iax2 prune realtime";
03561       e->usage =
03562          "Usage: iax2 prune realtime [<peername>|all]\n"
03563          "       Prunes object(s) from the cache\n";
03564       return NULL;
03565    case CLI_GENERATE:
03566       if (a->pos == 3) {
03567          cmplt = ast_cli_complete(a->word, choices, a->n);
03568          if (!cmplt)
03569             cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03570          return cmplt;
03571       }
03572       return NULL;
03573    }
03574    if (a->argc != 4)
03575       return CLI_SHOWUSAGE;
03576    if (!strcmp(a->argv[3], "all")) {
03577       prune_users();
03578       prune_peers();
03579       ast_cli(a->fd, "Cache flushed successfully.\n");
03580       return CLI_SUCCESS;
03581    }
03582    peer = find_peer(a->argv[3], 0);
03583    user = find_user(a->argv[3]);
03584    if (peer || user) {
03585       if (peer) {
03586          if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
03587             ast_set_flag64(peer, IAX_RTAUTOCLEAR);
03588             expire_registry(peer_ref(peer));
03589             ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03590          } else {
03591             ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03592          }
03593          peer_unref(peer);
03594       }
03595       if (user) {
03596          if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
03597             ast_set_flag64(user, IAX_RTAUTOCLEAR);
03598             ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03599          } else {
03600             ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03601          }
03602          ao2_unlink(users,user);
03603          user_unref(user);
03604       }
03605    } else {
03606       ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03607    }
03608 
03609    return CLI_SUCCESS;
03610 }

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

Definition at line 13500 of file chan_iax2.c.

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

13501 {
13502    switch (cmd) {
13503    case CLI_INIT:
13504       e->command = "iax2 reload";
13505       e->usage =
13506          "Usage: iax2 reload\n"
13507          "       Reloads IAX configuration from iax.conf\n";
13508       return NULL;
13509    case CLI_GENERATE:
13510       return NULL;
13511    }
13512 
13513    reload_config();
13514 
13515    return CLI_SUCCESS;
13516 }

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

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

07309 {
07310    switch (cmd) {
07311    case CLI_INIT:
07312       e->command = "iax2 set debug {on|off|peer}";
07313       e->usage =
07314          "Usage: iax2 set debug {on|off|peer peername}\n"
07315          "       Enables/Disables dumping of IAX packets for debugging purposes.\n";
07316       return NULL;
07317    case CLI_GENERATE:
07318       if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07319          return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07320       return NULL;
07321    }
07322 
07323    if (a->argc < e->args  || a->argc > e->args + 1)
07324       return CLI_SHOWUSAGE;
07325 
07326    if (!strcasecmp(a->argv[3], "peer")) {
07327       struct iax2_peer *peer;
07328       struct sockaddr_in peer_addr;
07329 
07330 
07331       if (a->argc != e->args + 1)
07332          return CLI_SHOWUSAGE;
07333 
07334       peer = find_peer(a->argv[4], 1);
07335 
07336       if (!peer) {
07337          ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07338          return CLI_FAILURE;
07339       }
07340 
07341       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07342 
07343       debugaddr.sin_addr = peer_addr.sin_addr;
07344       debugaddr.sin_port = peer_addr.sin_port;
07345 
07346       ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07347          ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07348 
07349       ao2_ref(peer, -1);
07350    } else if (!strncasecmp(a->argv[3], "on", 2)) {
07351       iaxdebug = 1;
07352       ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07353    } else {
07354       iaxdebug = 0;
07355       memset(&debugaddr, 0, sizeof(debugaddr));
07356       ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07357    }
07358    return CLI_SUCCESS;
07359 }

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

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

07388 {
07389    switch (cmd) {
07390    case CLI_INIT:
07391       e->command = "iax2 set debug jb {on|off}";
07392       e->usage =
07393          "Usage: iax2 set debug jb {on|off}\n"
07394          "       Enables/Disables jitterbuffer debugging information\n";
07395       return NULL;
07396    case CLI_GENERATE:
07397       return NULL;
07398    }
07399 
07400    if (a->argc != e->args)
07401       return CLI_SHOWUSAGE;
07402    
07403    if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07404       jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07405       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07406    } else {
07407       jb_setoutput(jb_error_output, jb_warning_output, NULL);
07408       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07409    }
07410    return CLI_SUCCESS;
07411 }

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

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

07362 {
07363    switch (cmd) {
07364    case CLI_INIT:
07365       e->command = "iax2 set debug trunk {on|off}";
07366       e->usage =
07367          "Usage: iax2 set debug trunk {on|off}\n"
07368          "       Enables/Disables debugging of IAX trunking\n";
07369       return NULL;
07370    case CLI_GENERATE:
07371       return NULL;
07372    }
07373 
07374    if (a->argc != e->args)
07375       return CLI_SHOWUSAGE;
07376 
07377    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07378       iaxtrunkdebug = 1;
07379       ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07380    } else {
07381       iaxtrunkdebug = 0;
07382       ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07383    }
07384    return CLI_SUCCESS;
07385 }

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

03879 {
03880    int mtuv;
03881 
03882    switch (cmd) {
03883    case CLI_INIT:
03884       e->command = "iax2 set mtu";
03885       e->usage =
03886          "Usage: iax2 set mtu <value>\n"
03887          "       Set the system-wide IAX IP mtu to <value> bytes net or\n"
03888          "       zero to disable. Disabling means that the operating system\n"
03889          "       must handle fragmentation of UDP packets when the IAX2 trunk\n"
03890          "       packet exceeds the UDP payload size. This is substantially\n"
03891          "       below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03892          "       greater for G.711 samples.\n";
03893       return NULL;
03894    case CLI_GENERATE:
03895       return NULL;
03896    }
03897 
03898    if (a->argc != 4)
03899       return CLI_SHOWUSAGE; 
03900    if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03901       mtuv = MAX_TRUNK_MTU;
03902    else
03903       mtuv = atoi(a->argv[3]);
03904 
03905    if (mtuv == 0) {
03906       ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 
03907       global_max_trunk_mtu = 0; 
03908       return CLI_SUCCESS; 
03909    }
03910    if (mtuv < 172 || mtuv > 4000) {
03911       ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 
03912       return CLI_SHOWUSAGE; 
03913    }
03914    ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 
03915    global_max_trunk_mtu = mtuv; 
03916    return CLI_SUCCESS;
03917 }

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

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

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

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

Definition at line 2537 of file chan_iax2.c.

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

02538 {
02539    struct ao2_iterator i;
02540    struct peercnt *peercnt;
02541    struct sockaddr_in sin;
02542    int found = 0;
02543 
02544    switch (cmd) {
02545    case CLI_INIT:
02546       e->command = "iax2 show callnumber usage";
02547       e->usage =
02548          "Usage: iax2 show callnumber usage [IP address]\n"
02549          "       Shows current IP addresses which are consuming iax2 call numbers\n";
02550       return NULL;
02551    case CLI_GENERATE:
02552       return NULL;
02553    case CLI_HANDLER:
02554       if (a->argc < 4 || a->argc > 5)
02555          return CLI_SHOWUSAGE;
02556 
02557       ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02558       i = ao2_iterator_init(peercnts, 0);
02559       while ((peercnt = ao2_iterator_next(&i))) {
02560          sin.sin_addr.s_addr = peercnt->addr;
02561          if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02562                ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02563                ao2_ref(peercnt, -1);
02564                found = 1;
02565                break;
02566          } else {
02567             ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02568          }
02569          ao2_ref(peercnt, -1);
02570       }
02571       ao2_iterator_destroy(&i);
02572 
02573       if (a->argc == 4) {
02574          ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
02575                           "Non-CallToken Validated Callno Used:   %d\n",
02576             global_maxcallno_nonval,
02577             total_nonval_callno_used);
02578 
02579          ast_cli(a->fd,   "Total Available Callno:                %d\n"
02580                           "Regular Callno Available:              %d\n"
02581                           "Trunk Callno Available:                %d\n",
02582             ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk),
02583             ao2_container_count(callno_pool),
02584             ao2_container_count(callno_pool_trunk));
02585       } else if (a->argc == 5 && !found) {
02586          ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02587       }
02588 
02589 
02590       return CLI_SUCCESS;
02591    default:
02592       return NULL;
02593    }
02594 }

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

Definition at line 7135 of file chan_iax2.c.

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

07136 {
07137 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s  %s  %9s\n"
07138 #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"
07139 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
07140    int x;
07141    int numchans = 0;
07142    char first_message[10] = { 0, };
07143    char last_message[10] = { 0, };
07144 
07145    switch (cmd) {
07146    case CLI_INIT:
07147       e->command = "iax2 show channels";
07148       e->usage =
07149          "Usage: iax2 show channels\n"
07150          "       Lists all currently active IAX channels.\n";
07151       return NULL;
07152    case CLI_GENERATE:
07153       return NULL;
07154    }
07155 
07156    if (a->argc != 3)
07157       return CLI_SHOWUSAGE;
07158    ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07159    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07160       ast_mutex_lock(&iaxsl[x]);
07161       if (iaxs[x]) {
07162          int lag, jitter, localdelay;
07163          jb_info jbinfo;
07164          if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07165             jb_getinfo(iaxs[x]->jb, &jbinfo);
07166             jitter = jbinfo.jitter;
07167             localdelay = jbinfo.current - jbinfo.min;
07168          } else {
07169             jitter = -1;
07170             localdelay = 0;
07171          }
07172 
07173          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07174          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07175          lag = iaxs[x]->remote_rr.delay;
07176          ast_cli(a->fd, FORMAT,
07177             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07178             ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07179             S_OR(iaxs[x]->username, "(None)"),
07180             iaxs[x]->callno, iaxs[x]->peercallno,
07181             iaxs[x]->oseqno, iaxs[x]->iseqno,
07182             lag,
07183             jitter,
07184             localdelay,
07185             ast_getformatname(iaxs[x]->voiceformat),
07186             (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07187             first_message,
07188             (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07189             last_message);
07190          numchans++;
07191       }
07192       ast_mutex_unlock(&iaxsl[x]);
07193    }
07194    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07195    return CLI_SUCCESS;
07196 #undef FORMAT
07197 #undef FORMAT2
07198 #undef FORMATB
07199 }

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

Definition at line 6921 of file chan_iax2.c.

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

06922 {
06923    struct iax_firmware *cur = NULL;
06924 
06925    switch (cmd) {
06926    case CLI_INIT:
06927       e->command = "iax2 show firmware";
06928       e->usage =
06929          "Usage: iax2 show firmware\n"
06930          "       Lists all known IAX firmware images.\n";
06931       return NULL;
06932    case CLI_GENERATE:
06933       return NULL;
06934    }
06935 
06936    if (a->argc != 3 && a->argc != 4)
06937       return CLI_SHOWUSAGE;
06938 
06939    ast_cli(a->fd, "%-15.15s  %-15.15s %-15.15s\n", "Device", "Version", "Size");
06940    AST_LIST_LOCK(&firmwares);
06941    AST_LIST_TRAVERSE(&firmwares, cur, list) {
06942       if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname)))  {
06943          ast_cli(a->fd, "%-15.15s  %-15d %-15d\n", cur->fwh->devname, 
06944             ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06945       }
06946    }
06947    AST_LIST_UNLOCK(&firmwares);
06948 
06949    return CLI_SUCCESS;
06950 }

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

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

07286 {
07287    int numchans = 0;
07288 
07289    switch (cmd) {
07290    case CLI_INIT:
07291       e->command = "iax2 show netstats";
07292       e->usage =
07293          "Usage: iax2 show netstats\n"
07294          "       Lists network status for all currently active IAX channels.\n";
07295       return NULL;
07296    case CLI_GENERATE:
07297       return NULL;
07298    }
07299    if (a->argc != 3)
07300       return CLI_SHOWUSAGE;
07301    ast_cli(a->fd, "                           -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
07302    ast_cli(a->fd, "Channel               RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts FirstMsg    LastMsg\n");
07303    numchans = ast_cli_netstats(NULL, a->fd, 1);
07304    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07305    return CLI_SUCCESS;
07306 }

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 3726 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, iax2_peer::cid_name, iax2_peer::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), iax2_peer::context, iax2_peer::defaddr, iax2_peer::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::mailbox, iax2_peer::maxcallno, ast_cli_args::n, iax2_peer::name, iax2_peer::parkinglot, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, ast_cli_args::pos, iax2_peer::prefs, iax2_peer::secret, iax2_peer::smoothing, status, ast_cli_entry::usage, iax2_peer::username, and ast_cli_args::word.

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

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

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

06890 {
06891    switch (cmd) {
06892    case CLI_INIT:
06893       e->command = "iax2 show peers";
06894       e->usage =
06895          "Usage: iax2 show peers [registered] [like <pattern>]\n"
06896          "       Lists all known IAX2 peers.\n"
06897          "       Optional 'registered' argument lists only peers with known addresses.\n"
06898          "       Optional regular expression pattern is used to filter the peer list.\n";
06899       return NULL;
06900    case CLI_GENERATE:
06901       return NULL;
06902    }
06903 
06904    switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
06905    case RESULT_SHOWUSAGE:
06906       return CLI_SHOWUSAGE;
06907    case RESULT_FAILURE:
06908       return CLI_FAILURE;
06909    default:
06910       return CLI_SUCCESS;
06911    }
06912 }

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

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

07045 {
07046 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
07047 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
07048    struct iax2_registry *reg = NULL;
07049    char host[80];
07050    char perceived[80];
07051    int counter = 0;
07052 
07053    switch (cmd) {
07054    case CLI_INIT:
07055       e->command = "iax2 show registry";
07056       e->usage =
07057          "Usage: iax2 show registry\n"
07058          "       Lists all registration requests and status.\n";
07059       return NULL;
07060    case CLI_GENERATE:
07061       return NULL;
07062    }
07063    if (a->argc != 3)
07064       return CLI_SHOWUSAGE;
07065    ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07066    AST_LIST_LOCK(&registrations);
07067    AST_LIST_TRAVERSE(&registrations, reg, entry) {
07068       snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
07069       if (reg->us.sin_addr.s_addr) 
07070          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07071       else
07072          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07073       ast_cli(a->fd, FORMAT, host, 
07074                (reg->dnsmgr) ? "Y" : "N", 
07075                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07076       counter++;
07077    }
07078    AST_LIST_UNLOCK(&registrations);
07079    ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07080    return CLI_SUCCESS;
07081 #undef FORMAT
07082 #undef FORMAT2
07083 }

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

Definition at line 3832 of file chan_iax2.c.

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

03833 {
03834    struct iax_frame *cur;
03835    int cnt = 0, dead = 0, final = 0, i = 0;
03836 
03837    switch (cmd) {
03838    case CLI_INIT:
03839       e->command = "iax2 show stats";
03840       e->usage =
03841          "Usage: iax2 show stats\n"
03842          "       Display statistics on IAX channel driver.\n";
03843       return NULL;
03844    case CLI_GENERATE:
03845       return NULL;
03846    }
03847 
03848    if (a->argc != 3)
03849       return CLI_SHOWUSAGE;
03850 
03851    for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
03852       ast_mutex_lock(&iaxsl[i]);
03853       AST_LIST_TRAVERSE(&frame_queue[i], cur, list) {
03854          if (cur->retries < 0)
03855             dead++;
03856          if (cur->final)
03857             final++;
03858          cnt++;
03859       }
03860       ast_mutex_unlock(&iaxsl[i]);
03861    }
03862 
03863    ast_cli(a->fd, "    IAX Statistics\n");
03864    ast_cli(a->fd, "---------------------\n");
03865    ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03866    ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03867       trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03868    ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03869 
03870    trunk_timed = trunk_untimed = 0;
03871    if (trunk_maxmtu > trunk_nmaxmtu)
03872       trunk_nmaxmtu = trunk_maxmtu;
03873 
03874    return CLI_SUCCESS;
03875 }

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

Definition at line 6752 of file chan_iax2.c.

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

06753 {
06754    struct iax2_thread *thread = NULL;
06755    time_t t;
06756    int threadcount = 0, dynamiccount = 0;
06757    char type;
06758 
06759    switch (cmd) {
06760    case CLI_INIT:
06761       e->command = "iax2 show threads";
06762       e->usage =
06763          "Usage: iax2 show threads\n"
06764          "       Lists status of IAX helper threads\n";
06765       return NULL;
06766    case CLI_GENERATE:
06767       return NULL;
06768    }
06769    if (a->argc != 3)
06770       return CLI_SHOWUSAGE;
06771       
06772    ast_cli(a->fd, "IAX2 Thread Information\n");
06773    time(&t);
06774    ast_cli(a->fd, "Idle Threads:\n");
06775    AST_LIST_LOCK(&idle_list);
06776    AST_LIST_TRAVERSE(&idle_list, thread, list) {
06777 #ifdef DEBUG_SCHED_MULTITHREAD
06778       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 
06779          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06780 #else
06781       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
06782          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06783 #endif
06784       threadcount++;
06785    }
06786    AST_LIST_UNLOCK(&idle_list);
06787    ast_cli(a->fd, "Active Threads:\n");
06788    AST_LIST_LOCK(&active_list);
06789    AST_LIST_TRAVERSE(&active_list, thread, list) {
06790       if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06791          type = 'D';
06792       else
06793          type = 'P';
06794 #ifdef DEBUG_SCHED_MULTITHREAD
06795       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 
06796          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06797 #else
06798       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
06799          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06800 #endif
06801       threadcount++;
06802    }
06803    AST_LIST_UNLOCK(&active_list);
06804    ast_cli(a->fd, "Dynamic Threads:\n");
06805    AST_LIST_LOCK(&dynamic_list);
06806    AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06807 #ifdef DEBUG_SCHED_MULTITHREAD
06808       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06809          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06810 #else
06811       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06812          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06813 #endif
06814       dynamiccount++;
06815    }
06816    AST_LIST_UNLOCK(&dynamic_list);
06817    ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06818    return CLI_SUCCESS;
06819 }

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

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

06544 {
06545    regex_t regexbuf;
06546    int havepattern = 0;
06547 
06548 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
06549 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
06550 
06551    struct iax2_user *user = NULL;
06552    char auth[90];
06553    char *pstr = "";
06554    struct ao2_iterator i;
06555 
06556    switch (cmd) {
06557    case CLI_INIT:
06558       e->command = "iax2 show users [like]";
06559       e->usage =
06560          "Usage: iax2 show users [like <pattern>]\n"
06561          "       Lists all known IAX2 users.\n"
06562          "       Optional regular expression pattern is used to filter the user list.\n";
06563       return NULL;
06564    case CLI_GENERATE:
06565       return NULL;
06566    }
06567 
06568    switch (a->argc) {
06569    case 5:
06570       if (!strcasecmp(a->argv[3], "like")) {
06571          if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06572             return CLI_SHOWUSAGE;
06573          havepattern = 1;
06574       } else
06575          return CLI_SHOWUSAGE;
06576    case 3:
06577       break;
06578    default:
06579       return CLI_SHOWUSAGE;
06580    }
06581 
06582    ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06583    i = ao2_iterator_init(users, 0);
06584    for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
06585       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
06586          continue;
06587 
06588       if (!ast_strlen_zero(user->secret)) {
06589          ast_copy_string(auth,user->secret, sizeof(auth));
06590       } else if (!ast_strlen_zero(user->inkeys)) {
06591          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06592       } else
06593          ast_copy_string(auth, "-no secret-", sizeof(auth));
06594 
06595       if(ast_test_flag64(user, IAX_CODEC_NOCAP))
06596          pstr = "REQ Only";
06597       else if(ast_test_flag64(user, IAX_CODEC_NOPREFS))
06598          pstr = "Disabled";
06599       else
06600          pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06601 
06602       ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 
06603          user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06604          user->ha ? "Yes" : "No", pstr);
06605    }
06606    ao2_iterator_destroy(&i);
06607 
06608    if (havepattern)
06609       regfree(&regexbuf);
06610 
06611    return CLI_SUCCESS;
06612 #undef FORMAT
06613 #undef FORMAT2
06614 }

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

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

03613 {
03614    switch (cmd) {
03615    case CLI_INIT:
03616       e->command = "iax2 test losspct";
03617       e->usage =
03618          "Usage: iax2 test losspct <percentage>\n"
03619          "       For testing, throws away <percentage> percent of incoming packets\n";
03620       return NULL;
03621    case CLI_GENERATE:
03622       return NULL;
03623    }
03624    if (a->argc != 4)
03625       return CLI_SHOWUSAGE;
03626 
03627    test_losspct = atoi(a->argv[3]);
03628 
03629    return CLI_SUCCESS;
03630 }

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

Definition at line 6821 of file chan_iax2.c.

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

06822 {
06823    struct iax2_peer *p;
06824 
06825    switch (cmd) {
06826    case CLI_INIT:
06827       e->command = "iax2 unregister";
06828       e->usage =
06829          "Usage: iax2 unregister <peername>\n"
06830          "       Unregister (force expiration) an IAX2 peer from the registry.\n";
06831       return NULL;
06832    case CLI_GENERATE:
06833       return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06834    }
06835 
06836    if (a->argc != 3)
06837       return CLI_SHOWUSAGE;
06838 
06839    p = find_peer(a->argv[2], 1);
06840    if (p) {
06841       if (p->expire > 0) {
06842          struct iax2_peer tmp_peer = {
06843             .name = a->argv[2],
06844          };
06845          struct iax2_peer *peer;
06846 
06847          peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06848          if (peer) {
06849             expire_registry(peer_ref(peer)); /* will release its own reference when done */
06850             peer_unref(peer); /* ref from ao2_find() */
06851             ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06852          } else {
06853             ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06854          }
06855       } else {
06856          ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06857       }
06858    } else {
06859       ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06860    }
06861    return CLI_SUCCESS;
06862 }

static void handle_deferred_full_frames ( struct iax2_thread thread  )  [static]

Handle any deferred full frames for this thread.

Definition at line 9514 of file chan_iax2.c.

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

09515 {
09516    struct iax2_pkt_buf *pkt_buf;
09517 
09518    ast_mutex_lock(&thread->lock);
09519 
09520    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09521       ast_mutex_unlock(&thread->lock);
09522 
09523       thread->buf = pkt_buf->buf;
09524       thread->buf_len = pkt_buf->len;
09525       thread->buf_size = pkt_buf->len + 1;
09526       
09527       socket_process(thread);
09528 
09529       thread->buf = NULL;
09530       ast_free(pkt_buf);
09531 
09532       ast_mutex_lock(&thread->lock);
09533    }
09534 
09535    ast_mutex_unlock(&thread->lock);
09536 }

static int handle_error ( void   )  [static]

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

03268 {
03269    /* XXX Ideally we should figure out why an error occurred and then abort those
03270       rather than continuing to try.  Unfortunately, the published interface does
03271       not seem to work XXX */
03272 #if 0
03273    struct sockaddr_in *sin;
03274    int res;
03275    struct msghdr m;
03276    struct sock_extended_err e;
03277    m.msg_name = NULL;
03278    m.msg_namelen = 0;
03279    m.msg_iov = NULL;
03280    m.msg_control = &e;
03281    m.msg_controllen = sizeof(e);
03282    m.msg_flags = 0;
03283    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03284    if (res < 0)
03285       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03286    else {
03287       if (m.msg_controllen) {
03288          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03289          if (sin) 
03290             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03291          else
03292             ast_log(LOG_WARNING, "No address detected??\n");
03293       } else {
03294          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03295       }
03296    }
03297 #endif
03298    return 0;
03299 }

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

Acknowledgment received for OUR registration.

Definition at line 8410 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, sched, iax2_registry::us, and iax_ies::username.

Referenced by socket_process().

08411 {
08412    struct iax2_registry *reg;
08413    /* Start pessimistic */
08414    char peer[256] = "";
08415    char msgstatus[60];
08416    int refresh = 60;
08417    char ourip[256] = "<Unspecified>";
08418    struct sockaddr_in oldus;
08419    struct sockaddr_in us;
08420    int oldmsgs;
08421    struct sockaddr_in reg_addr;
08422 
08423    memset(&us, 0, sizeof(us));
08424    if (ies->apparent_addr) {
08425       memmove(&us, ies->apparent_addr, sizeof(us));
08426    }
08427    if (ies->username) {
08428       ast_copy_string(peer, ies->username, sizeof(peer));
08429    }
08430    if (ies->refresh) {
08431       refresh = ies->refresh;
08432    }
08433    if (ies->calling_number) {
08434       /* We don't do anything with it really, but maybe we should */
08435    }
08436    reg = iaxs[callno]->reg;
08437    if (!reg) {
08438       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08439       return -1;
08440    }
08441    memcpy(&oldus, &reg->us, sizeof(oldus));
08442    oldmsgs = reg->messages;
08443    ast_sockaddr_to_sin(&reg->addr, &reg_addr);
08444    if (inaddrcmp(&reg_addr, sin)) {
08445       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08446       return -1;
08447    }
08448    memcpy(&reg->us, &us, sizeof(reg->us));
08449    if (ies->msgcount >= 0) {
08450       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
08451    }
08452    /* always refresh the registration at the interval requested by the server
08453       we are registering to
08454    */
08455    reg->refresh = refresh;
08456    reg->expire = iax2_sched_replace(reg->expire, sched,
08457       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08458    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
08459       if (reg->messages > 255) {
08460          snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08461       } else if (reg->messages > 1) {
08462          snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
08463       } else if (reg->messages > 0) {
08464          ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
08465       } else {
08466          ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
08467       }
08468       snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08469       ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08470       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08471    }
08472    reg->regstate = REG_STATE_REGISTERED;
08473    return 0;
08474 }

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

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

02733 {
02734    if (frametype != AST_FRAME_IAX) {
02735       return 0;
02736    }
02737    switch (subclass) {
02738    case IAX_COMMAND_NEW:
02739    case IAX_COMMAND_REGREQ:
02740    case IAX_COMMAND_FWDOWNL:
02741    case IAX_COMMAND_REGREL:
02742       return 1;
02743    case IAX_COMMAND_POKE:
02744       if (!inbound) {
02745          return 1;
02746       }
02747       break;
02748    }
02749    return 0;
02750 }

static void iax2_ami_channelupdate ( struct chan_iax2_pvt pvt  )  [static]

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

Definition at line 1322 of file chan_iax2.c.

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

Referenced by ast_iax2_new(), and iax2_answer().

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

static int iax2_answer ( struct ast_channel c  )  [static]

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

05595 {
05596    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05597    ast_debug(1, "Answering IAX2 call\n");
05598    ast_mutex_lock(&iaxsl[callno]);
05599    if (iaxs[callno])
05600       iax2_ami_channelupdate(iaxs[callno]);
05601    ast_mutex_unlock(&iaxsl[callno]);
05602    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05603 }

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

Definition at line 8476 of file chan_iax2.c.

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

Referenced by iax2_register().

08478 {
08479    struct iax2_registry *reg;
08480 
08481    if (!(reg = ast_calloc(1, sizeof(*reg))))
08482       return -1;
08483 
08484    reg->addr.ss.ss_family = AF_INET;
08485    if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08486       ast_free(reg);
08487       return -1;
08488    }
08489 
08490    ast_copy_string(reg->username, username, sizeof(reg->username));
08491 
08492    if (secret)
08493       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08494 
08495    reg->expire = -1;
08496    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08497    ast_sockaddr_set_port(&reg->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08498 
08499    AST_LIST_LOCK(&registrations);
08500    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
08501    AST_LIST_UNLOCK(&registrations);
08502    
08503    return 0;
08504 }

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

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

05440 {
05441    struct ast_channel *cs[3];
05442    struct ast_channel *who, *other;
05443    int to = -1;
05444    int res = -1;
05445    int transferstarted=0;
05446    struct ast_frame *f;
05447    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05448    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05449    struct timeval waittimer = {0, 0};
05450 
05451    /* We currently do not support native bridging if a timeoutms value has been provided */
05452    if (timeoutms > 0) {
05453       return AST_BRIDGE_FAILED;
05454    }
05455 
05456    timeoutms = -1;
05457 
05458    lock_both(callno0, callno1);
05459    if (!iaxs[callno0] || !iaxs[callno1]) {
05460       unlock_both(callno0, callno1);
05461       return AST_BRIDGE_FAILED;
05462    }
05463    /* Put them in native bridge mode */
05464    if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05465       iaxs[callno0]->bridgecallno = callno1;
05466       iaxs[callno1]->bridgecallno = callno0;
05467    }
05468    unlock_both(callno0, callno1);
05469 
05470    /* If not, try to bridge until we can execute a transfer, if we can */
05471    cs[0] = c0;
05472    cs[1] = c1;
05473    for (/* ever */;;) {
05474       /* Check in case we got masqueraded into */
05475       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05476          ast_verb(3, "Can't masquerade, we're different...\n");
05477          /* Remove from native mode */
05478          if (c0->tech == &iax2_tech) {
05479             ast_mutex_lock(&iaxsl[callno0]);
05480             iaxs[callno0]->bridgecallno = 0;
05481             ast_mutex_unlock(&iaxsl[callno0]);
05482          }
05483          if (c1->tech == &iax2_tech) {
05484             ast_mutex_lock(&iaxsl[callno1]);
05485             iaxs[callno1]->bridgecallno = 0;
05486             ast_mutex_unlock(&iaxsl[callno1]);
05487          }
05488          return AST_BRIDGE_FAILED_NOWARN;
05489       }
05490       if (c0->nativeformats != c1->nativeformats) {
05491          char buf0[256];
05492          char buf1[256];
05493          ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05494          ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05495          ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05496          /* Remove from native mode */
05497          lock_both(callno0, callno1);
05498          if (iaxs[callno0])
05499             iaxs[callno0]->bridgecallno = 0;
05500          if (iaxs[callno1])
05501             iaxs[callno1]->bridgecallno = 0;
05502          unlock_both(callno0, callno1);
05503          return AST_BRIDGE_FAILED_NOWARN;
05504       }
05505       /* check if transfered and if we really want native bridging */
05506       if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05507          /* Try the transfer */
05508          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05509                      ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05510             ast_log(LOG_WARNING, "Unable to start the transfer\n");
05511          transferstarted = 1;
05512       }
05513       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05514          /* Call has been transferred.  We're no longer involved */
05515          struct timeval now = ast_tvnow();
05516          if (ast_tvzero(waittimer)) {
05517             waittimer = now;
05518          } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05519             c0->_softhangup |= AST_SOFTHANGUP_DEV;
05520             c1->_softhangup |= AST_SOFTHANGUP_DEV;
05521             *fo = NULL;
05522             *rc = c0;
05523             res = AST_BRIDGE_COMPLETE;
05524             break;
05525          }
05526       }
05527       to = 1000;
05528       who = ast_waitfor_n(cs, 2, &to);
05529       if (timeoutms > -1) {
05530          timeoutms -= (1000 - to);
05531          if (timeoutms < 0)
05532             timeoutms = 0;
05533       }
05534       if (!who) {
05535          if (!timeoutms) {
05536             res = AST_BRIDGE_RETRY;
05537             break;
05538          }
05539          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05540             res = AST_BRIDGE_FAILED;
05541             break;
05542          }
05543          continue;
05544       }
05545       f = ast_read(who);
05546       if (!f) {
05547          *fo = NULL;
05548          *rc = who;
05549          res = AST_BRIDGE_COMPLETE;
05550          break;
05551       }
05552       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) {
05553          *fo = f;
05554          *rc = who;
05555          res =  AST_BRIDGE_COMPLETE;
05556          break;
05557       }
05558       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
05559       if ((f->frametype == AST_FRAME_VOICE) ||
05560          (f->frametype == AST_FRAME_TEXT) ||
05561          (f->frametype == AST_FRAME_VIDEO) || 
05562          (f->frametype == AST_FRAME_IMAGE) ||
05563          (f->frametype == AST_FRAME_DTMF) ||
05564          (f->frametype == AST_FRAME_CONTROL)) {
05565          /* monitored dtmf take out of the bridge.
05566           * check if we monitor the specific source.
05567           */
05568          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05569          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05570             *rc = who;
05571             *fo = f;
05572             res = AST_BRIDGE_COMPLETE;
05573             /* Remove from native mode */
05574             break;
05575          }
05576          /* everything else goes to the other side */
05577          ast_write(other, f);
05578       }
05579       ast_frfree(f);
05580       /* Swap who gets priority */
05581       cs[2] = cs[0];
05582       cs[0] = cs[1];
05583       cs[1] = cs[2];
05584    }
05585    lock_both(callno0, callno1);
05586    if(iaxs[callno0])
05587       iaxs[callno0]->bridgecallno = 0;
05588    if(iaxs[callno1])
05589       iaxs[callno1]->bridgecallno = 0;
05590    unlock_both(callno0, callno1);
05591    return res;
05592 }

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

Definition at line 4987 of file chan_iax2.c.

References ast_channel::_state, add_empty_calltoken_ie(), 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(), CALLNO_TO_PTR, capability, ast_channel::connected, context, ast_channel::context, create_addr(), ast_datastore::data, ast_channel::dialed, chan_iax2_pvt::encmethods, 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, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, chan_iax2_pvt::mohinterpret, chan_iax2_pvt::mohsuggest, ast_party_id::name, ast_channel::name, ast_channel::nativeformats, ast_party_dialed::number, ast_party_id::number, parse_dial_string(), pbx_builtin_getvar_helper(), chan_iax2_pvt::pingtime, ast_party_number::plan, PTR_TO_CALLNO, ast_channel::redirecting, sched, secret, send_command(), chan_iax2_pvt::sockfd, ast_party_dialed::str, ast_party_name::str, ast_party_number::str, ast_channel::tech_pvt, ast_party_dialed::transit_network_select, chan_iax2_pvt::username, ast_party_name::valid, ast_party_number::valid, and var.

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

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

13750 {
13751    int res = 0;
13752    struct iax2_dpcache *dp = NULL;
13753 #if 0
13754    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13755 #endif
13756    if ((priority != 1) && (priority != 2))
13757       return 0;
13758 
13759    AST_LIST_LOCK(&dpcache);
13760    if ((dp = find_cache(chan, data, context, exten, priority))) {
13761       if (dp->flags & CACHE_FLAG_CANEXIST)
13762          res = 1;
13763    } else {
13764       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13765    }
13766    AST_LIST_UNLOCK(&dpcache);
13767 
13768    return res;
13769 }

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

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

04661 {
04662    struct timeval t = ast_tvnow();
04663    struct ast_tm tm;
04664    unsigned int tmp;
04665    ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04666    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
04667    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
04668    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
04669    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
04670    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
04671    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
04672    return tmp;
04673 }

static void iax2_destroy ( int  callno  )  [static]

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

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

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 1770 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, DONT_RESCHEDULE, IAX_MAXAUTHREQ, iaxsl, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, iax2_user::name, OBJ_POINTER, chan_iax2_pvt::pingid, sched, user, user_unref(), chan_iax2_pvt::username, and users.

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

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

static int iax2_devicestate ( void *  data  )  [static]

Part of the device state notification system ---.

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

13955 {
13956    struct parsed_dial_string pds;
13957    char *tmp = ast_strdupa(data);
13958    struct iax2_peer *p;
13959    int res = AST_DEVICE_INVALID;
13960 
13961    memset(&pds, 0, sizeof(pds));
13962    parse_dial_string(tmp, &pds);
13963 
13964    if (ast_strlen_zero(pds.peer)) {
13965       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13966       return res;
13967    }
13968    
13969    ast_debug(3, "Checking device state for device %s\n", pds.peer);
13970 
13971    /* SLD: FIXME: second call to find_peer during registration */
13972    if (!(p = find_peer(pds.peer, 1)))
13973       return res;
13974 
13975    res = AST_DEVICE_UNAVAILABLE;
13976    ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13977       pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13978    
13979    if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
13980        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13981       /* Peer is registered, or have default IP address
13982          and a valid registration */
13983       if (p->historicms == 0 || p->historicms <= p->maxms)
13984          /* let the core figure out whether it is in use or not */
13985          res = AST_DEVICE_UNKNOWN;  
13986    }
13987 
13988    peer_unref(p);
13989 
13990    return res;
13991 }

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

Definition at line 4263 of file chan_iax2.c.

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

04264 {
04265    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04266 }

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

Definition at line 4268 of file chan_iax2.c.

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

04269 {
04270    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04271 }

static int iax2_do_register ( struct iax2_registry reg  )  [static]

Definition at line 11760 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, 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, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), and iax2_registry::username.

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

11761 {
11762    struct iax_ie_data ied;
11763    if (iaxdebug)
11764       ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11765 
11766    if (reg->dnsmgr && 
11767        ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(&reg->addr))) {
11768       /* Maybe the IP has changed, force DNS refresh */
11769       ast_dnsmgr_refresh(reg->dnsmgr);
11770    }
11771    
11772    /*
11773     * if IP has Changed, free allocated call to create a new one with new IP
11774     * call has the pointer to IP and must be updated to the new one
11775     */
11776    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11777       int callno = reg->callno;
11778       ast_mutex_lock(&iaxsl[callno]);
11779       iax2_destroy(callno);
11780       ast_mutex_unlock(&iaxsl[callno]);
11781       reg->callno = 0;
11782    }
11783    if (!ast_sockaddr_ipv4(&reg->addr)) {
11784       if (iaxdebug)
11785          ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11786       /* Setup the next registration attempt */
11787       reg->expire = iax2_sched_replace(reg->expire, sched, 
11788          (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11789       return -1;
11790    }
11791 
11792    if (!reg->callno) {
11793       struct sockaddr_in reg_addr;
11794 
11795       ast_debug(3, "Allocate call number\n");
11796 
11797       ast_sockaddr_to_sin(&reg->addr, &reg_addr);
11798 
11799       reg->callno = find_callno_locked(0, 0, &reg_addr, NEW_FORCE, defaultsockfd, 0);
11800       if (reg->callno < 1) {
11801          ast_log(LOG_WARNING, "Unable to create call for registration\n");
11802          return -1;
11803       } else
11804          ast_debug(3, "Registration created on call %d\n", reg->callno);
11805       iaxs[reg->callno]->reg = reg;
11806       ast_mutex_unlock(&iaxsl[reg->callno]);
11807    }
11808    /* Setup the next registration a little early */
11809    reg->expire = iax2_sched_replace(reg->expire, sched, 
11810       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11811    /* Send the request */
11812    memset(&ied, 0, sizeof(ied));
11813    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11814    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11815    add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */
11816    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11817    reg->regstate = REG_STATE_REGSENT;
11818    return 0;
11819 }

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

Definition at line 8257 of file chan_iax2.c.

References __iax2_do_register_s(), and schedule_action.

Referenced by iax2_ack_registry(), and iax2_do_register().

08258 {
08259 #ifdef SCHED_MULTITHREADED
08260    if (schedule_action(__iax2_do_register_s, data))
08261 #endif      
08262       __iax2_do_register_s(data);
08263    return 0;
08264 }

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

Definition at line 9032 of file chan_iax2.c.

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

Referenced by find_cache(), and socket_process().

09033 {
09034    struct iax_ie_data ied;
09035    /* Auto-hangup with 30 seconds of inactivity */
09036    iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
09037       sched, 30000, auto_hangup, (void *)(long)callno);
09038    memset(&ied, 0, sizeof(ied));
09039    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09040    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09041    dp->flags |= CACHE_FLAG_TRANSMITTED;
09042 }

static void * iax2_dup_variable_datastore ( void *   )  [static]

Definition at line 1336 of file chan_iax2.c.

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

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

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

Execute IAX2 dialplan switch.

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

13796 {
13797    char odata[256];
13798    char req[256];
13799    char *ncontext;
13800    struct iax2_dpcache *dp = NULL;
13801    struct ast_app *dial = NULL;
13802 #if 0
13803    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);
13804 #endif
13805    if (priority == 2) {
13806       /* Indicate status, can be overridden in dialplan */
13807       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13808       if (dialstatus) {
13809          dial = pbx_findapp(dialstatus);
13810          if (dial) 
13811             pbx_exec(chan, dial, "");
13812       }
13813       return -1;
13814    } else if (priority != 1)
13815       return -1;
13816 
13817    AST_LIST_LOCK(&dpcache);
13818    if ((dp = find_cache(chan, data, context, exten, priority))) {
13819       if (dp->flags & CACHE_FLAG_EXISTS) {
13820          ast_copy_string(odata, data, sizeof(odata));
13821          ncontext = strchr(odata, '/');
13822          if (ncontext) {
13823             *ncontext = '\0';
13824             ncontext++;
13825             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13826          } else {
13827             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13828          }
13829          ast_verb(3, "Executing Dial('%s')\n", req);
13830       } else {
13831          AST_LIST_UNLOCK(&dpcache);
13832          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13833          return -1;
13834       }
13835    }
13836    AST_LIST_UNLOCK(&dpcache);
13837 
13838    if ((dial = pbx_findapp("Dial")))
13839       return pbx_exec(chan, dial, req);
13840    else
13841       ast_log(LOG_WARNING, "No dial application registered\n");
13842 
13843    return -1;
13844 }

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

13727 {
13728    int res = 0;
13729    struct iax2_dpcache *dp = NULL;
13730 #if 0
13731    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13732 #endif
13733    if ((priority != 1) && (priority != 2))
13734       return 0;
13735 
13736    AST_LIST_LOCK(&dpcache);
13737    if ((dp = find_cache(chan, data, context, exten, priority))) {
13738       if (dp->flags & CACHE_FLAG_EXISTS)
13739          res = 1;
13740    } else {
13741       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13742    }
13743    AST_LIST_UNLOCK(&dpcache);
13744 
13745    return res;
13746 }

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

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

04291 {
04292    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04293    ast_mutex_lock(&iaxsl[callno]);
04294    if (iaxs[callno])
04295       iaxs[callno]->owner = newchan;
04296    else
04297       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04298    ast_mutex_unlock(&iaxsl[callno]);
04299    return 0;
04300 }

static void iax2_frame_free ( struct iax_frame fr  )  [static]

Definition at line 1799 of file chan_iax2.c.

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

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

01800 {
01801    ast_sched_thread_del(sched, fr->retrans);
01802    iax_frame_free(fr);
01803 }

static void iax2_free_variable_datastore ( void *   )  [static]

Definition at line 1360 of file chan_iax2.c.

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

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

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

Definition at line 1733 of file chan_iax2.c.

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

Referenced by __find_callno().

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

static int iax2_getpeertrunk ( struct sockaddr_in  sin  )  [static]

Definition at line 5669 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, peer_unref(), and peers.

Referenced by check_access().

05670 {
05671    struct iax2_peer *peer;
05672    int res = 0;
05673    struct ao2_iterator i;
05674 
05675    i = ao2_iterator_init(peers, 0);
05676    while ((peer = ao2_iterator_next(&i))) {
05677       struct sockaddr_in peer_addr;
05678 
05679       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05680 
05681       if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05682           (peer_addr.sin_port == sin.sin_port)) {
05683          res = ast_test_flag64(peer, IAX_TRUNK);
05684          peer_unref(peer);
05685          break;
05686       }
05687       peer_unref(peer);
05688    }
05689    ao2_iterator_destroy(&i);
05690 
05691    return res;
05692 }

static int iax2_hangup ( struct ast_channel c  )  [static]

Definition at line 5195 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, 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, ast_channel::name, PTR_TO_CALLNO, sched, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.

05196 {
05197    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05198    struct iax_ie_data ied;
05199    int alreadygone;
05200    memset(&ied, 0, sizeof(ied));
05201    ast_mutex_lock(&iaxsl[callno]);
05202    if (callno && iaxs[callno]) {
05203       ast_debug(1, "We're hanging up %s now...\n", c->name);
05204       alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
05205       /* Send the hangup unless we have had a transmission error or are already gone */
05206       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05207       if (!iaxs[callno]->error && !alreadygone) {
05208          if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05209             ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05210          }
05211          if (!iaxs[callno]) {
05212             ast_mutex_unlock(&iaxsl[callno]);
05213             return 0;
05214          }
05215       }
05216       /* Explicitly predestroy it */
05217       iax2_predestroy(callno);
05218       /* If we were already gone to begin with, destroy us now */
05219       if (iaxs[callno] && alreadygone) {
05220          ast_debug(1, "Really destroying %s now...\n", c->name);
05221          iax2_destroy(callno);
05222       } else if (iaxs[callno]) {
05223          if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05224             ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!!  Destroying immediately.\n", callno);
05225             iax2_destroy(callno);
05226          }
05227       }
05228    } else if (c->tech_pvt) {
05229       /* If this call no longer exists, but the channel still
05230        * references it we need to set the channel's tech_pvt to null
05231        * to avoid ast_channel_free() trying to free it.
05232        */
05233       c->tech_pvt = NULL;
05234    }
05235    ast_mutex_unlock(&iaxsl[callno]);
05236    ast_verb(3, "Hungup '%s'\n", c->name);
05237    return 0;
05238 }

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

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

05606 {
05607    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05608    struct chan_iax2_pvt *pvt;
05609    int res = 0;
05610 
05611    if (iaxdebug)
05612       ast_debug(1, "Indicating condition %d\n", condition);
05613 
05614    ast_mutex_lock(&iaxsl[callno]);
05615    pvt = iaxs[callno];
05616 
05617    if (wait_for_peercallno(pvt)) {
05618       res = -1;
05619       goto done;
05620    }
05621 
05622    switch (condition) {
05623    case AST_CONTROL_HOLD:
05624       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05625          ast_moh_start(c, data, pvt->mohinterpret);
05626          goto done;
05627       }
05628       break;
05629    case AST_CONTROL_UNHOLD:
05630       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05631          ast_moh_stop(c);
05632          goto done;
05633       }
05634       break;
05635    case AST_CONTROL_CONNECTED_LINE:
05636       if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
05637          goto done;
05638       break;
05639    }
05640 
05641    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05642 
05643 done:
05644    ast_mutex_unlock(&iaxsl[callno]);
05645 
05646    return res;
05647 }

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

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

Referenced by iax2_send().

05358 {
05359    int res = 0;
05360    struct chan_iax2_pvt *pvt = (void *) vpvt;
05361    struct MD5Context md5;
05362    char key[17] = "";
05363    struct iax_ie_data ied = {
05364       .pos = 0,   
05365    };
05366    
05367    ast_mutex_lock(&iaxsl[pvt->callno]);
05368    pvt->keyrotateid = 
05369       ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05370 
05371    snprintf(key, sizeof(key), "%lX", ast_random());
05372 
05373    MD5Init(&md5);
05374    MD5Update(&md5, (unsigned char *) key, strlen(key));
05375    MD5Final((unsigned char *) key, &md5);
05376 
05377    IAX_DEBUGDIGEST("Sending", key);
05378 
05379    iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05380 
05381    res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05382 
05383    build_ecx_key((unsigned char *) key, pvt);
05384 
05385    ast_mutex_unlock(&iaxsl[pvt->callno]);
05386 
05387    return res;
05388 }

static void iax2_lock_owner ( int  callno  )  [static]

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

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

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

Part of the IAX2 Switch interface.

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

13773 {
13774    int res = 0;
13775    struct iax2_dpcache *dp = NULL;
13776 #if 0
13777    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13778 #endif
13779    if ((priority != 1) && (priority != 2))
13780       return 0;
13781 
13782    AST_LIST_LOCK(&dpcache);
13783    if ((dp = find_cache(chan, data, context, exten, priority))) {
13784       if (dp->flags & CACHE_FLAG_MATCHMORE)
13785          res = 1;
13786    } else {
13787       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13788    }
13789    AST_LIST_UNLOCK(&dpcache);
13790 
13791    return res;
13792 }

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

Definition at line 11964 of file chan_iax2.c.

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

Referenced by iax2_poke_peer().

11965 {
11966    struct iax2_peer *peer = (struct iax2_peer *)data;
11967    peer->pokeexpire = -1;
11968 #ifdef SCHED_MULTITHREADED
11969    if (schedule_action(__iax2_poke_noanswer, data))
11970 #endif      
11971       __iax2_poke_noanswer(data);
11972    peer_unref(peer);
11973    return 0;
11974 }

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

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

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

11986 {
11987    int callno;
11988    struct sockaddr_in peer_addr;
11989 
11990    if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
11991       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
11992         immediately after clearing things out */
11993       peer->lastms = 0;
11994       peer->historicms = 0;
11995       peer->pokeexpire = -1;
11996       peer->callno = 0;
11997       return 0;
11998    }
11999 
12000    ast_sockaddr_to_sin(&peer->addr, &peer_addr);
12001 
12002    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
12003    if ((callno = peer->callno) > 0) {
12004       ast_log(LOG_NOTICE, "Still have a callno...\n");
12005       ast_mutex_lock(&iaxsl[callno]);
12006       iax2_destroy(callno);
12007       ast_mutex_unlock(&iaxsl[callno]);
12008    }
12009    if (heldcall)
12010       ast_mutex_unlock(&iaxsl[heldcall]);
12011    callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
12012    if (heldcall)
12013       ast_mutex_lock(&iaxsl[heldcall]);
12014    if (peer->callno < 1) {
12015       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12016       return -1;
12017    }
12018 
12019    /* Speed up retransmission times for this qualify call */
12020    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
12021    iaxs[peer->callno]->peerpoke = peer;
12022 
12023    if (peer->pokeexpire > -1) {
12024       if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
12025          peer->pokeexpire = -1;
12026          peer_unref(peer);
12027       }
12028    }
12029  
12030    /* Queue up a new task to handle no reply */
12031    /* If the host is already unreachable then use the unreachable interval instead */
12032    if (peer->lastms < 0)
12033       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
12034    else
12035       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
12036 
12037    if (peer->pokeexpire == -1)
12038       peer_unref(peer);
12039 
12040    /* And send the poke */
12041    ast_mutex_lock(&iaxsl[callno]);
12042    if (iaxs[callno]) {
12043       struct iax_ie_data ied = {
12044          .buf = { 0 },
12045          .pos = 0,
12046       };
12047       add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
12048       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12049    }
12050    ast_mutex_unlock(&iaxsl[callno]);
12051 
12052    return 0;
12053 }

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

Definition at line 11976 of file chan_iax2.c.

References iax2_poke_peer().

Referenced by load_module().

11977 {
11978    struct iax2_peer *peer = obj;
11979 
11980    iax2_poke_peer(peer, 0);
11981 
11982    return 0;
11983 }

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

Definition at line 9069 of file chan_iax2.c.

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

Referenced by __iax2_poke_noanswer(), and socket_process().

09070 {
09071    struct iax2_peer *peer = (struct iax2_peer *)data;
09072    peer->pokeexpire = -1;
09073 #ifdef SCHED_MULTITHREADED
09074    if (schedule_action(__iax2_poke_peer_s, data))
09075 #endif      
09076       __iax2_poke_peer_s(data);
09077    return 0;
09078 }

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

03351 {
03352    struct ast_channel *c = NULL;
03353    struct chan_iax2_pvt *pvt = iaxs[callno];
03354 
03355    if (!pvt)
03356       return -1;
03357 
03358    if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
03359       iax2_destroy_helper(pvt);
03360       ast_set_flag64(pvt, IAX_ALREADYGONE);
03361    }
03362 
03363    if ((c = pvt->owner)) {
03364       c->tech_pvt = NULL;
03365       iax2_queue_hangup(callno);
03366       pvt->owner = NULL;
03367       ast_module_unref(ast_module_info->self);
03368    }
03369 
03370    return 0;
03371 }

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

Definition at line 11615 of file chan_iax2.c.

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

Referenced by find_idle_thread(), and start_network_thread().

11616 {
11617    struct iax2_thread *thread = data;
11618    struct timeval wait;
11619    struct timespec ts;
11620    int put_into_idle = 0;
11621    int first_time = 1;
11622    int old_state;
11623 
11624    ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11625 
11626    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11627    pthread_cleanup_push(iax2_process_thread_cleanup, data);
11628 
11629    for (;;) {
11630       /* Wait for something to signal us to be awake */
11631       ast_mutex_lock(&thread->lock);
11632 
11633       if (thread->stop) {
11634          ast_mutex_unlock(&thread->lock);
11635          break;
11636       }
11637 
11638       /* Flag that we're ready to accept signals */
11639       if (first_time) {
11640          signal_condition(&thread->init_lock, &thread->init_cond);
11641          first_time = 0;
11642       }
11643 
11644       /* Put into idle list if applicable */
11645       if (put_into_idle) {
11646          insert_idle_thread(thread);
11647       }
11648 
11649       if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11650          struct iax2_thread *t = NULL;
11651          /* Wait to be signalled or time out */
11652          wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11653          ts.tv_sec = wait.tv_sec;
11654          ts.tv_nsec = wait.tv_usec * 1000;
11655          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11656             /* This thread was never put back into the available dynamic
11657              * thread list, so just go away. */
11658             if (!put_into_idle || thread->stop) {
11659                ast_mutex_unlock(&thread->lock);
11660                break;
11661             }
11662             AST_LIST_LOCK(&dynamic_list);
11663             /* Account for the case where this thread is acquired *right* after a timeout */
11664             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11665                ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11666             AST_LIST_UNLOCK(&dynamic_list);
11667             if (t) {
11668                /* This dynamic thread timed out waiting for a task and was
11669                 * not acquired immediately after the timeout, 
11670                 * so it's time to go away. */
11671                ast_mutex_unlock(&thread->lock);
11672                break;
11673             }
11674             /* Someone grabbed our thread *right* after we timed out.
11675              * Wait for them to set us up with something to do and signal
11676              * us to continue. */
11677             wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11678             ts.tv_sec = wait.tv_sec;
11679             ts.tv_nsec = wait.tv_usec * 1000;
11680             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11681                ast_mutex_unlock(&thread->lock);
11682                break;
11683             }
11684          }
11685       } else {
11686          ast_cond_wait(&thread->cond, &thread->lock);
11687       }
11688 
11689       /* Go back into our respective list */
11690       put_into_idle = 1;
11691 
11692       ast_mutex_unlock(&thread->lock);
11693 
11694       if (thread->stop) {
11695          break;
11696       }
11697 
11698       if (thread->iostate == IAX_IOSTATE_IDLE)
11699          continue;
11700 
11701       /* See what we need to do */
11702       switch (thread->iostate) {
11703       case IAX_IOSTATE_READY:
11704          thread->actions++;
11705          thread->iostate = IAX_IOSTATE_PROCESSING;
11706          socket_process(thread);
11707          handle_deferred_full_frames(thread);
11708          break;
11709       case IAX_IOSTATE_SCHEDREADY:
11710          thread->actions++;
11711          thread->iostate = IAX_IOSTATE_PROCESSING;
11712 #ifdef SCHED_MULTITHREADED
11713          thread->schedfunc(thread->scheddata);
11714 #endif      
11715       default:
11716          break;
11717       }
11718       time(&thread->checktime);
11719       thread->iostate = IAX_IOSTATE_IDLE;
11720 #ifdef DEBUG_SCHED_MULTITHREAD
11721       thread->curfunc[0]='\0';
11722 #endif      
11723 
11724       /* The network thread added us to the active_thread list when we were given
11725        * frames to process, Now that we are done, we must remove ourselves from
11726        * the active list, and return to the idle list */
11727       AST_LIST_LOCK(&active_list);
11728       AST_LIST_REMOVE(&active_list, thread, list);
11729       AST_LIST_UNLOCK(&active_list);
11730 
11731       /* Make sure another frame didn't sneak in there after we thought we were done. */
11732       handle_deferred_full_frames(thread);
11733    }
11734 
11735    /*!
11736     * \note For some reason, idle threads are exiting without being removed
11737     * from an idle list, which is causing memory corruption.  Forcibly remove
11738     * it from the list, if it's there.
11739     */
11740    AST_LIST_LOCK(&idle_list);
11741    AST_LIST_REMOVE(&idle_list, thread, list);
11742    AST_LIST_UNLOCK(&idle_list);
11743 
11744    AST_LIST_LOCK(&dynamic_list);
11745    AST_LIST_REMOVE(&dynamic_list, thread, list);
11746    AST_LIST_UNLOCK(&dynamic_list);
11747 
11748    if (!thread->stop) {
11749       /* Nobody asked me to stop so nobody is waiting to join me. */
11750       pthread_detach(pthread_self());
11751    }
11752 
11753    /* I am exiting here on my own volition, I need to clean up my own data structures
11754    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
11755    */
11756    pthread_cleanup_pop(1);
11757    return NULL;
11758 }

static void iax2_process_thread_cleanup ( void *  data  )  [static]

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

11605 {
11606    struct iax2_thread *thread = data;
11607    ast_mutex_destroy(&thread->lock);
11608    ast_cond_destroy(&thread->cond);
11609    ast_mutex_destroy(&thread->init_lock);
11610    ast_cond_destroy(&thread->init_cond);
11611    ast_free(thread);
11612    ast_atomic_dec_and_test(&iaxactivethreadcount);
11613 }

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

Definition at line 11821 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, sched, and send_command().

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

11822 {
11823    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
11824       is found for template */
11825    struct iax_ie_data provdata;
11826    struct iax_ie_data ied;
11827    unsigned int sig;
11828    struct sockaddr_in sin;
11829    int callno;
11830    struct create_addr_info cai;
11831 
11832    memset(&cai, 0, sizeof(cai));
11833 
11834    ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11835 
11836    if (iax_provision_build(&provdata, &sig, template, force)) {
11837       ast_debug(1, "No provisioning found for template '%s'\n", template);
11838       return 0;
11839    }
11840 
11841    if (end) {
11842       memcpy(&sin, end, sizeof(sin));
11843       cai.sockfd = sockfd;
11844    } else if (create_addr(dest, NULL, &sin, &cai))
11845       return -1;
11846 
11847    /* Build the rest of the message */
11848    memset(&ied, 0, sizeof(ied));
11849    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11850 
11851    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11852    if (!callno)
11853       return -1;
11854 
11855    if (iaxs[callno]) {
11856       /* Schedule autodestruct in case they don't ever give us anything back */
11857       iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
11858          sched, 15000, auto_hangup, (void *)(long)callno);
11859       ast_set_flag64(iaxs[callno], IAX_PROVISION);
11860       /* Got a call number now, so go ahead and send the provisioning information */
11861       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11862    }
11863    ast_mutex_unlock(&iaxsl[callno]);
11864 
11865    return 1;
11866 }

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

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

05335 {
05336    switch (option) {
05337    case AST_OPTION_SECURE_SIGNALING:
05338    case AST_OPTION_SECURE_MEDIA:
05339    {
05340       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05341       ast_mutex_lock(&iaxsl[callno]);
05342       *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05343       ast_mutex_unlock(&iaxsl[callno]);
05344       return 0;
05345    }
05346    default:
05347       return -1;
05348    }
05349 }

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

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

Referenced by socket_process().

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

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

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

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

02938 {
02939    iax2_lock_owner(callno);
02940    if (iaxs[callno] && iaxs[callno]->owner) {
02941       ast_queue_frame(iaxs[callno]->owner, f);
02942       ast_channel_unlock(iaxs[callno]->owner);
02943    }
02944    return 0;
02945 }

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

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

Referenced by iax2_predestroy().

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

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

Definition at line 5351 of file chan_iax2.c.

References ast_debug, and ast_null_frame.

05352 {
05353    ast_debug(1, "I should never be called!\n");
05354    return &ast_null_frame;
05355 }

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

Definition at line 8506 of file chan_iax2.c.

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

Referenced by set_config().

08507 {
08508    char copy[256];
08509    char *username, *hostname, *secret;
08510    char *porta;
08511    char *stringp=NULL;
08512    
08513    if (!value)
08514       return -1;
08515 
08516    ast_copy_string(copy, value, sizeof(copy));
08517    stringp = copy;
08518    username = strsep(&stringp, "@");
08519    hostname = strsep(&stringp, "@");
08520 
08521    if (!hostname) {
08522       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08523       return -1;
08524    }
08525 
08526    stringp = username;
08527    username = strsep(&stringp, ":");
08528    secret = strsep(&stringp, ":");
08529    stringp = hostname;
08530    hostname = strsep(&stringp, ":");
08531    porta = strsep(&stringp, ":");
08532    
08533    if (porta && !atoi(porta)) {
08534       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08535       return -1;
08536    }
08537 
08538    return iax2_append_register(hostname, username, secret, porta);
08539 }

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

Definition at line 12065 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(), find_callno_locked(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, ast_channel::linkedid, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), chan_iax2_pvt::peer, ast_channel::readformat, and ast_channel::writeformat.

12066 {
12067    int callno;
12068    int res;
12069    format_t fmt, native;
12070    struct sockaddr_in sin;
12071    struct ast_channel *c;
12072    struct parsed_dial_string pds;
12073    struct create_addr_info cai;
12074    char *tmpstr;
12075 
12076    memset(&pds, 0, sizeof(pds));
12077    tmpstr = ast_strdupa(data);
12078    parse_dial_string(tmpstr, &pds);
12079 
12080    if (ast_strlen_zero(pds.peer)) {
12081       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12082       return NULL;
12083    }
12084           
12085    memset(&cai, 0, sizeof(cai));
12086    cai.capability = iax2_capability;
12087 
12088    ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12089    
12090    /* Populate our address from the given */
12091    if (create_addr(pds.peer, NULL, &sin, &cai)) {
12092       *cause = AST_CAUSE_UNREGISTERED;
12093       return NULL;
12094    }
12095 
12096    if (pds.port)
12097       sin.sin_port = htons(atoi(pds.port));
12098 
12099    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12100    if (callno < 1) {
12101       ast_log(LOG_WARNING, "Unable to create call\n");
12102       *cause = AST_CAUSE_CONGESTION;
12103       return NULL;
12104    }
12105 
12106    /* If this is a trunk, update it now */
12107    ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12108    if (ast_test_flag64(&cai, IAX_TRUNK)) {
12109       int new_callno;
12110       if ((new_callno = make_trunk(callno, 1)) != -1)
12111          callno = new_callno;
12112    }
12113    iaxs[callno]->maxtime = cai.maxtime;
12114    if (cai.found)
12115       ast_string_field_set(iaxs[callno], host, pds.peer);
12116 
12117    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL);
12118 
12119    ast_mutex_unlock(&iaxsl[callno]);
12120 
12121    if (c) {
12122       /* Choose a format we can live with */
12123       if (c->nativeformats & format) 
12124          c->nativeformats &= format;
12125       else {
12126          native = c->nativeformats;
12127          fmt = format;
12128          res = ast_translator_best_choice(&fmt, &native);
12129          if (res < 0) {
12130             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12131                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
12132             ast_hangup(c);
12133             return NULL;
12134          }
12135          c->nativeformats = native;
12136       }
12137       c->readformat = ast_best_codec(c->nativeformats);
12138       c->writeformat = c->readformat;
12139    }
12140 
12141    return c;
12142 }

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

Definition at line 1496 of file chan_iax2.c.

References ast_sched_thread_add().

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

01498 {
01499    return ast_sched_thread_add(st, when, callback, data);
01500 }

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

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

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

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

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

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

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

Definition at line 4285 of file chan_iax2.c.

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

04286 {
04287    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04288 }

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

Definition at line 4280 of file chan_iax2.c.

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

04281 {
04282    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1);
04283 }

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

Definition at line 4273 of file chan_iax2.c.

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

04274 {
04275    
04276    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04277       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04278 }

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

Definition at line 5262 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, errno, IAX_FORCE_ENCRYPT, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().

05263 {
05264    struct ast_option_header *h;
05265    int res;
05266 
05267    switch (option) {
05268    case AST_OPTION_TXGAIN:
05269    case AST_OPTION_RXGAIN:
05270       /* these two cannot be sent, because they require a result */
05271       errno = ENOSYS;
05272       return -1;
05273    case AST_OPTION_OPRMODE:
05274       errno = EINVAL;
05275       return -1;
05276    case AST_OPTION_SECURE_SIGNALING:
05277    case AST_OPTION_SECURE_MEDIA:
05278    {
05279       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05280       ast_mutex_lock(&iaxsl[callno]);
05281       if ((*(int *) data)) {
05282          ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05283       } else {
05284          ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05285       }
05286       ast_mutex_unlock(&iaxsl[callno]);
05287       return 0;
05288    }
05289    /* These options are sent to the other side across the network where
05290     * they will be passed to whatever channel is bridged there. Don't
05291     * do anything silly like pass an option that transmits pointers to
05292     * memory on this machine to a remote machine to use */
05293    case AST_OPTION_TONE_VERIFY:
05294    case AST_OPTION_TDD:
05295    case AST_OPTION_RELAXDTMF:
05296    case AST_OPTION_AUDIO_MODE:
05297    case AST_OPTION_DIGIT_DETECT:
05298    case AST_OPTION_FAX_DETECT:
05299    {
05300       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05301       struct chan_iax2_pvt *pvt;
05302 
05303       ast_mutex_lock(&iaxsl[callno]);
05304       pvt = iaxs[callno];
05305 
05306       if (wait_for_peercallno(pvt)) {
05307          ast_mutex_unlock(&iaxsl[callno]);
05308          return -1;
05309       }
05310 
05311       ast_mutex_unlock(&iaxsl[callno]);
05312 
05313       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05314          return -1;
05315       }
05316 
05317       h->flag = AST_OPTION_FLAG_REQUEST;
05318       h->option = htons(option);
05319       memcpy(h->data, data, datalen);
05320       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05321                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
05322                  datalen + sizeof(*h), -1);
05323       ast_free(h);
05324       return res;
05325    }
05326    default:
05327       return -1;
05328    }
05329 
05330    /* Just in case someone does a break instead of a return */
05331    return -1;
05332 }

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

Definition at line 5390 of file chan_iax2.c.

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

05391 {
05392    int res;
05393    struct iax_ie_data ied0;
05394    struct iax_ie_data ied1;
05395    unsigned int transferid = (unsigned int)ast_random();
05396 
05397    if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05398       ast_debug(1, "transfers are not supported for encrypted calls at this time");
05399       ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05400       ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05401       return 0;
05402    }
05403 
05404    memset(&ied0, 0, sizeof(ied0));
05405    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05406    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05407    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05408 
05409    memset(&ied1, 0, sizeof(ied1));
05410    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05411    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05412    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05413    
05414    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05415    if (res)
05416       return -1;
05417    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05418    if (res)
05419       return -1;
05420    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05421    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05422    return 0;
05423 }

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

Definition at line 5649 of file chan_iax2.c.

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

05650 {
05651    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05652    struct iax_ie_data ied = { "", };
05653    char tmp[256], *context;
05654    enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05655    ast_copy_string(tmp, dest, sizeof(tmp));
05656    context = strchr(tmp, '@');
05657    if (context) {
05658       *context = '\0';
05659       context++;
05660    }
05661    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05662    if (context)
05663       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05664    ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05665    ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05666    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05667 }

static int iax2_transmit ( struct iax_frame fr  )  [static]

Definition at line 4256 of file chan_iax2.c.

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

Referenced by iax2_send().

04257 {
04258    fr->sentyet = 0;
04259 
04260    return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04261 }

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

Definition at line 9123 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

09124 {
09125    /* Drop when trunk is about 5 seconds idle */
09126    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
09127       return 1;
09128    return 0;
09129 }

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

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

Referenced by iax2_send().

06072 {
06073    struct ast_frame *f;
06074    struct iax2_trunk_peer *tpeer;
06075    void *tmp, *ptr;
06076    struct timeval now;
06077    struct ast_iax2_meta_trunk_entry *met;
06078    struct ast_iax2_meta_trunk_mini *mtm;
06079 
06080    f = &fr->af;
06081    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06082    if (tpeer) {
06083       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06084          /* Need to reallocate space */
06085          if (tpeer->trunkdataalloc < trunkmaxsize) {
06086             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06087                ast_mutex_unlock(&tpeer->lock);
06088                return -1;
06089             }
06090             
06091             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06092             tpeer->trunkdata = tmp;
06093             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);
06094          } else {
06095             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));
06096             ast_mutex_unlock(&tpeer->lock);
06097             return -1;
06098          }
06099       }
06100 
06101       /* Append to meta frame */
06102       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06103       if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06104          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06105          mtm->len = htons(f->datalen);
06106          mtm->mini.callno = htons(pvt->callno);
06107          mtm->mini.ts = htons(0xffff & fr->ts);
06108          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06109          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06110       } else {
06111          met = (struct ast_iax2_meta_trunk_entry *)ptr;
06112          /* Store call number and length in meta header */
06113          met->callno = htons(pvt->callno);
06114          met->len = htons(f->datalen);
06115          /* Advance pointers/decrease length past trunk entry header */
06116          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06117          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06118       }
06119       /* Copy actual trunk data */
06120       memcpy(ptr, f->data.ptr, f->datalen);
06121       tpeer->trunkdatalen += f->datalen;
06122 
06123       tpeer->calls++;
06124 
06125       /* track the largest mtu we actually have sent */
06126       if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 
06127          trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 
06128 
06129       /* if we have enough for a full MTU, ship it now without waiting */
06130       if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06131          now = ast_tvnow();
06132          send_trunk(tpeer, &now); 
06133          trunk_untimed ++; 
06134       }
06135 
06136       ast_mutex_unlock(&tpeer->lock);
06137    }
06138    return 0;
06139 }

static int iax2_vnak ( int  callno  )  [static]

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

09045 {
09046    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09047 }

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

Definition at line 7413 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, f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, PTR_TO_CALLNO, state, and ast_channel::tech_pvt.

07414 {
07415    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07416    int res = -1;
07417    ast_mutex_lock(&iaxsl[callno]);
07418    if (iaxs[callno]) {
07419    /* If there's an outstanding error, return failure now */
07420       if (!iaxs[callno]->error) {
07421          if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07422             res = 0;
07423             /* Don't waste bandwidth sending null frames */
07424          else if (f->frametype == AST_FRAME_NULL)
07425             res = 0;
07426          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07427             res = 0;
07428          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07429             res = 0;
07430          else
07431          /* Simple, just queue for transmission */
07432             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07433       } else {
07434          ast_debug(1, "Write error: %s\n", strerror(errno));
07435       }
07436    }
07437    /* If it's already gone, just return */
07438    ast_mutex_unlock(&iaxsl[callno]);
07439    return res;
07440 }

static int iax_check_version ( char *  dev  )  [static]

Definition at line 3142 of file chan_iax2.c.

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

Referenced by update_registry().

03143 {
03144    int res = 0;
03145    struct iax_firmware *cur = NULL;
03146 
03147    if (ast_strlen_zero(dev))
03148       return 0;
03149 
03150    AST_LIST_LOCK(&firmwares);
03151    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03152       if (!strcmp(dev, (char *)cur->fwh->devname)) {
03153          res = ntohs(cur->fwh->version);
03154          break;
03155       }
03156    }
03157    AST_LIST_UNLOCK(&firmwares);
03158 
03159    return res;
03160 }

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

Definition at line 1116 of file chan_iax2.c.

References ast_verbose.

Referenced by load_module().

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

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

Definition at line 1122 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

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

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

Definition at line 3162 of file chan_iax2.c.

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

Referenced by socket_process().

03163 {
03164    int res = -1;
03165    unsigned int bs = desc & 0xff;
03166    unsigned int start = (desc >> 8) & 0xffffff;
03167    unsigned int bytes;
03168    struct iax_firmware *cur;
03169 
03170    if (ast_strlen_zero((char *)dev) || !bs)
03171       return -1;
03172 
03173    start *= bs;
03174    
03175    AST_LIST_LOCK(&firmwares);
03176    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03177       if (strcmp((char *)dev, (char *)cur->fwh->devname))
03178          continue;
03179       iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03180       if (start < ntohl(cur->fwh->datalen)) {
03181          bytes = ntohl(cur->fwh->datalen) - start;
03182          if (bytes > bs)
03183             bytes = bs;
03184          iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03185       } else {
03186          bytes = 0;
03187          iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03188       }
03189       if (bytes == bs)
03190          res = 0;
03191       else
03192          res = 1;
03193       break;
03194    }
03195    AST_LIST_UNLOCK(&firmwares);
03196 
03197    return res;
03198 }

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

References debugaddr, f, and iax_showframe().

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

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

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

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

Referenced by socket_process().

09295 {
09296    struct iax_dual *d;
09297    struct ast_channel *chan1m, *chan2m;/* Chan2m: The transferer, chan1m: The transferee */
09298    pthread_t th;
09299 
09300    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09301    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09302    d = ast_calloc(1, sizeof(*d));
09303    if (!chan1m || !chan2m || !d) {
09304       if (chan1m) {
09305          ast_hangup(chan1m);
09306       }
09307       if (chan2m) {
09308          ast_hangup(chan2m);
09309       }
09310       ast_free(d);
09311       return -1;
09312    }
09313    d->park_exten = ast_strdup(park_exten);
09314    d->park_context = ast_strdup(park_context);
09315    if (!d->park_exten || !d->park_context) {
09316       ast_hangup(chan1m);
09317       ast_hangup(chan2m);
09318       ast_free(d->park_exten);
09319       ast_free(d->park_context);
09320       ast_free(d);
09321       return -1;
09322    }
09323 
09324    /* Make formats okay */
09325    chan1m->readformat = chan1->readformat;
09326    chan1m->writeformat = chan1->writeformat;
09327 
09328    /* Prepare for taking over the channel */
09329    if (ast_channel_masquerade(chan1m, chan1)) {
09330       ast_hangup(chan1m);
09331       ast_hangup(chan2m);
09332       ast_free(d->park_exten);
09333       ast_free(d->park_context);
09334       ast_free(d);
09335       return -1;
09336    }
09337 
09338    /* Setup the extensions and such */
09339    ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09340    ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09341    chan1m->priority = chan1->priority;
09342 
09343    ast_do_masquerade(chan1m);
09344 
09345    /* We make a clone of the peer channel too, so we can play
09346       back the announcement */
09347 
09348    /* Make formats okay */
09349    chan2m->readformat = chan2->readformat;
09350    chan2m->writeformat = chan2->writeformat;
09351    ast_string_field_set(chan2m, parkinglot, chan2->parkinglot);
09352 
09353    /* Prepare for taking over the channel */
09354    if (ast_channel_masquerade(chan2m, chan2)) {
09355       ast_hangup(chan1m);
09356       ast_hangup(chan2m);
09357       ast_free(d->park_exten);
09358       ast_free(d->park_context);
09359       ast_free(d);
09360       return -1;
09361    }
09362 
09363    /* Setup the extensions and such */
09364    ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09365    ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09366    chan2m->priority = chan2->priority;
09367 
09368    ast_do_masquerade(chan2m);
09369 
09370    d->chan1 = chan1m;   /* Transferee */
09371    d->chan2 = chan2m;   /* Transferer */
09372    if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) {
09373       /* Could not start thread */
09374       ast_hangup(chan1m);
09375       ast_hangup(chan2m);
09376       ast_free(d->park_exten);
09377       ast_free(d->park_context);
09378       ast_free(d);
09379       return -1;
09380    }
09381    return 0;
09382 }

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

Definition at line 9267 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, ast_channel::name, iax_dual::park_context, and iax_dual::park_exten.

Referenced by iax_park().

09268 {
09269    struct iax_dual *d;
09270    int res;
09271    int ext = 0;
09272 
09273    d = stuff;
09274 
09275    ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n",
09276       d->chan2->name, d->chan1->name);
09277 
09278    res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext);
09279    if (res) {
09280       /* Parking failed. */
09281       ast_hangup(d->chan1);
09282    } else {
09283       ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09284    }
09285    ast_hangup(d->chan2);
09286 
09287    ast_free(d->park_exten);
09288    ast_free(d->park_context);
09289    ast_free(d);
09290    return NULL;
09291 }

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

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

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

static void insert_idle_thread ( struct iax2_thread thread  )  [static]

Definition at line 1378 of file chan_iax2.c.

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

Referenced by iax2_process_thread().

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

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

Definition at line 1151 of file chan_iax2.c.

References args, and ast_verbose.

Referenced by handle_cli_iax2_set_debug_jb().

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

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

Definition at line 1127 of file chan_iax2.c.

References args, ast_log(), and LOG_ERROR.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

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

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

Definition at line 1139 of file chan_iax2.c.

References args, ast_log(), and LOG_WARNING.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

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

static int load_module ( void   )  [static]

Load IAX2 module, load configuraiton ---.

Definition at line 14652 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, iax2_registry::entry, 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, 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(), netsock, network_change_event_subscribe(), outsock, papp, peer_set_sock_cb(), peers, reload_firmware(), RQ_CHAR, RQ_UINTEGER2, sched, SENTINEL, set_config(), start_network_thread(), and timer.

14653 {
14654    static const char config[] = "iax.conf";
14655    int x = 0;
14656    struct iax2_registry *reg = NULL;
14657 
14658    if (load_objects()) {
14659       return AST_MODULE_LOAD_FAILURE;
14660    }
14661 
14662    memset(iaxs, 0, sizeof(iaxs));
14663 
14664    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14665       ast_mutex_init(&iaxsl[x]);
14666    }
14667 
14668    if (!(sched = ast_sched_thread_create())) {
14669       ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14670       return AST_MODULE_LOAD_FAILURE;
14671    }
14672 
14673    if (!(io = io_context_create())) {
14674       ast_log(LOG_ERROR, "Failed to create I/O context\n");
14675       sched = ast_sched_thread_destroy(sched);
14676       return AST_MODULE_LOAD_FAILURE;
14677    }
14678 
14679    if (!(netsock = ast_netsock_list_alloc())) {
14680       ast_log(LOG_ERROR, "Failed to create netsock list\n");
14681       io_context_destroy(io);
14682       sched = ast_sched_thread_destroy(sched);
14683       return AST_MODULE_LOAD_FAILURE;
14684    }
14685    ast_netsock_init(netsock);
14686    
14687    outsock = ast_netsock_list_alloc();
14688    if (!outsock) {
14689       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14690       io_context_destroy(io);
14691       sched = ast_sched_thread_destroy(sched);
14692       return AST_MODULE_LOAD_FAILURE;
14693    }
14694    ast_netsock_init(outsock);
14695 
14696    randomcalltokendata = ast_random();
14697 
14698    iax_set_output(iax_debug_output);
14699    iax_set_error(iax_error_output);
14700    jb_setoutput(jb_error_output, jb_warning_output, NULL);
14701    
14702    if ((timer = ast_timer_open())) {
14703       ast_timer_set_rate(timer, trunkfreq);
14704    }
14705 
14706    if (set_config(config, 0) == -1) {
14707       if (timer) {
14708          ast_timer_close(timer);
14709       }
14710       return AST_MODULE_LOAD_DECLINE;
14711    }
14712 
14713 #ifdef TEST_FRAMEWORK
14714    AST_TEST_REGISTER(test_iax2_peers_get);
14715    AST_TEST_REGISTER(test_iax2_users_get);
14716 #endif
14717 
14718    /* Register AstData providers */
14719    ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
14720    ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14721 
14722    ast_register_application_xml(papp, iax2_prov_app);
14723 
14724    ast_custom_function_register(&iaxpeer_function);
14725    ast_custom_function_register(&iaxvar_function);
14726 
14727    ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
14728    ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
14729    ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
14730    ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
14731 
14732    if (ast_channel_register(&iax2_tech)) {
14733       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
14734       __unload_module();
14735       return AST_MODULE_LOAD_FAILURE;
14736    }
14737 
14738    if (ast_register_switch(&iax2_switch)) {
14739       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
14740    }
14741 
14742    if (start_network_thread()) {
14743       ast_log(LOG_ERROR, "Unable to start network thread\n");
14744       __unload_module();
14745       return AST_MODULE_LOAD_FAILURE;
14746    } else {
14747       ast_verb(2, "IAX Ready and Listening\n");
14748    }
14749 
14750    AST_LIST_LOCK(&registrations);
14751    AST_LIST_TRAVERSE(&registrations, reg, entry)
14752       iax2_do_register(reg);
14753    AST_LIST_UNLOCK(&registrations); 
14754    
14755    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
14756    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
14757 
14758 
14759    reload_firmware(0);
14760    iax_provision_reload(0);
14761 
14762    ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
14763 
14764    network_change_event_subscribe();
14765 
14766    return AST_MODULE_LOAD_SUCCESS;
14767 }

static int load_objects ( void   )  [static]

Definition at line 14414 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(), callno_limits, calltoken_ignores, 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(), peercnts, peers, pvt_cmp_cb(), pvt_hash_cb(), TPS_REF_DEFAULT, transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), user_hash_cb(), and users.

Referenced by load_module().

14415 {
14416    peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14417    peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14418 
14419    if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14420       goto container_fail;
14421    } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14422       goto container_fail;
14423    } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14424       goto container_fail;
14425    } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14426       goto container_fail;
14427    } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14428       goto container_fail;
14429    } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14430       goto container_fail;
14431    } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14432       goto container_fail;
14433    } else if (create_callno_pools()) {
14434       goto container_fail;
14435    } else if  (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14436       goto container_fail;
14437    }
14438 
14439    return 0;
14440 
14441 container_fail:
14442    if (peers) {
14443       ao2_ref(peers, -1);
14444    }
14445    if (users) {
14446       ao2_ref(users, -1);
14447    }
14448    if (iax_peercallno_pvts) {
14449       ao2_ref(iax_peercallno_pvts, -1);
14450    }
14451    if (iax_transfercallno_pvts) {
14452       ao2_ref(iax_transfercallno_pvts, -1);
14453    }
14454    if (peercnts) {
14455       ao2_ref(peercnts, -1);
14456    }
14457    if (callno_limits) {
14458       ao2_ref(callno_limits, -1);
14459    }
14460    if (calltoken_ignores) {
14461       ao2_ref(calltoken_ignores, -1);
14462    }
14463    if (callno_pool) {
14464       ao2_ref(callno_pool, -1);
14465    }
14466    if (callno_pool_trunk) {
14467       ao2_ref(callno_pool_trunk, -1);
14468    }
14469    return AST_MODULE_LOAD_FAILURE;
14470 }

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

Definition at line 5425 of file chan_iax2.c.

References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.

Referenced by iax2_bridge().

05426 {
05427    ast_mutex_lock(&iaxsl[callno0]);
05428    while (ast_mutex_trylock(&iaxsl[callno1])) {
05429       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05430    }
05431 }

static void log_jitterstats ( unsigned short  callno  )  [static]

Definition at line 9454 of file chan_iax2.c.

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

Referenced by socket_process().

09455 {
09456    int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09457    jb_info jbinfo;
09458 
09459    ast_mutex_lock(&iaxsl[callno]);
09460    if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09461       if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09462          jb_getinfo(iaxs[callno]->jb, &jbinfo);
09463          localjitter = jbinfo.jitter;
09464          localdelay = jbinfo.current - jbinfo.min;
09465          locallost = jbinfo.frames_lost;
09466          locallosspct = jbinfo.losspct/1000;
09467          localdropped = jbinfo.frames_dropped;
09468          localooo = jbinfo.frames_ooo;
09469          localpackets = jbinfo.frames_in;
09470       }
09471       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",
09472          iaxs[callno]->owner->name,
09473          iaxs[callno]->pingtime,
09474          localjitter,
09475          localdelay,
09476          locallost,
09477          locallosspct,
09478          localdropped,
09479          localooo,
09480          localpackets,
09481          iaxs[callno]->remote_rr.jitter,
09482          iaxs[callno]->remote_rr.delay,
09483          iaxs[callno]->remote_rr.losscnt,
09484          iaxs[callno]->remote_rr.losspct/1000,
09485          iaxs[callno]->remote_rr.dropped,
09486          iaxs[callno]->remote_rr.ooo,
09487          iaxs[callno]->remote_rr.packets);
09488       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",
09489          iaxs[callno]->owner->name,
09490          iaxs[callno]->pingtime,
09491          localjitter,
09492          localdelay,
09493          locallost,
09494          locallosspct,
09495          localdropped,
09496          localooo,
09497          localpackets,
09498          iaxs[callno]->remote_rr.jitter,
09499          iaxs[callno]->remote_rr.delay,
09500          iaxs[callno]->remote_rr.losscnt,
09501          iaxs[callno]->remote_rr.losspct/1000,
09502          iaxs[callno]->remote_rr.dropped,
09503          iaxs[callno]->remote_rr.ooo,
09504          iaxs[callno]->remote_rr.packets);
09505    }
09506    ast_mutex_unlock(&iaxsl[callno]);
09507 }

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

Definition at line 2035 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(), sched, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), update_max_trunk(), and callno_entry::validated.

Referenced by iax2_request(), and socket_process().

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

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

Definition at line 6914 of file chan_iax2.c.

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

Referenced by load_module().

06915 {
06916    ast_cli_netstats(s, -1, 0);
06917    astman_append(s, "\r\n");
06918    return RESULT_SUCCESS;
06919 }

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

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

Referenced by load_module().

06978 {
06979    struct iax2_peer *peer = NULL;
06980    int peer_count = 0;
06981    char nm[20];
06982    char status[20];
06983    const char *id = astman_get_header(m,"ActionID");
06984    char idtext[256] = "";
06985    struct ast_str *encmethods = ast_str_alloca(256);
06986    struct ao2_iterator i;
06987 
06988    if (!ast_strlen_zero(id))
06989       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06990 
06991    astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06992 
06993 
06994    i = ao2_iterator_init(peers, 0);
06995    for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
06996       encmethods_to_str(peer->encmethods, encmethods);
06997       astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06998       if (!ast_strlen_zero(peer->username)) {
06999          astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
07000       } else {
07001          astman_append(s, "ObjectName: %s\r\n", peer->name);
07002       }
07003       astman_append(s, "ChanObjectType: peer\r\n");
07004       astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
07005       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
07006       astman_append(s, "Mask: %s\r\n", nm);
07007       astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
07008       astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
07009       astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
07010       astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
07011       peer_status(peer, status, sizeof(status));
07012       astman_append(s, "Status: %s\r\n\r\n", status);
07013       peer_count++;
07014    }
07015    ao2_iterator_destroy(&i);
07016 
07017    astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07018    return RESULT_SUCCESS;
07019 }

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

callback to display iax peers in manager

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

06954 {
06955    static const char * const a[] = { "iax2", "show", "peers" };
06956    const char *id = astman_get_header(m,"ActionID");
06957    char idtext[256] = "";
06958    int total = 0;
06959 
06960    if (!ast_strlen_zero(id))
06961       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06962 
06963    astman_send_listack(s, m, "Peer status list will follow", "start");
06964         /* List the peers in separate manager events */
06965    __iax2_show_peers(-1, &total, s, 3, a);
06966         /* Send final confirmation */
06967         astman_append(s,
06968         "Event: PeerlistComplete\r\n"
06969         "EventList: Complete\r\n"
06970         "ListItems: %d\r\n"
06971         "%s"
06972         "\r\n", total, idtext);
06973         return 0;
06974 }

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

Definition at line 7085 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::entry, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), total, iax2_registry::us, and iax2_registry::username.

Referenced by load_module().

07086 {
07087    const char *id = astman_get_header(m, "ActionID");
07088    struct iax2_registry *reg = NULL;
07089    char idtext[256] = "";
07090    char host[80] = "";
07091    char perceived[80] = "";
07092    int total = 0;
07093 
07094    if (!ast_strlen_zero(id))
07095       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07096 
07097    astman_send_listack(s, m, "Registrations will follow", "start");
07098 
07099    AST_LIST_LOCK(&registrations);
07100    AST_LIST_TRAVERSE(&registrations, reg, entry) {
07101       snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
07102       
07103       if (reg->us.sin_addr.s_addr) {
07104          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07105       } else {
07106          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07107       }
07108       
07109       astman_append(s,
07110          "Event: RegistryEntry\r\n"
07111          "%s"
07112          "Host: %s\r\n"
07113          "DNSmanager: %s\r\n"
07114          "Username: %s\r\n"
07115          "Perceived: %s\r\n"
07116          "Refresh: %d\r\n"
07117          "State: %s\r\n"
07118          "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 
07119          reg->refresh, regstate2str(reg->regstate));
07120 
07121       total++;
07122    }
07123    AST_LIST_UNLOCK(&registrations);
07124 
07125    astman_append(s,
07126       "Event: RegistrationsComplete\r\n"
07127       "EventList: Complete\r\n"
07128       "ListItems: %d\r\n"
07129       "%s"
07130       "\r\n", total, idtext);
07131    
07132    return 0;
07133 }

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

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

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

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

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

Definition at line 6169 of file chan_iax2.c.

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

Referenced by decode_frame().

06170 {
06171 #if 0
06172    /* Debug with "fake encryption" */
06173    int x;
06174    if (len % 16)
06175       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06176    for (x=0;x<len;x++)
06177       dst[x] = src[x] ^ 0xff;
06178 #else 
06179    unsigned char lastblock[16] = { 0 };
06180    int x;
06181    while(len > 0) {
06182       ast_aes_decrypt(src, dst, dcx);
06183       for (x=0;x<16;x++)
06184          dst[x] ^= lastblock[x];
06185       memcpy(lastblock, src, sizeof(lastblock));
06186       dst += 16;
06187       src += 16;
06188       len -= 16;
06189    }
06190 #endif
06191 }

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

Definition at line 6193 of file chan_iax2.c.

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

Referenced by encrypt_frame().

06194 {
06195 #if 0
06196    /* Debug with "fake encryption" */
06197    int x;
06198    if (len % 16)
06199       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06200    for (x=0;x<len;x++)
06201       dst[x] = src[x] ^ 0xff;
06202 #else
06203    unsigned char curblock[16] = { 0 };
06204    int x;
06205    while(len > 0) {
06206       for (x=0;x<16;x++)
06207          curblock[x] ^= src[x];
06208       ast_aes_encrypt(curblock, dst, ecx);
06209       memcpy(curblock, dst, sizeof(curblock)); 
06210       dst += 16;
06211       src += 16;
06212       len -= 16;
06213    }
06214 #endif
06215 }

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

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

07758 {
07759    /* Select exactly one common encryption if there are any */
07760    p->encmethods &= enc;
07761    if (p->encmethods) {
07762       if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */
07763          p->keyrotateid = -2;
07764       }
07765       if (p->encmethods & IAX_ENCRYPT_AES128)
07766          p->encmethods = IAX_ENCRYPT_AES128;
07767       else
07768          p->encmethods = 0;
07769    }
07770 }

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

Definition at line 1275 of file chan_iax2.c.

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

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

Definition at line 1310 of file chan_iax2.c.

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

Referenced by network_change_event_subscribe().

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

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

Definition at line 1297 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_registry::entry, and iax2_do_register().

Referenced by network_change_event_cb().

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

static void network_change_event_subscribe ( void   )  [static]

Definition at line 1282 of file chan_iax2.c.

References AST_EVENT_IE_END, AST_EVENT_NETWORK_CHANGE, ast_event_subscribe(), network_change_event_cb(), and network_change_event_subscription.

Referenced by load_module(), and set_config().

static void network_change_event_unsubscribe ( void   )  [static]

Definition at line 1290 of file chan_iax2.c.

References ast_event_unsubscribe(), and network_change_event_subscription.

Referenced by __unload_module(), set_config(), and unload_module().

01291 {
01292    if (network_change_event_subscription) {
01293       network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription);
01294    }
01295 }

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

Definition at line 12144 of file chan_iax2.c.

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

Referenced by start_network_thread().

12145 {
12146    if (timer) {
12147       ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12148    }
12149 
12150    for (;;) {
12151       pthread_testcancel();
12152       /* Wake up once a second just in case SIGURG was sent while
12153        * we weren't in poll(), to make sure we don't hang when trying
12154        * to unload. */
12155       ast_io_wait(io, 1000);
12156    }
12157 
12158    return NULL;
12159 }

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

Definition at line 1913 of file chan_iax2.c.

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

Referenced by __find_callno().

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

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

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

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

04948 {
04949    if (ast_strlen_zero(data))
04950       return;
04951 
04952    pds->peer = strsep(&data, "/");
04953    pds->exten = strsep(&data, "/");
04954    pds->options = data;
04955 
04956    if (pds->exten) {
04957       data = pds->exten;
04958       pds->exten = strsep(&data, "@");
04959       pds->context = data;
04960    }
04961 
04962    if (strchr(pds->peer, '@')) {
04963       data = pds->peer;
04964       pds->username = strsep(&data, "@");
04965       pds->peer = data;
04966    }
04967 
04968    if (pds->username) {
04969       data = pds->username;
04970       pds->username = strsep(&data, ":");
04971       pds->password = data;
04972    }
04973 
04974    data = pds->peer;
04975    pds->peer = strsep(&data, ":");
04976    pds->port = data;
04977 
04978    /* check for a key name wrapped in [] in the secret position, if found,
04979       move it to the key field instead
04980    */
04981    if (pds->password && (pds->password[0] == '[')) {
04982       pds->key = ast_strip_quoted(pds->password, "[", "]");
04983       pds->password = NULL;
04984    }
04985 }

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

References CMP_MATCH, CMP_STOP, and iax2_peer::name.

Referenced by load_module(), and load_objects().

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

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

Definition at line 12891 of file chan_iax2.c.

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

12892 {
12893    struct iax2_peer *peer = obj;
12894 
12895    ast_set_flag64(peer, IAX_DELME);
12896 
12897    return 0;
12898 }

static void peer_destructor ( void *  obj  )  [static]

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

12322 {
12323    struct iax2_peer *peer = obj;
12324    int callno = peer->callno;
12325 
12326    ast_free_ha(peer->ha);
12327 
12328    if (callno > 0) {
12329       ast_mutex_lock(&iaxsl[callno]);
12330       iax2_destroy(callno);
12331       ast_mutex_unlock(&iaxsl[callno]);
12332    }
12333 
12334    register_peer_exten(peer, 0);
12335 
12336    if (peer->dnsmgr)
12337       ast_dnsmgr_release(peer->dnsmgr);
12338 
12339    if (peer->mwi_event_sub)
12340       ast_event_unsubscribe(peer->mwi_event_sub);
12341 
12342    ast_string_field_free_memory(peer);
12343 }

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

References ast_str_hash(), and iax2_peer::name.

Referenced by load_module(), and load_objects().

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

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

Definition at line 1701 of file chan_iax2.c.

References ao2_ref.

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

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

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

Definition at line 14368 of file chan_iax2.c.

References iax2_peer::sockfd.

Referenced by load_module().

14369 {
14370    struct iax2_peer *peer = obj;
14371 
14372    if (peer->sockfd < 0)
14373       peer->sockfd = defaultsockfd;
14374 
14375    return 0;
14376 }

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

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

Referenced by build_peer().

12247 {
12248    struct sockaddr_in sin;
12249    struct ast_sockaddr sin_tmp;
12250    int nonlocal = 1;
12251    int port = IAX_DEFAULT_PORTNO;
12252    int sockfd = defaultsockfd;
12253    char *tmp;
12254    char *addr;
12255    char *portstr;
12256 
12257    if (!(tmp = ast_strdupa(srcaddr)))
12258       return -1;
12259 
12260    addr = strsep(&tmp, ":");
12261    portstr = tmp;
12262 
12263    if (portstr) {
12264       port = atoi(portstr);
12265       if (port < 1)
12266          port = IAX_DEFAULT_PORTNO;
12267    }
12268 
12269    sin_tmp.ss.ss_family = AF_INET;
12270    if (!ast_get_ip(&sin_tmp, addr)) {
12271       struct ast_netsock *sock;
12272       int res;
12273 
12274       ast_sockaddr_to_sin(&sin_tmp, &sin);
12275       sin.sin_port = 0;
12276       sin.sin_family = AF_INET;
12277       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12278       if (res == 0) {
12279          /* ip address valid. */
12280          sin.sin_port = htons(port);
12281          if (!(sock = ast_netsock_find(netsock, &sin)))
12282             sock = ast_netsock_find(outsock, &sin);
12283          if (sock) {
12284             sockfd = ast_netsock_sockfd(sock);
12285             nonlocal = 0;
12286          } else {
12287             unsigned int orig_saddr = sin.sin_addr.s_addr;
12288             /* INADDR_ANY matches anyway! */
12289             sin.sin_addr.s_addr = INADDR_ANY;
12290             if (ast_netsock_find(netsock, &sin)) {
12291                sin.sin_addr.s_addr = orig_saddr;
12292                sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12293                if (sock) {
12294                   sockfd = ast_netsock_sockfd(sock);
12295                   ast_netsock_unref(sock);
12296                   nonlocal = 0;
12297                } else {
12298                   nonlocal = 2;
12299                }
12300             }
12301          }
12302       }
12303    }
12304       
12305    peer->sockfd = sockfd;
12306 
12307    if (nonlocal == 1) {
12308       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12309          srcaddr, peer->name);
12310       return -1;
12311         } else if (nonlocal == 2) {
12312       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12313          srcaddr, peer->name);
12314          return -1;
12315    } else {
12316       ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12317       return 0;
12318    }
12319 }

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

peer_status: Report Peer status in character string

Definition at line 3703 of file chan_iax2.c.

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

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

03704 {
03705    int res = 0;
03706    if (peer->maxms) {
03707       if (peer->lastms < 0) {
03708          ast_copy_string(status, "UNREACHABLE", statuslen);
03709       } else if (peer->lastms > peer->maxms) {
03710          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03711          res = 1;
03712       } else if (peer->lastms) {
03713          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03714          res = 1;
03715       } else {
03716          ast_copy_string(status, "UNKNOWN", statuslen);
03717       }
03718    } else { 
03719       ast_copy_string(status, "Unmonitored", statuslen);
03720       res = -1;
03721    }
03722    return res;
03723 }

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

Definition at line 1707 of file chan_iax2.c.

References ao2_ref.

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

01708 {
01709    ao2_ref(peer, -1);
01710    return NULL;
01711 }

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

Definition at line 2332 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

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

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

Definition at line 2162 of file chan_iax2.c.

References peercnt::addr, CMP_MATCH, and CMP_STOP.

Referenced by load_objects().

02163 {
02164    struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02165    return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02166 }

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

Definition at line 2156 of file chan_iax2.c.

References peercnt::addr.

Referenced by load_objects().

02157 {
02158    const struct peercnt *peercnt = obj;
02159    return abs((int) peercnt->addr);
02160 }

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

Definition at line 2299 of file chan_iax2.c.

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

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

02300 {
02301    /* this function turns off and on custom callno limits set by peer registration */
02302    struct peercnt *peercnt;
02303    struct peercnt tmp = {
02304       .addr = 0,
02305    };
02306    struct sockaddr_in sin;
02307 
02308    ast_sockaddr_to_sin(sockaddr, &sin);
02309 
02310    tmp.addr = sin.sin_addr.s_addr;
02311 
02312    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02313       peercnt->reg = reg;
02314       if (limit) {
02315          peercnt->limit = limit;
02316       } else {
02317          set_peercnt_limit(peercnt);
02318       }
02319       ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg);
02320       ao2_ref(peercnt, -1); /* decrement ref from find */
02321    }
02322 }

static void peercnt_remove ( struct peercnt peercnt  )  [static]

Definition at line 2384 of file chan_iax2.c.

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

Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().

02385 {
02386    struct sockaddr_in sin = {
02387       .sin_addr.s_addr = peercnt->addr,
02388    };
02389 
02390    if (peercnt) {
02391       /* Container locked here since peercnt may be unlinked from list.  If left unlocked,
02392        * peercnt_add could try and grab this entry from the table and modify it at the
02393        * "same time" this thread attemps to unlink it.*/
02394       ao2_lock(peercnts);
02395       peercnt->cur--;
02396       ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02397       /* if this was the last connection from the peer remove it from table */
02398       if (peercnt->cur == 0) {
02399          ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */
02400       }
02401       ao2_unlock(peercnts);
02402    }
02403 }

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

Definition at line 2423 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

02424 {
02425    struct peercnt *peercnt;
02426    struct peercnt tmp = {
02427       .addr = sin->sin_addr.s_addr,
02428    };
02429 
02430    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02431       peercnt_remove(peercnt);
02432       ao2_ref(peercnt, -1); /* decrement ref from find */
02433    }
02434    return 0;
02435 }

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

Definition at line 2409 of file chan_iax2.c.

References ao2_ref, and peercnt_remove().

Referenced by sched_delay_remove().

02410 {
02411    struct peercnt *peercnt = (struct peercnt *) obj;
02412 
02413    peercnt_remove(peercnt);
02414    ao2_ref(peercnt, -1); /* decrement ref from scheduler */
02415 
02416    return 0;
02417 }

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

Definition at line 14502 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(), peers, and status.

14504 {
14505    struct ast_data *data_peer;
14506    struct iax2_peer *peer;
14507    struct ao2_iterator i;
14508    char status[20];
14509    struct ast_str *encmethods = ast_str_alloca(256);
14510 
14511    i = ao2_iterator_init(peers, 0);
14512    while ((peer = ao2_iterator_next(&i))) {
14513       data_peer = ast_data_add_node(data_root, "peer");
14514       if (!data_peer) {
14515          peer_unref(peer);
14516          continue;
14517       }
14518 
14519       ast_data_add_structure(iax2_peer, data_peer, peer);
14520 
14521       ast_data_add_codecs(data_peer, "codecs", peer->capability);
14522 
14523       peer_status(peer, status, sizeof(status));
14524       ast_data_add_str(data_peer, "status", status);
14525 
14526       ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14527 
14528       ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14529 
14530       ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14531 
14532       ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14533 
14534       ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14535 
14536       encmethods_to_str(peer->encmethods, encmethods);
14537       ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14538 
14539       peer_unref(peer);
14540 
14541       if (!ast_data_search_match(search, data_peer)) {
14542          ast_data_remove_node(data_root, data_peer);
14543       }
14544    }
14545    ao2_iterator_destroy(&i);
14546 
14547    return 0;
14548 }

static void poke_all_peers ( void   )  [static]

Definition at line 13457 of file chan_iax2.c.

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

Referenced by reload_config().

13458 {
13459    struct ao2_iterator i;
13460    struct iax2_peer *peer;
13461 
13462    i = ao2_iterator_init(peers, 0);
13463    while ((peer = ao2_iterator_next(&i))) {
13464       iax2_poke_peer(peer, 0);
13465       peer_unref(peer);
13466    }
13467    ao2_iterator_destroy(&i);
13468 }

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

Definition at line 2288 of file chan_iax2.c.

References CMP_MATCH, and addr_range::delme.

Referenced by reload_config().

02289 {
02290    struct addr_range *addr_range = obj;
02291 
02292    return addr_range->delme ? CMP_MATCH : 0;
02293 }

static void prune_peers ( void   )  [static]

Definition at line 12954 of file chan_iax2.c.

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

12955 {
12956    struct iax2_peer *peer;
12957    struct ao2_iterator i;
12958 
12959    i = ao2_iterator_init(peers, 0);
12960    while ((peer = ao2_iterator_next(&i))) {
12961       if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
12962          unlink_peer(peer);
12963       }
12964       peer_unref(peer);
12965    }
12966    ao2_iterator_destroy(&i);
12967 }

static void prune_users ( void   )  [static]

Definition at line 12938 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_prune_realtime(), and reload_config().

12939 {
12940    struct iax2_user *user;
12941    struct ao2_iterator i;
12942 
12943    i = ao2_iterator_init(users, 0);
12944    while ((user = ao2_iterator_next(&i))) {
12945       if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
12946          ao2_unlink(users, user);
12947       }
12948       user_unref(user);
12949    }
12950    ao2_iterator_destroy(&i);
12951 }

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

Definition at line 14385 of file chan_iax2.c.

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

14386 {
14387    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14388 
14389    /* The frames_received field is used to hold whether we're matching
14390     * against a full frame or not ... */
14391 
14392    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
14393       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14394 }

static void pvt_destructor ( void *  obj  )  [static]

Definition at line 1866 of file chan_iax2.c.

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

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

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

Definition at line 14378 of file chan_iax2.c.

References chan_iax2_pvt::peercallno.

14379 {
14380    const struct chan_iax2_pvt *pvt = obj;
14381 
14382    return pvt->peercallno;
14383 }

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

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

Referenced by __send_command().

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

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

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

07739 {
07740    struct ast_iax2_full_hdr fh;
07741    fh.scallno = htons(src | IAX_FLAG_FULL);
07742    fh.dcallno = htons(dst);
07743    fh.ts = 0;
07744    fh.oseqno = 0;
07745    fh.iseqno = 0;
07746    fh.type = AST_FRAME_IAX;
07747    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07748    iax_outputframe(NULL, &fh, 0, sin, 0);
07749 #if 0
07750    if (option_debug)
07751 #endif   
07752       ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07753          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07754    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07755 }

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

Note:
This function calls reg_source_db -> iax2_poke_peer -> find_callno, so do not call this with a pvt lock held.

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

Definition at line 4306 of file chan_iax2.c.

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

04307 {
04308    struct ast_variable *var = NULL;
04309    struct ast_variable *tmp;
04310    struct iax2_peer *peer=NULL;
04311    time_t regseconds = 0, nowtime;
04312    int dynamic=0;
04313 
04314    if (peername) {
04315       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04316       if (!var && sin)
04317          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04318    } else if (sin) {
04319       char porta[25];
04320       sprintf(porta, "%d", ntohs(sin->sin_port));
04321       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04322       if (var) {
04323          /* We'll need the peer name in order to build the structure! */
04324          for (tmp = var; tmp; tmp = tmp->next) {
04325             if (!strcasecmp(tmp->name, "name"))
04326                peername = tmp->value;
04327          }
04328       }
04329    }
04330    if (!var && peername) { /* Last ditch effort */
04331       var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04332       /*!\note
04333        * If this one loaded something, then we need to ensure that the host
04334        * field matched.  The only reason why we can't have this as a criteria
04335        * is because we only have the IP address and the host field might be
04336        * set as a name (and the reverse PTR might not match).
04337        */
04338       if (var && sin) {
04339          for (tmp = var; tmp; tmp = tmp->next) {
04340             if (!strcasecmp(tmp->name, "host")) {
04341                struct ast_hostent ahp;
04342                struct hostent *hp;
04343                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04344                   /* No match */
04345                   ast_variables_destroy(var);
04346                   var = NULL;
04347                }
04348                break;
04349             }
04350          }
04351       }
04352    }
04353    if (!var)
04354       return NULL;
04355 
04356    peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04357 
04358    if (!peer) {
04359       ast_variables_destroy(var);
04360       return NULL;
04361    }
04362 
04363    for (tmp = var; tmp; tmp = tmp->next) {
04364       /* Make sure it's not a user only... */
04365       if (!strcasecmp(tmp->name, "type")) {
04366          if (strcasecmp(tmp->value, "friend") &&
04367              strcasecmp(tmp->value, "peer")) {
04368             /* Whoops, we weren't supposed to exist! */
04369             peer = peer_unref(peer);
04370             break;
04371          } 
04372       } else if (!strcasecmp(tmp->name, "regseconds")) {
04373          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
04374       } else if (!strcasecmp(tmp->name, "ipaddr")) {
04375          ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE);
04376       } else if (!strcasecmp(tmp->name, "port")) {
04377          ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
04378       } else if (!strcasecmp(tmp->name, "host")) {
04379          if (!strcasecmp(tmp->value, "dynamic"))
04380             dynamic = 1;
04381       }
04382    }
04383 
04384    ast_variables_destroy(var);
04385 
04386    if (!peer)
04387       return NULL;
04388 
04389    if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04390       ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04391       if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
04392          if (peer->expire > -1) {
04393             if (!ast_sched_thread_del(sched, peer->expire)) {
04394                peer->expire = -1;
04395                peer_unref(peer);
04396             }
04397          }
04398          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04399          if (peer->expire == -1)
04400             peer_unref(peer);
04401       }
04402       ao2_link(peers, peer);
04403       if (ast_test_flag64(peer, IAX_DYNAMIC))
04404          reg_source_db(peer);
04405    } else {
04406       ast_set_flag64(peer, IAX_TEMPONLY);
04407    }
04408 
04409    if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04410       time(&nowtime);
04411       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04412          memset(&peer->addr, 0, sizeof(peer->addr));
04413          realtime_update_peer(peer->name, &peer->addr, 0);
04414          ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04415             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04416       }
04417       else {
04418          ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04419             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04420       }
04421    }
04422 
04423    return peer;
04424 }

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

Definition at line 4497 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(), globalflags, IAX_RTSAVE_SYSNAME, and SENTINEL.

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

04498 {
04499    char port[10];
04500    char regseconds[20];
04501    const char *sysname = ast_config_AST_SYSTEM_NAME;
04502    char *syslabel = NULL;
04503 
04504    if (ast_strlen_zero(sysname)) /* No system name, disable this */
04505       sysname = NULL;
04506    else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME))
04507       syslabel = "regserver";
04508 
04509    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04510    snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
04511    ast_update_realtime("iaxpeers", "name", peername, 
04512       "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 
04513       "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */
04514 }

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

Definition at line 4426 of file chan_iax2.c.

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

04427 {
04428    struct ast_variable *var;
04429    struct ast_variable *tmp;
04430    struct iax2_user *user=NULL;
04431 
04432    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04433    if (!var)
04434       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04435    if (!var && sin) {
04436       char porta[6];
04437       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04438       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04439       if (!var)
04440          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04441    }
04442    if (!var) { /* Last ditch effort */
04443       var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04444       /*!\note
04445        * If this one loaded something, then we need to ensure that the host
04446        * field matched.  The only reason why we can't have this as a criteria
04447        * is because we only have the IP address and the host field might be
04448        * set as a name (and the reverse PTR might not match).
04449        */
04450       if (var) {
04451          for (tmp = var; tmp; tmp = tmp->next) {
04452             if (!strcasecmp(tmp->name, "host")) {
04453                struct ast_hostent ahp;
04454                struct hostent *hp;
04455                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04456                   /* No match */
04457                   ast_variables_destroy(var);
04458                   var = NULL;
04459                }
04460                break;
04461             }
04462          }
04463       }
04464    }
04465    if (!var)
04466       return NULL;
04467 
04468    tmp = var;
04469    while(tmp) {
04470       /* Make sure it's not a peer only... */
04471       if (!strcasecmp(tmp->name, "type")) {
04472          if (strcasecmp(tmp->value, "friend") &&
04473              strcasecmp(tmp->value, "user")) {
04474             return NULL;
04475          } 
04476       }
04477       tmp = tmp->next;
04478    }
04479 
04480    user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS));
04481 
04482    ast_variables_destroy(var);
04483 
04484    if (!user)
04485       return NULL;
04486 
04487    if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04488       ast_set_flag64(user, IAX_RTCACHEFRIENDS);
04489       ao2_link(users, user);
04490    } else {
04491       ast_set_flag64(user, IAX_TEMPONLY);
04492    }
04493 
04494    return user;
04495 }

static void reg_source_db ( struct iax2_peer p  )  [static]

Definition at line 8627 of file chan_iax2.c.

References iax2_peer::addr, ast_db_get(), AST_DEVICE_UNKNOWN, 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, iax2_peer::name, PARSE_PORT_REQUIRE, peer_ref(), peer_unref(), register_peer_exten(), and sched.

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

08628 {
08629    char data[80];
08630    char *expiry;
08631 
08632    if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08633       return;
08634    }
08635 
08636    expiry = strrchr(data, ':');
08637    if (!expiry) {
08638       ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08639    }
08640    *expiry++ = '\0';
08641 
08642    if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08643       ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08644       return;
08645    }
08646 
08647    p->expiry = atoi(expiry);
08648 
08649    ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08650       ast_sockaddr_stringify(&p->addr), p->expiry);
08651 
08652    iax2_poke_peer(p, 0);
08653    if (p->expire > -1) {
08654       if (!ast_sched_thread_del(sched, p->expire)) {
08655          p->expire = -1;
08656          peer_unref(p);
08657       }
08658    }
08659 
08660    ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
08661 
08662    p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08663    if (p->expire == -1) {
08664       peer_unref(p);
08665    }
08666 
08667    if (iax2_regfunk) {
08668       iax2_regfunk(p->name, 1);
08669    }
08670 
08671    register_peer_exten(p, 1);
08672 }

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

Definition at line 8542 of file chan_iax2.c.

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

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

08543 {
08544    char multi[256];
08545    char *stringp, *ext;
08546    if (!ast_strlen_zero(regcontext)) {
08547       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08548       stringp = multi;
08549       while((ext = strsep(&stringp, "&"))) {
08550          if (onoff) {
08551             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08552                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08553                        "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08554          } else
08555             ast_context_remove_extension(regcontext, ext, 1, NULL);
08556       }
08557    }
08558 }

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

Verify inbound registration.

Definition at line 7912 of file chan_iax2.c.

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

Referenced by handle_request_register(), and socket_process().

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

static int registry_authrequest ( int  callno  )  [static]

Definition at line 8848 of file chan_iax2.c.

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

Referenced by socket_process().

08849 {
08850    struct iax_ie_data ied;
08851    struct iax2_peer *p;
08852    char challenge[10];
08853    const char *peer_name;
08854    int sentauthmethod;
08855 
08856    peer_name = ast_strdupa(iaxs[callno]->peer);
08857 
08858    /* SLD: third call to find_peer in registration */
08859    ast_mutex_unlock(&iaxsl[callno]);
08860    if ((p = find_peer(peer_name, 1))) {
08861       last_authmethod = p->authmethods;
08862    }
08863 
08864    ast_mutex_lock(&iaxsl[callno]);
08865    if (!iaxs[callno])
08866       goto return_unref;
08867 
08868    memset(&ied, 0, sizeof(ied));
08869    /* The selection of which delayed reject is sent may leak information,
08870     * if it sets a static response.  For example, if a host is known to only
08871     * use MD5 authentication, then an RSA response would indicate that the
08872     * peer does not exist, and vice-versa.
08873     * Therefore, we use whatever the last peer used (which may vary over the
08874     * course of a server, which should leak minimal information). */
08875    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08876    if (!p) {
08877       iaxs[callno]->authmethods = sentauthmethod;
08878    }
08879    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08880    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08881       /* Build the challenge */
08882       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08883       ast_string_field_set(iaxs[callno], challenge, challenge);
08884       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08885    }
08886    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08887 
08888 return_unref:
08889    if (p) {
08890       peer_unref(p);
08891    }
08892 
08893    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08894 }

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

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

Referenced by socket_process().

08897 {
08898    struct iax2_registry *reg;
08899    /* Start pessimistic */
08900    struct iax_ie_data ied;
08901    char peer[256] = "";
08902    char challenge[256] = "";
08903    int res;
08904    int authmethods = 0;
08905    if (ies->authmethods)
08906       authmethods = ies->authmethods;
08907    if (ies->username)
08908       ast_copy_string(peer, ies->username, sizeof(peer));
08909    if (ies->challenge)
08910       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08911    memset(&ied, 0, sizeof(ied));
08912    reg = iaxs[callno]->reg;
08913    if (reg) {
08914       struct sockaddr_in reg_addr;
08915 
08916       ast_sockaddr_to_sin(&reg->addr, &reg_addr);
08917 
08918       if (inaddrcmp(&reg_addr, sin)) {
08919          ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08920          return -1;
08921       }
08922       if (ast_strlen_zero(reg->secret)) {
08923          ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08924          reg->regstate = REG_STATE_NOAUTH;
08925          return -1;
08926       }
08927       iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08928       iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08929       if (reg->secret[0] == '[') {
08930          char tmpkey[256];
08931          ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08932          tmpkey[strlen(tmpkey) - 1] = '\0';
08933          res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08934       } else
08935          res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08936       if (!res) {
08937          reg->regstate = REG_STATE_AUTHSENT;
08938          add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
08939          return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08940       } else
08941          return -1;
08942       ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08943    } else   
08944       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08945    return -1;
08946 }

static char* regstate2str ( int  regstate  )  [static]

Definition at line 7022 of file chan_iax2.c.

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

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

07023 {
07024    switch(regstate) {
07025    case REG_STATE_UNREGISTERED:
07026       return "Unregistered";
07027    case REG_STATE_REGSENT:
07028       return "Request Sent";
07029    case REG_STATE_AUTHSENT:
07030       return "Auth. Sent";
07031    case REG_STATE_REGISTERED:
07032       return "Registered";
07033    case REG_STATE_REJECTED:
07034       return "Rejected";
07035    case REG_STATE_TIMEOUT:
07036       return "Timeout";
07037    case REG_STATE_NOAUTH:
07038       return "No Authentication";
07039    default:
07040       return "Unknown";
07041    }
07042 }

static int reload ( void   )  [static]

Definition at line 13518 of file chan_iax2.c.

References reload_config().

13519 {
13520    return reload_config();
13521 }

static int reload_config ( void   )  [static]

Definition at line 13469 of file chan_iax2.c.

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

13470 {
13471    static const char config[] = "iax.conf";
13472    struct iax2_registry *reg;
13473 
13474    if (set_config(config, 1) > 0) {
13475       prune_peers();
13476       prune_users();
13477       ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13478       ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13479       ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13480       trunk_timed = trunk_untimed = 0; 
13481       trunk_nmaxmtu = trunk_maxmtu = 0;
13482       memset(&debugaddr, '\0', sizeof(debugaddr));
13483 
13484       AST_LIST_LOCK(&registrations);
13485       AST_LIST_TRAVERSE(&registrations, reg, entry)
13486          iax2_do_register(reg);
13487       AST_LIST_UNLOCK(&registrations);
13488 
13489       /* Qualify hosts, too */
13490       poke_all_peers();
13491    }
13492    
13493    reload_firmware(0);
13494    iax_provision_reload(1);
13495    ast_unload_realtime("iaxpeers");
13496 
13497    return 0;
13498 }

static void reload_firmware ( int  unload  )  [static]

Definition at line 3201 of file chan_iax2.c.

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

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

03202 {
03203    struct iax_firmware *cur = NULL;
03204    DIR *fwd;
03205    struct dirent *de;
03206    char dir[256], fn[256];
03207 
03208    AST_LIST_LOCK(&firmwares);
03209 
03210    /* Mark all as dead */
03211    AST_LIST_TRAVERSE(&firmwares, cur, list)
03212       cur->dead = 1;
03213 
03214    /* Now that we have marked them dead... load new ones */
03215    if (!unload) {
03216       snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03217       fwd = opendir(dir);
03218       if (fwd) {
03219          while((de = readdir(fwd))) {
03220             if (de->d_name[0] != '.') {
03221                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03222                if (!try_firmware(fn)) {
03223                   ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03224                }
03225             }
03226          }
03227          closedir(fwd);
03228       } else 
03229          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03230    }
03231 
03232    /* Clean up leftovers */
03233    AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03234       if (!cur->dead)
03235          continue;
03236       AST_LIST_REMOVE_CURRENT(list);
03237       destroy_firmware(cur);
03238    }
03239    AST_LIST_TRAVERSE_SAFE_END;
03240 
03241    AST_LIST_UNLOCK(&firmwares);
03242 }

static void remove_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

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

02124 {
02125    if (!pvt->peercallno) {
02126       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02127       return;
02128    }
02129 
02130    ao2_unlink(iax_peercallno_pvts, pvt);
02131 }

static void remove_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

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

02105 {
02106    if (!pvt->transfercallno) {
02107       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02108       return;
02109    }
02110 
02111    ao2_unlink(iax_transfercallno_pvts, pvt);
02112 }

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

Definition at line 2633 of file chan_iax2.c.

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

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

02634 {
02635    struct callno_entry *callno_entry = (struct callno_entry *) obj;
02636 
02637    /* the callno_pool container is locked here primarily to ensure thread
02638     * safety of the total_nonval_callno_used check and decrement */
02639    ao2_lock(callno_pool);
02640 
02641    if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02642       total_nonval_callno_used--;
02643    } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02644       ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02645    }
02646 
02647    if (callno_entry->callno < TRUNK_CALL_START) {
02648       ao2_link(callno_pool, callno_entry);
02649    } else {
02650       ao2_link(callno_pool_trunk, callno_entry);
02651    }
02652    ao2_ref(callno_entry, -1); /* only container ref remains */
02653 
02654    ao2_unlock(callno_pool);
02655    return 0;
02656 }

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

Definition at line 4804 of file chan_iax2.c.

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

Referenced by handle_call_token().

04805 {
04806    struct iax2_user *user = NULL;
04807    struct iax2_peer *peer = NULL;
04808 
04809    if (ast_strlen_zero(name)) {
04810       return; /* no username given */
04811    }
04812 
04813    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04814       user->calltoken_required = CALLTOKEN_YES;
04815    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04816       peer->calltoken_required = CALLTOKEN_YES;
04817    }
04818 
04819    if (peer) {
04820       peer_unref(peer);
04821    }
04822    if (user) {
04823       user_unref(user);
04824    }
04825 }

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

Definition at line 4722 of file chan_iax2.c.

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

Referenced by socket_process().

04723 {
04724    struct chan_iax2_pvt *pvt = iaxs[callno];
04725    int frametype = f->af.frametype;
04726    int subclass = f->af.subclass.integer;
04727    struct {
04728       struct ast_iax2_full_hdr fh;
04729       struct iax_ie_data ied;
04730    } data = {
04731       .ied.buf = { 0 },
04732       .ied.pos = 0,
04733    };
04734    /* total len - header len gives us the frame's IE len */
04735    int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04736 
04737    if (!pvt) {
04738       return;  /* this should not be possible if called from socket_process() */
04739    }
04740 
04741    /* 
04742     * Check to make sure last frame sent is valid for call token resend
04743     * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 
04744     * 2. Frame should _NOT_ already have a destination callno
04745     * 3. Frame must be a valid iax_frame subclass capable of starting dialog
04746     * 4. Pvt must have a calltoken_ie_len which represents the number of
04747     *    bytes at the end of the frame used for the previous calltoken ie.
04748     * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length
04749     * 6. Total length of f->data must be _LESS_ than size of our data struct
04750     *    because f->data must be able to fit within data. 
04751     */
04752    if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04753       || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04754       (f->datalen > sizeof(data))) {
04755 
04756       return;  /* ignore resend, token was not valid for the dialog */
04757    }
04758 
04759    /* token is valid
04760     * 1. Copy frame data over
04761     * 2. Redo calltoken IE, it will always be the last ie in the frame.
04762     *    NOTE: Having the ie always be last is not protocol specified,
04763     *    it is only an implementation choice.  Since we only expect the ie to
04764     *    be last for frames we have sent, this can no way be affected by
04765     *    another end point.
04766     * 3. Remove frame from queue
04767     * 4. Free old frame
04768     * 5. Clear previous seqnos
04769     * 6. Resend with CALLTOKEN ie.
04770     */
04771 
04772    /* ---1.--- */
04773    memcpy(&data, f->data, f->datalen);
04774    data.ied.pos = ie_data_pos;
04775 
04776    /* ---2.--- */
04777    /* move to the beginning of the calltoken ie so we can write over it */
04778    data.ied.pos -= pvt->calltoken_ie_len;
04779    iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04780 
04781    /* make sure to update token length incase it ever has to be stripped off again */
04782    pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */
04783 
04784    /* ---3.--- */
04785    AST_LIST_REMOVE(&frame_queue[callno], f, list);
04786 
04787    /* ---4.--- */
04788    iax2_frame_free(f);
04789 
04790    /* ---5.--- */
04791    pvt->oseqno = 0;
04792    pvt->rseqno = 0;
04793    pvt->iseqno = 0;
04794    pvt->aseqno = 0;
04795    if (pvt->peercallno) {
04796       remove_by_peercallno(pvt);
04797       pvt->peercallno = 0;
04798    }
04799 
04800    /* ---6.--- */
04801    send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04802 }

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

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

09425 {
09426    int i;
09427    unsigned int length, offset = 0;
09428    char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09429 
09430    for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09431       length = ies->ospblocklength[i];
09432       if (length != 0) {
09433          if (length > IAX_MAX_OSPBLOCK_SIZE) {
09434             /* OSP token block length wrong, clear buffer */
09435             offset = 0;
09436             break;
09437          } else {
09438             memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09439             offset += length;
09440          }
09441       } else {
09442          break;
09443       }
09444    }
09445    *(full_osptoken + offset) = '\0';
09446    if (strlen(full_osptoken) != offset) {
09447       /* OSP token length wrong, clear buffer */
09448       *full_osptoken = '\0';
09449    }
09450 
09451    ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09452 }

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

Definition at line 9413 of file chan_iax2.c.

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

Referenced by socket_process().

09414 {
09415    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09416    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09417    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09418    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09419    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09420    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09421    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09422 }

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

Definition at line 2705 of file chan_iax2.c.

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

Referenced by pvt_destructor().

02706 {
02707    int i;
02708    struct peercnt *peercnt;
02709    struct peercnt tmp = {
02710       .addr = sin->sin_addr.s_addr,
02711    };
02712 
02713    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02714       /* refcount is incremented with ao2_find.  keep that ref for the scheduler */
02715       ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02716       i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02717       if (i == -1) {
02718          ao2_ref(peercnt, -1);
02719       }
02720    }
02721 
02722    iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02723 }

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 4134 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::delivery, ast_frame::frametype, iax2_frame_free(), iax2_lock_owner(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, sched, ast_frame::subclass, iax_frame::ts, unwrap_timestamp(), and update_jbsched().

Referenced by socket_process(), and socket_process_meta().

04135 {
04136    int type, len;
04137    int ret;
04138    int needfree = 0;
04139    struct ast_channel *owner = NULL;
04140    struct ast_channel *bridge = NULL;
04141    
04142    /* Attempt to recover wrapped timestamps */
04143    unwrap_timestamp(fr);
04144 
04145    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
04146    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04147       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04148    else {
04149 #if 0
04150       ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04151 #endif
04152       fr->af.delivery = ast_tv(0,0);
04153    }
04154 
04155    type = JB_TYPE_CONTROL;
04156    len = 0;
04157 
04158    if(fr->af.frametype == AST_FRAME_VOICE) {
04159       type = JB_TYPE_VOICE;
04160       len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000);
04161    } else if(fr->af.frametype == AST_FRAME_CNG) {
04162       type = JB_TYPE_SILENCE;
04163    }
04164 
04165    if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04166       if (tsout)
04167          *tsout = fr->ts;
04168       __do_deliver(fr);
04169       return -1;
04170    }
04171 
04172    iax2_lock_owner(fr->callno);
04173    if (!iaxs[fr->callno]) {
04174       /* The call dissappeared so discard this frame that we could not send. */
04175       iax2_frame_free(fr);
04176       return -1;
04177    }
04178    if ((owner = iaxs[fr->callno]->owner))
04179       bridge = ast_bridged_channel(owner);
04180 
04181    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
04182     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
04183    if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04184       jb_frame frame;
04185 
04186       ast_channel_unlock(owner);
04187 
04188       /* deliver any frames in the jb */
04189       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04190          __do_deliver(frame.data);
04191          /* __do_deliver() can make the call disappear */
04192          if (!iaxs[fr->callno])
04193             return -1;
04194       }
04195 
04196       jb_reset(iaxs[fr->callno]->jb);
04197 
04198       ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04199 
04200       /* deliver this frame now */
04201       if (tsout)
04202          *tsout = fr->ts;
04203       __do_deliver(fr);
04204       return -1;
04205    }
04206    if (owner) {
04207       ast_channel_unlock(owner);
04208    }
04209 
04210    /* insert into jitterbuffer */
04211    /* TODO: Perhaps we could act immediately if it's not droppable and late */
04212    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04213          calc_rxstamp(iaxs[fr->callno],fr->ts));
04214    if (ret == JB_DROP) {
04215       needfree++;
04216    } else if (ret == JB_SCHED) {
04217       update_jbsched(iaxs[fr->callno]);
04218    }
04219    if (tsout)
04220       *tsout = fr->ts;
04221    if (needfree) {
04222       /* Free our iax frame */
04223       iax2_frame_free(fr);
04224       return -1;
04225    }
04226    return 0;
04227 }

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

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

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

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

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

Referenced by handle_call_token(), and socket_process().

04689 {
04690    struct {
04691       struct ast_iax2_full_hdr f;
04692       struct iax_ie_data ied;
04693    } data;
04694    size_t size = sizeof(struct ast_iax2_full_hdr);
04695 
04696    if (ied) {
04697       size += ied->pos;
04698       memcpy(&data.ied, ied->buf, ied->pos);
04699    }
04700 
04701    data.f.scallno = htons(0x8000 | callno);
04702    data.f.dcallno = htons(dcallno);
04703    data.f.ts = htonl(ts);
04704    data.f.iseqno = seqno;
04705    data.f.oseqno = 0;
04706    data.f.type = AST_FRAME_IAX;
04707    data.f.csub = compress_subclass(command);
04708 
04709    return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04710 }

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

Definition at line 7461 of file chan_iax2.c.

References __send_command().

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

07462 {
07463    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07464 }

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

07481 {
07482    int call_num = i->callno;
07483    /* It is assumed that the callno has already been locked */
07484    iax2_predestroy(i->callno);
07485    if (!iaxs[call_num])
07486       return -1;
07487    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07488 }

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

Definition at line 7490 of file chan_iax2.c.

References __send_command().

Referenced by iax2_vnak(), and socket_process().

07491 {
07492    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07493 }

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

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

07467 {
07468    int res;
07469    ast_mutex_lock(&iaxsl[callno]);
07470    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07471    ast_mutex_unlock(&iaxsl[callno]);
07472    return res;
07473 }

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

Definition at line 7495 of file chan_iax2.c.

References __send_command().

Referenced by socket_process(), and try_transfer().

07496 {
07497    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07498 }

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

Definition at line 1591 of file chan_iax2.c.

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

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

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

static int send_packet ( struct iax_frame f  )  [static]

Definition at line 3314 of file chan_iax2.c.

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

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

03315 {
03316    int res;
03317    int callno = f->callno;
03318 
03319    /* Don't send if there was an error, but return error instead */
03320    if (!callno || !iaxs[callno] || iaxs[callno]->error)
03321        return -1;
03322    
03323    /* Called with iaxsl held */
03324    if (iaxdebug)
03325       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));
03326    
03327    if (f->transfer) {
03328       if (iaxdebug)
03329          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03330       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03331    } else {
03332       if (iaxdebug)
03333          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03334       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03335    }
03336    if (res < 0) {
03337       if (iaxdebug)
03338          ast_debug(1, "Received error: %s\n", strerror(errno));
03339       handle_error();
03340    } else
03341       res = 0;
03342 
03343    return res;
03344 }

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

Definition at line 1524 of file chan_iax2.c.

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

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

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

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

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

Referenced by socket_process().

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

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

Definition at line 9080 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, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.

Referenced by iax2_trunk_queue(), and timing_read().

09081 {
09082    int res = 0;
09083    struct iax_frame *fr;
09084    struct ast_iax2_meta_hdr *meta;
09085    struct ast_iax2_meta_trunk_hdr *mth;
09086    int calls = 0;
09087    
09088    /* Point to frame */
09089    fr = (struct iax_frame *)tpeer->trunkdata;
09090    /* Point to meta data */
09091    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09092    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09093    if (tpeer->trunkdatalen) {
09094       /* We're actually sending a frame, so fill the meta trunk header and meta header */
09095       meta->zeros = 0;
09096       meta->metacmd = IAX_META_TRUNK;
09097       if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09098          meta->cmddata = IAX_META_TRUNK_MINI;
09099       else
09100          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09101       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09102       /* And the rest of the ast_iax2 header */
09103       fr->direction = DIRECTION_OUTGRESS;
09104       fr->retrans = -1;
09105       fr->transfer = 0;
09106       /* Any appropriate call will do */
09107       fr->data = fr->afdata;
09108       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09109       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09110       calls = tpeer->calls;
09111 #if 0
09112       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));
09113 #endif      
09114       /* Reset transmit trunk side data */
09115       tpeer->trunkdatalen = 0;
09116       tpeer->calls = 0;
09117    }
09118    if (res < 0)
09119       return res;
09120    return calls;
09121 }

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

Load configuration.

Definition at line 12986 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_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, build_callno_limits(), build_peer(), build_user(), capability, CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), globalflags, iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_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, io, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_TRUNK_MTU, MAX_TRUNKDATA, ast_variable::name, netsock, network_change_event_subscribe(), network_change_event_unsubscribe(), ast_variable::next, outsock, peer_unref(), peers, prefs, qos, reg_source_db(), secret, set_config_destroy(), socket_read(), user, user_unref(), users, and ast_variable::value.

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

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

static void set_config_destroy ( void   )  [static]

Definition at line 12969 of file chan_iax2.c.

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

Referenced by set_config().

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

Definition at line 9849 of file chan_iax2.c.

References ast_channel_unlock, ast_set_hangupsource(), ast_channel::hangupcause, iax2_lock_owner(), iaxs, and chan_iax2_pvt::owner.

Referenced by socket_process().

09850 {
09851    iax2_lock_owner(callno);
09852    if (iaxs[callno] && iaxs[callno]->owner) {
09853       if (causecode) {
09854          iaxs[callno]->owner->hangupcause = causecode;
09855       }
09856       ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0);
09857       ast_channel_unlock(iaxs[callno]->owner);
09858    }
09859 }

static void set_peercnt_limit ( struct peercnt peercnt  )  [static]

Definition at line 2248 of file chan_iax2.c.

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

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

02249 {
02250    uint16_t limit = global_maxcallno;
02251    struct addr_range *addr_range;
02252    struct sockaddr_in sin = {
02253       .sin_addr.s_addr = peercnt->addr,
02254    };
02255 
02256 
02257    if (peercnt->reg && peercnt->limit) {
02258       return; /* this peercnt has a custom limit set by a registration */
02259    }
02260 
02261    if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02262       limit = addr_range->limit;
02263       ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02264       ao2_ref(addr_range, -1);
02265    }
02266 
02267    peercnt->limit = limit;
02268 }

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

Definition at line 2274 of file chan_iax2.c.

References ast_debug, and set_peercnt_limit().

Referenced by reload_config().

02275 {
02276    struct peercnt *peercnt = obj;
02277 
02278    set_peercnt_limit(peercnt);
02279    ast_debug(1, "Reset limits for peercnts table\n");
02280 
02281    return 0;
02282 }

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

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

01049 {
01050    ast_mutex_lock(lock);
01051    ast_cond_signal(cond);
01052    ast_mutex_unlock(lock);
01053 }

static int socket_process ( struct iax2_thread thread  )  [static]

Definition at line 9861 of file chan_iax2.c.

References ast_aes_set_decrypt_key(), ast_async_goto(), ast_best_codec(), ast_bridged_channel(), ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_channel_datastore_add(), ast_channel_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_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(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax_ies::called_number, chan_iax2_pvt::calling_pres, iax_ies::callno, iax2_peer::callno, iax2_dpcache::callno, chan_iax2_pvt::callno, iax_ies::calltoken, iax_ies::calltokendata, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, check_access(), check_provisioning(), cid_name, cid_num, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), connected, construct_rr(), context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, decrypt_frame(), iax_ies::devicetype, dp_lookup(), iax_ies::encmethods, ast_var_t::entries, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, format, frame_queue, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, globalflags, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_allow_new(), iax2_destroy(), iax2_dprequest(), iax2_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, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event, iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, iax_ies::musiconhold, iax2_peer::name, ast_channel::name, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, iax_frame::oseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, iax_ies::provver, iax_ies::provverpres, raw_hangup(), iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rseqno, S_COR, S_OR, save_osptoken(), save_rr(), sched, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), send_signaling(), iax_ies::serviceident, set_hangup_source_and_cause(), iax2_peer::smoothing, socket_process_meta(), spawn_dp_lookup(), stop_stuff(), store_by_peercallno(), thread, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), iax_frame::ts, uncompress_subclass(), update_registry(), iax_ies::username, var, iax_ies::vars, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.

Referenced by handle_deferred_full_frames().

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

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

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

Referenced by socket_process().

09653 {
09654    unsigned char metatype;
09655    struct ast_iax2_meta_trunk_mini *mtm;
09656    struct ast_iax2_meta_trunk_hdr *mth;
09657    struct ast_iax2_meta_trunk_entry *mte;
09658    struct iax2_trunk_peer *tpeer;
09659    unsigned int ts;
09660    void *ptr;
09661    struct timeval rxtrunktime;
09662    struct ast_frame f = { 0, };
09663 
09664    if (packet_len < sizeof(*meta)) {
09665       ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 
09666          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09667       return 1;
09668    }
09669 
09670    if (meta->metacmd != IAX_META_TRUNK)
09671       return 1;
09672 
09673    if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09674       ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09675          (int) (sizeof(*meta) + sizeof(*mth)));
09676       return 1;
09677    }
09678    mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09679    ts = ntohl(mth->ts);
09680    metatype = meta->cmddata;
09681    packet_len -= (sizeof(*meta) + sizeof(*mth));
09682    ptr = mth->data;
09683    tpeer = find_tpeer(sin, sockfd);
09684    if (!tpeer) {
09685       ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 
09686          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09687       return 1;
09688    }
09689    tpeer->trunkact = ast_tvnow();
09690    if (!ts || ast_tvzero(tpeer->rxtrunktime))
09691       tpeer->rxtrunktime = tpeer->trunkact;
09692    rxtrunktime = tpeer->rxtrunktime;
09693    ast_mutex_unlock(&tpeer->lock);
09694    while (packet_len >= sizeof(*mte)) {
09695       /* Process channels */
09696       unsigned short callno, trunked_ts, len;
09697 
09698       if (metatype == IAX_META_TRUNK_MINI) {
09699          mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09700          ptr += sizeof(*mtm);
09701          packet_len -= sizeof(*mtm);
09702          len = ntohs(mtm->len);
09703          callno = ntohs(mtm->mini.callno);
09704          trunked_ts = ntohs(mtm->mini.ts);
09705       } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09706          mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09707          ptr += sizeof(*mte);
09708          packet_len -= sizeof(*mte);
09709          len = ntohs(mte->len);
09710          callno = ntohs(mte->callno);
09711          trunked_ts = 0;
09712       } else {
09713          ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09714          break;
09715       }
09716       /* Stop if we don't have enough data */
09717       if (len > packet_len)
09718          break;
09719       fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09720       if (!fr->callno)
09721          continue;
09722 
09723       /* If it's a valid call, deliver the contents.  If not, we
09724          drop it, since we don't have a scallno to use for an INVAL */
09725       /* Process as a mini frame */
09726       memset(&f, 0, sizeof(f));
09727       f.frametype = AST_FRAME_VOICE;
09728       if (!iaxs[fr->callno]) {
09729          /* drop it */
09730       } else if (iaxs[fr->callno]->voiceformat == 0) {
09731          ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09732          iax2_vnak(fr->callno);
09733       } else {
09734          f.subclass.codec = iaxs[fr->callno]->voiceformat;
09735          f.datalen = len;
09736          if (f.datalen >= 0) {
09737             if (f.datalen)
09738                f.data.ptr = ptr;
09739             else
09740                f.data.ptr = NULL;
09741             if (trunked_ts)
09742                fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09743             else
09744                fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09745             /* Don't pass any packets until we're started */
09746             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09747                struct iax_frame *duped_fr;
09748 
09749                /* Common things */
09750                f.src = "IAX2";
09751                f.mallocd = 0;
09752                f.offset = 0;
09753                if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
09754                   f.samples = ast_codec_get_samples(&f);
09755                else
09756                   f.samples = 0;
09757                fr->outoforder = 0;
09758                iax_frame_wrap(fr, &f);
09759                duped_fr = iaxfrdup2(fr);
09760                if (duped_fr)
09761                   schedule_delivery(duped_fr, 1, 1, &fr->ts);
09762                if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09763                   iaxs[fr->callno]->last = fr->ts;
09764             }
09765          } else {
09766             ast_log(LOG_WARNING, "Datalen < 0?\n");
09767          }
09768       }
09769       ast_mutex_unlock(&iaxsl[fr->callno]);
09770       ptr += len;
09771       packet_len -= len;
09772    }
09773 
09774    return 1;
09775 }

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

Definition at line 9572 of file chan_iax2.c.

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

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

09573 {
09574    struct iax2_thread *thread;
09575    socklen_t len;
09576    time_t t;
09577    static time_t last_errtime = 0;
09578    struct ast_iax2_full_hdr *fh;
09579 
09580    if (!(thread = find_idle_thread())) {
09581       time(&t);
09582       if (t != last_errtime)
09583          ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09584       last_errtime = t;
09585       usleep(1);
09586       return 1;
09587    }
09588 
09589    len = sizeof(thread->iosin);
09590    thread->iofd = fd;
09591    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09592    thread->buf_size = sizeof(thread->readbuf);
09593    thread->buf = thread->readbuf;
09594    if (thread->buf_len < 0) {
09595       if (errno != ECONNREFUSED && errno != EAGAIN)
09596          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09597       handle_error();
09598       thread->iostate = IAX_IOSTATE_IDLE;
09599       signal_condition(&thread->lock, &thread->cond);
09600       return 1;
09601    }
09602    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
09603       thread->iostate = IAX_IOSTATE_IDLE;
09604       signal_condition(&thread->lock, &thread->cond);
09605       return 1;
09606    }
09607    
09608    /* Determine if this frame is a full frame; if so, and any thread is currently
09609       processing a full frame for the same callno from this peer, then drop this
09610       frame (and the peer will retransmit it) */
09611    fh = (struct ast_iax2_full_hdr *) thread->buf;
09612    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09613       struct iax2_thread *cur = NULL;
09614       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09615       
09616       AST_LIST_LOCK(&active_list);
09617       AST_LIST_TRAVERSE(&active_list, cur, list) {
09618          if ((cur->ffinfo.callno == callno) &&
09619              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09620             break;
09621       }
09622       if (cur) {
09623          /* we found another thread processing a full frame for this call,
09624             so queue it up for processing later. */
09625          defer_full_frame(thread, cur);
09626          AST_LIST_UNLOCK(&active_list);
09627          thread->iostate = IAX_IOSTATE_IDLE;
09628          signal_condition(&thread->lock, &thread->cond);
09629          return 1;
09630       } else {
09631          /* this thread is going to process this frame, so mark it */
09632          thread->ffinfo.callno = callno;
09633          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09634          thread->ffinfo.type = fh->type;
09635          thread->ffinfo.csub = fh->csub;
09636          AST_LIST_INSERT_HEAD(&active_list, thread, list);
09637       }
09638       AST_LIST_UNLOCK(&active_list);
09639    }
09640    
09641    /* Mark as ready and send on its way */
09642    thread->iostate = IAX_IOSTATE_READY;
09643 #ifdef DEBUG_SCHED_MULTITHREAD
09644    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09645 #endif
09646    signal_condition(&thread->lock, &thread->cond);
09647 
09648    return 1;
09649 }

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

Definition at line 9242 of file chan_iax2.c.

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

Referenced by socket_process().

09243 {
09244    pthread_t newthread;
09245    struct dpreq_data *dpr;
09246    
09247    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09248       return;
09249 
09250    dpr->callno = callno;
09251    ast_copy_string(dpr->context, context, sizeof(dpr->context));
09252    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09253    if (callerid)
09254       dpr->callerid = ast_strdup(callerid);
09255    if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09256       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09257    }
09258 }

static int start_network_thread ( void   )  [static]

Definition at line 12161 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, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, iax2_thread::list, LOG_WARNING, and thread.

Referenced by load_module().

12162 {
12163    struct iax2_thread *thread;
12164    int threadcount = 0;
12165    int x;
12166    for (x = 0; x < iaxthreadcount; x++) {
12167       thread = ast_calloc(1, sizeof(*thread));
12168       if (thread) {
12169          thread->type = IAX_THREAD_TYPE_POOL;
12170          thread->threadnum = ++threadcount;
12171          ast_mutex_init(&thread->lock);
12172          ast_cond_init(&thread->cond, NULL);
12173          ast_mutex_init(&thread->init_lock);
12174          ast_cond_init(&thread->init_cond, NULL);
12175          if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12176             ast_log(LOG_WARNING, "Failed to create new thread!\n");
12177             ast_mutex_destroy(&thread->lock);
12178             ast_cond_destroy(&thread->cond);
12179             ast_mutex_destroy(&thread->init_lock);
12180             ast_cond_destroy(&thread->init_cond);
12181             ast_free(thread);
12182             thread = NULL;
12183             continue;
12184          }
12185          AST_LIST_LOCK(&idle_list);
12186          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12187          AST_LIST_UNLOCK(&idle_list);
12188       }
12189    }
12190    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
12191    ast_verb(2, "%d helper threads started\n", threadcount);
12192    return 0;
12193 }

static void stop_stuff ( int  callno  )  [static]

Definition at line 8948 of file chan_iax2.c.

References iax2_destroy_helper(), and iaxs.

Referenced by socket_process().

08949 {
08950    iax2_destroy_helper(iaxs[callno]);
08951 }

static void store_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

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

02114 {
02115    if (!pvt->peercallno) {
02116       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02117       return;
02118    }
02119 
02120    ao2_link(iax_peercallno_pvts, pvt);
02121 }

static void store_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2094 of file chan_iax2.c.

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

Referenced by try_transfer().

02095 {
02096    if (!pvt->transfercallno) {
02097       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02098       return;
02099    }
02100 
02101    ao2_link(iax_transfercallno_pvts, pvt);
02102 }

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

Definition at line 9131 of file chan_iax2.c.

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

Referenced by network_thread().

09132 {
09133    int res, processed = 0, totalcalls = 0;
09134    struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09135    struct timeval now = ast_tvnow();
09136 
09137    if (iaxtrunkdebug)
09138       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09139 
09140    if (timer) { 
09141       ast_timer_ack(timer, 1);
09142    }
09143 
09144    /* For each peer that supports trunking... */
09145    AST_LIST_LOCK(&tpeers);
09146    AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09147       processed++;
09148       res = 0;
09149       ast_mutex_lock(&tpeer->lock);
09150       /* We can drop a single tpeer per pass.  That makes all this logic
09151          substantially easier */
09152       if (!drop && iax2_trunk_expired(tpeer, &now)) {
09153          /* Take it out of the list, but don't free it yet, because it
09154             could be in use */
09155          AST_LIST_REMOVE_CURRENT(list);
09156          drop = tpeer;
09157       } else {
09158          res = send_trunk(tpeer, &now);
09159          trunk_timed++; 
09160          if (iaxtrunkdebug)
09161             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);
09162       }     
09163       totalcalls += res;   
09164       res = 0;
09165       ast_mutex_unlock(&tpeer->lock);
09166    }
09167    AST_LIST_TRAVERSE_SAFE_END;
09168    AST_LIST_UNLOCK(&tpeers);
09169 
09170    if (drop) {
09171       ast_mutex_lock(&drop->lock);
09172       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
09173          because by the time they could get tpeerlock, we've already grabbed it */
09174       ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09175       if (drop->trunkdata) {
09176          ast_free(drop->trunkdata);
09177          drop->trunkdata = NULL;
09178       }
09179       ast_mutex_unlock(&drop->lock);
09180       ast_mutex_destroy(&drop->lock);
09181       ast_free(drop);
09182       
09183    }
09184 
09185    if (iaxtrunkdebug)
09186       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09187    iaxtrunkdebug = 0;
09188 
09189    return 1;
09190 }

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

Definition at line 14403 of file chan_iax2.c.

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

Referenced by load_objects().

14404 {
14405    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14406 
14407    /* The frames_received field is used to hold whether we're matching
14408     * against a full frame or not ... */
14409 
14410    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14411       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14412 }

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

Definition at line 14396 of file chan_iax2.c.

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

14397 {
14398    const struct chan_iax2_pvt *pvt = obj;
14399 
14400    return pvt->transfercallno;
14401 }

static int transmit_frame ( void *  data  )  [static]

Definition at line 4229 of file chan_iax2.c.

References AST_LIST_INSERT_TAIL, ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, frame_queue, iax2_sched_add(), iax_frame_free(), iaxs, iaxsl, iax2_trunk_peer::list, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, sched, send_packet(), and iax_frame::sentyet.

Referenced by iax2_transmit().

04230 {
04231    struct iax_frame *fr = data;
04232 
04233    ast_mutex_lock(&iaxsl[fr->callno]);
04234 
04235    fr->sentyet = 1;
04236 
04237    if (iaxs[fr->callno]) {
04238       send_packet(fr);
04239    }
04240 
04241    if (fr->retries < 0) {
04242       ast_mutex_unlock(&iaxsl[fr->callno]);
04243       /* No retransmit requested */
04244       iax_frame_free(fr);
04245    } else {
04246       /* We need reliable delivery.  Schedule a retransmission */
04247       AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04248       fr->retries++;
04249       fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04250       ast_mutex_unlock(&iaxsl[fr->callno]);
04251    }
04252 
04253    return 0;
04254 }

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

Definition at line 3301 of file chan_iax2.c.

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

Referenced by send_trunk().

03302 {
03303    int res;
03304    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03305                sizeof(*sin));
03306    if (res < 0) {
03307       ast_debug(1, "Received error: %s\n", strerror(errno));
03308       handle_error();
03309    } else
03310       res = 0;
03311    return res;
03312 }

static int try_firmware ( char *  s  )  [static]

Definition at line 3003 of file chan_iax2.c.

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

Referenced by reload_firmware().

03004 {
03005    struct stat stbuf;
03006    struct iax_firmware *cur = NULL;
03007    int ifd, fd, res, len, chunk;
03008    struct ast_iax2_firmware_header *fwh, fwh2;
03009    struct MD5Context md5;
03010    unsigned char sum[16], buf[1024];
03011    char *s2, *last;
03012 
03013    if (!(s2 = alloca(strlen(s) + 100))) {
03014       ast_log(LOG_WARNING, "Alloca failed!\n");
03015       return -1;
03016    }
03017 
03018    last = strrchr(s, '/');
03019    if (last)
03020       last++;
03021    else
03022       last = s;
03023 
03024    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
03025 
03026    if ((res = stat(s, &stbuf) < 0)) {
03027       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03028       return -1;
03029    }
03030 
03031    /* Make sure it's not a directory */
03032    if (S_ISDIR(stbuf.st_mode))
03033       return -1;
03034    ifd = open(s, O_RDONLY);
03035    if (ifd < 0) {
03036       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03037       return -1;
03038    }
03039    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03040    if (fd < 0) {
03041       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03042       close(ifd);
03043       return -1;
03044    }
03045    /* Unlink our newly created file */
03046    unlink(s2);
03047    
03048    /* Now copy the firmware into it */
03049    len = stbuf.st_size;
03050    while(len) {
03051       chunk = len;
03052       if (chunk > sizeof(buf))
03053          chunk = sizeof(buf);
03054       res = read(ifd, buf, chunk);
03055       if (res != chunk) {
03056          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03057          close(ifd);
03058          close(fd);
03059          return -1;
03060       }
03061       res = write(fd, buf, chunk);
03062       if (res != chunk) {
03063          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03064          close(ifd);
03065          close(fd);
03066          return -1;
03067       }
03068       len -= chunk;
03069    }
03070    close(ifd);
03071    /* Return to the beginning */
03072    lseek(fd, 0, SEEK_SET);
03073    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03074       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03075       close(fd);
03076       return -1;
03077    }
03078    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03079       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03080       close(fd);
03081       return -1;
03082    }
03083    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03084       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03085       close(fd);
03086       return -1;
03087    }
03088    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03089       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03090       close(fd);
03091       return -1;
03092    }
03093    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
03094    if (fwh == MAP_FAILED) {
03095       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03096       close(fd);
03097       return -1;
03098    }
03099    MD5Init(&md5);
03100    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03101    MD5Final(sum, &md5);
03102    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03103       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03104       munmap((void*)fwh, stbuf.st_size);
03105       close(fd);
03106       return -1;
03107    }
03108 
03109    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03110       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03111          /* Found a candidate */
03112          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03113             /* The version we have on loaded is older, load this one instead */
03114             break;
03115          /* This version is no newer than what we have.  Don't worry about it.
03116             We'll consider it a proper load anyhow though */
03117          munmap((void*)fwh, stbuf.st_size);
03118          close(fd);
03119          return 0;
03120       }
03121    }
03122    
03123    if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03124       cur->fd = -1;
03125       AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03126    }
03127    
03128    if (cur) {
03129       if (cur->fwh)
03130          munmap((void*)cur->fwh, cur->mmaplen);
03131       if (cur->fd > -1)
03132          close(cur->fd);
03133       cur->fwh = fwh;
03134       cur->fd = fd;
03135       cur->mmaplen = stbuf.st_size;
03136       cur->dead = 0;
03137    }
03138    
03139    return 0;
03140 }

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

Definition at line 8266 of file chan_iax2.c.

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

Referenced by socket_process().

08267 {
08268    int newcall = 0;
08269    char newip[256];
08270    struct iax_ie_data ied;
08271    struct sockaddr_in new;
08272    
08273    
08274    memset(&ied, 0, sizeof(ied));
08275    if (ies->apparent_addr)
08276       memmove(&new, ies->apparent_addr, sizeof(new));
08277    if (ies->callno)
08278       newcall = ies->callno;
08279    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08280       ast_log(LOG_WARNING, "Invalid transfer request\n");
08281       return -1;
08282    }
08283    pvt->transfercallno = newcall;
08284    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08285    inet_aton(newip, &pvt->transfer.sin_addr);
08286    pvt->transfer.sin_family = AF_INET;
08287    pvt->transferid = ies->transferid;
08288    /* only store by transfercallno if this is a new transfer,
08289     * just in case we get a duplicate TXREQ */
08290    if (pvt->transferring == TRANSFER_NONE) {
08291       store_by_transfercallno(pvt);
08292    }
08293    pvt->transferring = TRANSFER_BEGIN;
08294 
08295    if (ies->transferid)
08296       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08297    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08298    return 0;
08299 }

static format_t uncompress_subclass ( unsigned char  csub  )  [static]

Definition at line 1627 of file chan_iax2.c.

References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

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

01628 {
01629    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01630    if (csub & IAX_FLAG_SC_LOG) {
01631       /* special case for 'compressed' -1 */
01632       if (csub == 0xff)
01633          return -1;
01634       else
01635          return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01636    }
01637    else
01638       return csub;
01639 }

static void unlink_peer ( struct iax2_peer peer  )  [static]

Definition at line 8561 of file chan_iax2.c.

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

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

08562 {
08563    if (peer->expire > -1) {
08564       if (!ast_sched_thread_del(sched, peer->expire)) {
08565          peer->expire = -1;
08566          peer_unref(peer);
08567       }
08568    }
08569 
08570    if (peer->pokeexpire > -1) {
08571       if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08572          peer->pokeexpire = -1;
08573          peer_unref(peer);
08574       }
08575    }
08576 
08577    ao2_unlink(peers, peer);
08578 }

static int unload_module ( void   )  [static]

Definition at line 14361 of file chan_iax2.c.

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

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

Definition at line 5433 of file chan_iax2.c.

References ast_mutex_unlock, and iaxsl.

Referenced by iax2_bridge().

05434 {
05435    ast_mutex_unlock(&iaxsl[callno1]);
05436    ast_mutex_unlock(&iaxsl[callno0]);
05437 }

static void unwrap_timestamp ( struct iax_frame fr  )  [static]

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

03992 {
03993    /* Video mini frames only encode the lower 15 bits of the session
03994     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
03995    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03996    const int lower_mask = (1 << ts_shift) - 1;
03997    const int upper_mask = ~lower_mask;
03998    const int last_upper = iaxs[fr->callno]->last & upper_mask;
03999 
04000    if ( (fr->ts & upper_mask) == last_upper ) {
04001       const int x = fr->ts - iaxs[fr->callno]->last;
04002       const int threshold = (ts_shift == 15) ? 25000 : 50000;
04003 
04004       if (x < -threshold) {
04005          /* Sudden big jump backwards in timestamp:
04006             What likely happened here is that miniframe timestamp has circled but we haven't
04007             gotten the update from the main packet.  We'll just pretend that we did, and
04008             update the timestamp appropriately. */
04009          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04010          if (iaxdebug)
04011             ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04012       } else if (x > threshold) {
04013          /* Sudden apparent big jump forwards in timestamp:
04014             What's likely happened is this is an old miniframe belonging to the previous
04015             top 15 or 16-bit timestamp that has turned up out of order.
04016             Adjust the timestamp appropriately. */
04017          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04018          if (iaxdebug)
04019             ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04020       }
04021    }
04022 }

static void update_jbsched ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 4026 of file chan_iax2.c.

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

Referenced by __get_from_jb(), and schedule_delivery().

04027 {
04028    int when;
04029    
04030    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04031    
04032    when = jb_next(pvt->jb) - when;
04033 
04034    if (when <= 0) {
04035       /* XXX should really just empty until when > 0.. */
04036       when = 1;
04037    }
04038    
04039    pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 
04040       CALLNO_TO_PTR(pvt->callno));
04041 }

static void update_max_nontrunk ( void   )  [static]

Definition at line 2021 of file chan_iax2.c.

References ast_debug, iaxs, and TRUNK_CALL_START.

Referenced by __find_callno(), and make_trunk().

02022 {
02023    int max = 1;
02024    int x;
02025    /* XXX Prolly don't need locks here XXX */
02026    for (x=1;x<TRUNK_CALL_START - 1; x++) {
02027       if (iaxs[x])
02028          max = x + 1;
02029    }
02030    maxnontrunkcall = max;
02031    if (iaxdebug)
02032       ast_debug(1, "New max nontrunk callno is %d\n", max);
02033 }

static void update_max_trunk ( void   )  [static]

Definition at line 2004 of file chan_iax2.c.

References ARRAY_LEN, ast_debug, iaxs, and TRUNK_CALL_START.

Referenced by iax2_destroy(), and make_trunk().

02005 {
02006    int max = TRUNK_CALL_START;
02007    int x;
02008 
02009    /* XXX Prolly don't need locks here XXX */
02010    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
02011       if (iaxs[x]) {
02012          max = x + 1;
02013       }
02014    }
02015 
02016    maxtrunkcall = max;
02017    if (iaxdebug)
02018       ast_debug(1, "New max trunk callno is %d\n", max);
02019 }

static int update_packet ( struct iax_frame f  )  [static]

Definition at line 3439 of file chan_iax2.c.

References build_rand_pad(), ast_iax2_full_hdr::dcallno, decode_frame(), encrypt_frame(), f, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, and chan_iax2_pvt::iseqno.

Referenced by __attempt_transmit().

03440 {
03441    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
03442    struct ast_iax2_full_hdr *fh = f->data;
03443    struct ast_frame af;
03444 
03445    /* if frame is encrypted. decrypt before updating it. */
03446    if (f->encmethods) {
03447       decode_frame(&f->mydcx, fh, &af, &f->datalen);
03448    }
03449    /* Mark this as a retransmission */
03450    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03451    /* Update iseqno */
03452    f->iseqno = iaxs[f->callno]->iseqno;
03453    fh->iseqno = f->iseqno;
03454 
03455    /* Now re-encrypt the frame */
03456    if (f->encmethods) {
03457    /* since this is a retransmit frame, create a new random padding
03458     * before re-encrypting. */
03459       build_rand_pad(f->semirand, sizeof(f->semirand));
03460       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03461    }
03462    return 0;
03463 }

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

References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_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, iax2_peer::cid_name, iax2_peer::cid_num, context, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, iaxsl, LOG_NOTICE, LOG_WARNING, mailbox, iax2_peer::mailbox, manager_event, iax2_peer::maxcallno, iax2_peer::name, peer_ref(), peer_unref(), peercnt_modify(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, state, strsep(), version, and iax2_peer::zonetag.

Referenced by socket_process().

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

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

References CMP_MATCH, CMP_STOP, and user.

Referenced by load_objects().

01675 {
01676    struct iax2_user *user = obj, *user2 = arg;
01677 
01678    return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01679 }

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

Definition at line 12900 of file chan_iax2.c.

References ast_set_flag64, IAX_DELME, and user.

Referenced by delete_users().

12901 {
12902    struct iax2_user *user = obj;
12903 
12904    ast_set_flag64(user, IAX_DELME);
12905 
12906    return 0;
12907 }

static void user_destructor ( void *  obj  )  [static]

Definition at line 12625 of file chan_iax2.c.

References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), free_context(), and user.

Referenced by build_user().

12626 {
12627    struct iax2_user *user = obj;
12628 
12629    ast_free_ha(user->ha);
12630    free_context(user->contexts);
12631    if(user->vars) {
12632       ast_variables_destroy(user->vars);
12633       user->vars = NULL;
12634    }
12635    ast_string_field_free_memory(user);
12636 }

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

References ast_str_hash(), and user.

Referenced by load_objects().

01665 {
01666    const struct iax2_user *user = obj;
01667 
01668    return ast_str_hash(user->name);
01669 }

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

Definition at line 1721 of file chan_iax2.c.

References ao2_ref, and user.

01722 {
01723    ao2_ref(user, +1);
01724    return user;
01725 }

static struct iax2_user* user_unref ( struct iax2_user user  )  [inline, static]

Definition at line 1727 of file chan_iax2.c.

References ao2_ref, and user.

Referenced by authenticate_request(), authenticate_verify(), build_user(), calltoken_required(), check_access(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), prune_users(), requirecalltoken_mark_auto(), set_config(), and users_data_provider_get().

01728 {
01729    ao2_ref(user, -1);
01730    return NULL;
01731 }

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

Definition at line 14566 of file chan_iax2.c.

References 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, DEFAULT_CONTEXT, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, user, user_unref(), and users.

14568 {
14569    struct ast_data *data_user, *data_authmethods, *data_enum_node;
14570    struct iax2_user *user;
14571    struct ao2_iterator i;
14572    char auth[90];
14573    char *pstr = "";
14574 
14575    i = ao2_iterator_init(users, 0);
14576    for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
14577       data_user = ast_data_add_node(data_root, "user");
14578       if (!data_user) {
14579          continue;
14580       }
14581 
14582       ast_data_add_structure(iax2_user, data_user, user);
14583 
14584       ast_data_add_codecs(data_user, "codecs", user->capability);
14585 
14586       if (!ast_strlen_zero(user->secret)) {
14587          ast_copy_string(auth, user->secret, sizeof(auth));
14588       } else if (!ast_strlen_zero(user->inkeys)) {
14589          snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14590       } else {
14591          ast_copy_string(auth, "no secret", sizeof(auth));
14592       }
14593       ast_data_add_password(data_user, "secret", auth);
14594 
14595       ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14596 
14597       /* authmethods */
14598       data_authmethods = ast_data_add_node(data_user, "authmethods");
14599       if (!data_authmethods) {
14600          ast_data_remove_node(data_root, data_user);
14601          continue;
14602       }
14603       ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14604       ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14605       ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14606 
14607       /* amaflags */
14608       data_enum_node = ast_data_add_node(data_user, "amaflags");
14609       if (!data_enum_node) {
14610          ast_data_remove_node(data_root, data_user);
14611          continue;
14612       }
14613       ast_data_add_int(data_enum_node, "value", user->amaflags);
14614       ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14615 
14616       ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14617 
14618       if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14619          pstr = "REQ only";
14620       } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14621          pstr = "disabled";
14622       } else {
14623          pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14624       }
14625       ast_data_add_str(data_user, "codec-preferences", pstr);
14626 
14627       if (!ast_data_search_match(search, data_user)) {
14628          ast_data_remove_node(data_root, data_user);
14629       }
14630    }
14631    ao2_iterator_destroy(&i);
14632 
14633    return 0;
14634 }

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

Definition at line 9049 of file chan_iax2.c.

References AST_LIST_TRAVERSE, f, frame_queue, iax_frame::list, and send_packet().

Referenced by socket_process().

09050 {
09051    struct iax_frame *f;
09052 
09053    AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09054       /* Send a copy immediately */
09055       if (((unsigned char) (f->oseqno - last) < 128) &&
09056             (f->retries >= 0)) {
09057          send_packet(f);
09058       }
09059    }
09060 }

static int wait_for_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Note:
expects the pvt to be locked

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

05244 {
05245    unsigned short callno = pvt->callno;
05246 
05247    if (!pvt->peercallno) {
05248       /* We don't know the remote side's call number, yet.  :( */
05249       int count = 10;
05250       while (count-- && pvt && !pvt->peercallno) {
05251          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05252          pvt = iaxs[callno];
05253       }
05254       if (!pvt->peercallno) {
05255          return -1;
05256       }
05257    }
05258 
05259    return 0;
05260 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", } [static]

Definition at line 14775 of file chan_iax2.c.

char accountcode[AST_MAX_ACCOUNT_CODE] [static]

Definition at line 379 of file chan_iax2.c.

Referenced by __ast_channel_alloc_ap(), __oh323_new(), ast_async_goto(), ast_call_forward(), ast_cdr_setaccount(), ast_cel_fabricate_channel_from_event(), ast_do_masquerade(), ast_set_owners_and_peers(), begin_dial_channel(), build_peer(), check_peer_ok(), create_addr_from_peer(), dahdi_new(), do_forward(), findmeexec(), func_channel_write_real(), gtalk_new(), jingle_new(), local_call(), mgcp_new(), sip_new(), skinny_new(), and tds_log().

int adsi = 0 [static]

Definition at line 383 of file chan_iax2.c.

int amaflags = 0 [static]

Definition at line 382 of file chan_iax2.c.

Referenced by ast_async_goto().

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 14775 of file chan_iax2.c.

int authdebug = 1 [static]

Definition at line 290 of file chan_iax2.c.

int autokill = 0 [static]

Definition at line 291 of file chan_iax2.c.

struct ao2_container* callno_limits [static]

Table containing custom callno limit rules for a range of ip addresses.

Definition at line 890 of file chan_iax2.c.

Referenced by __unload_module(), build_callno_limits(), load_objects(), reload_config(), set_config_destroy(), and set_peercnt_limit().

struct ao2_container* callno_pool [static]

table of available call numbers

Definition at line 845 of file chan_iax2.c.

const unsigned int CALLNO_POOL_BUCKETS = 2699 [static]

Definition at line 850 of file chan_iax2.c.

struct ao2_container* callno_pool_trunk [static]

table of available trunk call numbers

Definition at line 848 of file chan_iax2.c.

struct ao2_container* calltoken_ignores [static]

Table containing ip addresses not requiring calltoken validation

Definition at line 893 of file chan_iax2.c.

Referenced by __unload_module(), add_calltoken_ignore(), calltoken_required(), load_objects(), reload_config(), and set_config_destroy().

struct ast_cli_entry cli_iax2[] [static]

Definition at line 14107 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

unsigned int cos

Definition at line 301 of file chan_iax2.c.

struct sockaddr_in debugaddr [static]

Definition at line 1097 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_debug(), iax_outputframe(), reload_config(), sip_debug_test_addr(), sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer().

uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048 [static]

Definition at line 895 of file chan_iax2.c.

uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static]

Definition at line 897 of file chan_iax2.c.

char default_parkinglot[AST_MAX_CONTEXT] [static]

Definition at line 268 of file chan_iax2.c.

Referenced by create_dynamic_parkinglot(), handle_parkedcalls(), load_config(), park_call_exec(), park_space_reserve(), parked_call_exec(), reload_config(), sip_alloc(), and xfer_park_call_helper().

int defaultsockfd = -1 [static]

Definition at line 313 of file chan_iax2.c.

int delayreject = 0 [static]

Definition at line 384 of file chan_iax2.c.

struct iax_frame* first

Definition at line 861 of file chan_iax2.c.

struct { ... } frame_queue[IAX_MAX_CALLS + 1] [static]

a list of frames that may need to be retransmitted

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

Contents protected by the iaxsl[] locks

Referenced by __attempt_transmit(), complete_transfer(), handle_cli_iax2_show_stats(), pvt_destructor(), resend_with_token(), socket_process(), transmit_frame(), and vnak_retransmit().

int global_max_trunk_mtu [static]

Maximum MTU, 0 if not used

Definition at line 263 of file chan_iax2.c.

uint16_t global_maxcallno [static]

Definition at line 899 of file chan_iax2.c.

uint16_t global_maxcallno_nonval [static]

Total num of call numbers allowed to be allocated without calltoken validation

Definition at line 902 of file chan_iax2.c.

int global_rtautoclear = 120 [static]

Definition at line 435 of file chan_iax2.c.

struct ast_flags64 globalflags = { 0 } [static]

Definition at line 387 of file chan_iax2.c.

format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static]

Definition at line 365 of file chan_iax2.c.

struct ast_data_entry iax2_data_providers[] [static]

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

Referenced by load_module().

int iax2_encryption = 0 [static]

Definition at line 385 of file chan_iax2.c.

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

Definition at line 315 of file chan_iax2.c.

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

struct ast_switch iax2_switch [static]

Definition at line 13993 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

struct ast_channel_tech iax2_tech [static]

Definition at line 1215 of file chan_iax2.c.

Referenced by __unload_module(), acf_channel_read(), ast_iax2_new(), function_iaxpeer(), iax2_bridge(), iax2_prov_app(), and load_module().

struct ast_datastore_info iax2_variable_datastore_info [static]

Initial value:

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

Definition at line 1330 of file chan_iax2.c.

Referenced by acf_iaxvar_read(), acf_iaxvar_write(), ast_iax2_new(), authenticate_reply(), iax2_call(), and socket_process().

struct ao2_container* iax_peercallno_pvts [static]

Another container of iax2_pvt structures.

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

Definition at line 1074 of file chan_iax2.c.

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_peercallno(), and store_by_peercallno().

struct ao2_container* iax_transfercallno_pvts [static]

Another container of iax2_pvt structures.

*

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

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

Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().

int iaxcompat = 0 [static]

Definition at line 292 of file chan_iax2.c.

int iaxdebug = 0 [static]

Definition at line 367 of file chan_iax2.c.

int iaxdefaultdpcache = 10 * 60 [static]

Definition at line 295 of file chan_iax2.c.

int iaxdefaulttimeout = 5 [static]

Definition at line 297 of file chan_iax2.c.

int iaxdynamicthreadcount = 0 [static]

Definition at line 632 of file chan_iax2.c.

Referenced by find_idle_thread().

int iaxdynamicthreadnum = 0 [static]

Definition at line 633 of file chan_iax2.c.

Referenced by find_idle_thread().

int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static]

Definition at line 631 of file chan_iax2.c.

Referenced by find_idle_thread(), and set_config().

struct ast_custom_function iaxpeer_function [static]

Initial value:

 {
   .name = "IAXPEER",
   .read = function_iaxpeer,
}

Definition at line 13913 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS+1] [static]

an array of iax2 pvt structures

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

Definition at line 1063 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_max_nontrunk(), update_max_trunk(), update_packet(), update_registry(), and wait_for_peercallno().

ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static]

chan_iax2_pvt structure locks

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

Definition at line 1083 of file chan_iax2.c.

Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __find_callno(), __get_from_jb(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), __unload_module(), acf_channel_read(), ast_cli_netstats(), ast_iax2_new(), auth_reject(), authenticate_reply(), auto_hangup(), cache_get_callno_locked(), delete_users(), dp_lookup(), find_cache(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_stats(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_destroy_helper(), iax2_do_register(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_key_rotate(), iax2_lock_owner(), iax2_poke_peer(), iax2_provision(), iax2_queryoption(), iax2_request(), iax2_setoption(), iax2_write(), load_module(), lock_both(), log_jitterstats(), make_trunk(), peer_destructor(), pvt_destructor(), register_verify(), registry_authrequest(), scheduled_destroy(), send_command_locked(), send_lagrq(), send_ping(), socket_process(), socket_process_meta(), transmit_frame(), unlock_both(), update_registry(), and wait_for_peercallno().

int iaxthreadcount = DEFAULT_THREAD_COUNT [static]

Definition at line 630 of file chan_iax2.c.

Referenced by handle_cli_iax2_show_threads(), set_config(), and start_network_thread().

int iaxtrunkdebug = 0 [static]

Definition at line 369 of file chan_iax2.c.

struct ast_custom_function iaxvar_function [static]

Initial value:

 {
   .name = "IAXVAR",
   .read = acf_iaxvar_read,
   .write = acf_iaxvar_write,
}

Definition at line 9843 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct io_context* io [static]

Definition at line 360 of file chan_iax2.c.

int jittertargetextra = 40 [static]

Definition at line 283 of file chan_iax2.c.

int lagrq_time = 10 [static]

Definition at line 279 of file chan_iax2.c.

char language[MAX_LANGUAGE] = "" [static]

Definition at line 270 of file chan_iax2.c.

struct iax_frame* last

Definition at line 861 of file chan_iax2.c.

int last_authmethod = 0 [static]

Definition at line 293 of file chan_iax2.c.

const time_t MAX_CALLTOKEN_DELAY = 10 [static]

Definition at line 867 of file chan_iax2.c.

int max_reg_expire [static]

Definition at line 305 of file chan_iax2.c.

int max_retries = 4 [static]

Definition at line 277 of file chan_iax2.c.

int maxauthreq = 3 [static]

Definition at line 276 of file chan_iax2.c.

int maxjitterbuffer = 1000 [static]

Definition at line 280 of file chan_iax2.c.

int maxjitterinterps = 10 [static]

Definition at line 282 of file chan_iax2.c.

int maxnontrunkcall = 1 [static]

Definition at line 1164 of file chan_iax2.c.

int maxtrunkcall = TRUNK_CALL_START [static]

Definition at line 1163 of file chan_iax2.c.

int min_reg_expire [static]

Definition at line 304 of file chan_iax2.c.

char mohinterpret[MAX_MUSICCLASS] [static]

Definition at line 380 of file chan_iax2.c.

char mohsuggest[MAX_MUSICCLASS] [static]

Definition at line 381 of file chan_iax2.c.

Referenced by build_peer(), check_peer_ok(), create_addr_from_peer(), set_peer_defaults(), and sip_alloc().

struct ast_netsock_list* netsock [static]

Definition at line 311 of file chan_iax2.c.

Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().

pthread_t netthreadid = AST_PTHREADT_NULL [static]

Definition at line 389 of file chan_iax2.c.

int network_change_event_sched_id = -1 [static]

Definition at line 274 of file chan_iax2.c.

Referenced by network_change_event_cb(), and network_change_event_sched_cb().

struct ast_event_sub* network_change_event_subscription [static]

subscription id for network change events

Definition at line 273 of file chan_iax2.c.

Referenced by network_change_event_subscribe(), and network_change_event_unsubscribe().

struct ast_netsock_list* outsock [static]

used if sourceaddress specified and bindaddr == INADDR_ANY

Definition at line 312 of file chan_iax2.c.

Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().

char* papp = "IAX2Provision" [static]

Definition at line 11868 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

struct ao2_container* peercnts [static]

Table containing peercnt objects for every ip address consuming a callno

Definition at line 887 of file chan_iax2.c.

Referenced by __unload_module(), handle_cli_iax2_show_callno_limits(), load_objects(), peercnt_add(), peercnt_modify(), peercnt_remove(), peercnt_remove_by_addr(), reload_config(), and sched_delay_remove().

struct ao2_container* peers [static]

Definition at line 881 of file chan_iax2.c.

Referenced by __iax2_show_peers(), __unload_module(), authenticate_reply(), build_peer(), complete_iax2_peers(), complete_iax2_unregister(), delete_users(), find_peer(), get_insecure_variable_from_sipregs(), handle_cli_iax2_unregister(), iax2_getpeername(), iax2_getpeertrunk(), load_module(), load_objects(), manager_iax2_show_peer_list(), peers_data_provider_get(), poke_all_peers(), prune_peers(), set_config(), and unlink_peer().

struct ast_data_handler peers_data_provider [static]

Initial value:

Definition at line 14636 of file chan_iax2.c.

int ping_time = 21 [static]

Definition at line 278 of file chan_iax2.c.

struct ast_codec_pref prefs [static]

Definition at line 254 of file chan_iax2.c.

Referenced by ast_best_codec(), ast_rtp_codecs_packetization_set(), build_peer(), build_user(), check_access(), create_addr(), gtalk_create_member(), gtalk_load_config(), jingle_create_member(), jingle_load_config(), new_iax(), set_config(), set_local_capabilities(), and set_peer_capabilities().

struct { ... } qos [static]

Referenced by config_load(), config_parse_variables(), peer_set_srcaddr(), reload_config(), set_config(), and start_rtp().

int randomcalltokendata [static]

Definition at line 865 of file chan_iax2.c.

char regcontext[AST_MAX_CONTEXT] = "" [static]

Definition at line 271 of file chan_iax2.c.

int resyncthreshold = 1000 [static]

Definition at line 281 of file chan_iax2.c.

struct ast_sched_thread* sched [static]

Definition at line 361 of file chan_iax2.c.

int srvlookup = 0 [static]

Definition at line 307 of file chan_iax2.c.

Referenced by build_peer().

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

Definition at line 256 of file chan_iax2.c.

int test_losspct = 0 [static]

Definition at line 371 of file chan_iax2.c.

struct ast_timer* timer [static]

Definition at line 309 of file chan_iax2.c.

Referenced by __unload_module(), build_peer(), build_user(), check_timer(), find_timer(), kqueue_timer_hash(), kqueue_timer_open(), load_module(), network_thread(), pthread_timer_ack(), pthread_timer_close(), pthread_timer_destructor(), pthread_timer_disable_continuous(), pthread_timer_enable_continuous(), pthread_timer_get_event(), pthread_timer_hash(), pthread_timer_open(), pthread_timer_set_rate(), read_pipe(), run_timer(), softmix_bridge_create(), softmix_bridge_thread(), timer_destroy(), timerfd_timer_hash(), timerfd_timer_open(), timing_read(), timing_test(), and write_byte().

unsigned int tos

Definition at line 300 of file chan_iax2.c.

uint16_t total_nonval_callno_used = 0 [static]

Definition at line 904 of file chan_iax2.c.

struct ast_taskprocessor* transmit_processor [static]

Definition at line 863 of file chan_iax2.c.

int trunk_maxmtu [static]

Definition at line 264 of file chan_iax2.c.

int trunk_nmaxmtu [static]

Trunk MTU statistics

Definition at line 264 of file chan_iax2.c.

int trunk_timed [static]

Definition at line 264 of file chan_iax2.c.

int trunk_untimed [static]

Definition at line 264 of file chan_iax2.c.

int trunkfreq = 20 [static]

Definition at line 287 of file chan_iax2.c.

int trunkmaxsize = MAX_TRUNKDATA [static]

Definition at line 288 of file chan_iax2.c.

struct ao2_container* users [static]

Definition at line 884 of file chan_iax2.c.

Referenced by __unload_module(), authenticate_request(), authenticate_verify(), build_user(), check_access(), delete_users(), find_user(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), load_module(), load_objects(), pp_each_user_helper(), prune_users(), set_config(), unload_module(), and users_data_provider_get().

struct ast_data_handler users_data_provider [static]

Initial value:

Definition at line 14641 of file chan_iax2.c.


Generated on Mon Mar 19 11:30:40 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7