Mon Oct 8 12:39:13 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
#define update_max_nontrunk()   do { } while (0)
#define update_max_trunk()   do { } while (0)

Enumerations

enum  {
  CACHE_FLAG_EXISTS = (1 << 0), CACHE_FLAG_NONEXISTENT = (1 << 1), CACHE_FLAG_CANEXIST = (1 << 2), CACHE_FLAG_PENDING = (1 << 3),
  CACHE_FLAG_TIMEOUT = (1 << 4), CACHE_FLAG_TRANSMITTED = (1 << 5), CACHE_FLAG_UNKNOWN = (1 << 6), CACHE_FLAG_MATCHMORE = (1 << 7)
}
enum  { NEW_PREVENT = 0, NEW_ALLOW = 1, NEW_FORCE = 2, NEW_ALLOW_CALLTOKEN_VALIDATED = 3 }
enum  calltoken_peer_enum { CALLTOKEN_DEFAULT = 0, CALLTOKEN_YES = 1, CALLTOKEN_AUTO = 2, CALLTOKEN_NO = 3 }
 Call token validation settings. More...
enum  iax2_state { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) }
enum  iax2_thread_iostate { IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_SCHEDREADY }
enum  iax2_thread_type { IAX_THREAD_TYPE_POOL, IAX_THREAD_TYPE_DYNAMIC }
enum  iax_reg_state {
  REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED,
  REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH
}
enum  iax_transfer_state {
  TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED,
  TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED,
  TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS
}

Functions

static void __attempt_transmit (const void *data)
static void __auth_reject (const void *nothing)
static void __auto_congest (const void *nothing)
static void __auto_hangup (const void *nothing)
static int __do_deliver (void *data)
static void __expire_registry (const void *data)
static int __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
static void __get_from_jb (const void *p)
static void __iax2_do_register_s (const void *data)
static void __iax2_poke_noanswer (const void *data)
static void __iax2_poke_peer_s (const void *data)
static int __iax2_show_peers (int fd, int *total, struct mansession *s, const int argc, const char *const argv[])
static 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 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 = "ac1f6a56484a8820659555499174e588" , .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 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 243 of file chan_iax2.c.

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

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

Referenced by handle_call_token().

#define CALLTOKEN_IE_FORMAT   "%u?%s"

Referenced by handle_call_token().

#define DATA_EXPORT_IAX2_PEER ( MEMBER   ) 

Definition at line 14542 of file chan_iax2.c.

#define DATA_EXPORT_IAX2_USER ( MEMBER   ) 

Definition at line 14619 of file chan_iax2.c.

#define DEBUG_SCHED_MULTITHREAD

Definition at line 235 of file chan_iax2.c.

#define DEBUG_SUPPORT

Definition at line 251 of file chan_iax2.c.

#define DEFAULT_CONTEXT   "default"

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

#define DEFAULT_FREQ_NOTOK   10 * 1000

Definition at line 345 of file chan_iax2.c.

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

#define DEFAULT_FREQ_OK   60 * 1000

Definition at line 344 of file chan_iax2.c.

Referenced by build_peer().

#define DEFAULT_MAX_THREAD_COUNT   100

Definition at line 246 of file chan_iax2.c.

#define DEFAULT_MAXMS   2000

Definition at line 343 of file chan_iax2.c.

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

#define DEFAULT_RETRY_TIME   1000

Definition at line 247 of file chan_iax2.c.

Referenced by __find_callno(), and complete_transfer().

#define DEFAULT_THREAD_COUNT   10

Definition at line 245 of file chan_iax2.c.

#define DEFAULT_TRUNKDATA   640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 624 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

#define DONT_RESCHEDULE   -2

Definition at line 367 of file chan_iax2.c.

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

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

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

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

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

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

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

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

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

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

#define GAMMA   (0.01)

Definition at line 256 of file chan_iax2.c.

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

Definition at line 545 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

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

Allow the FWDOWNL command?

Definition at line 433 of file chan_iax2.c.

Referenced by set_config(), and socket_process().

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

Already disconnected

Definition at line 416 of file chan_iax2.c.

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

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

Definition at line 348 of file chan_iax2.c.

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

#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF

Definition at line 322 of file chan_iax2.c.

Referenced by cache_get_callno_locked(), and set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH

Value:

Definition at line 334 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWFREE

Value:

Definition at line 339 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH

Definition at line 324 of file chan_iax2.c.

Referenced by set_config().

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

only consider requested format and ignore capabilities

Definition at line 423 of file chan_iax2.c.

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

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

Force old behaviour by turning off prefs

Definition at line 422 of file chan_iax2.c.

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

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

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

Definition at line 421 of file chan_iax2.c.

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

#define IAX_DEBUGDIGEST ( msg,
key   ) 

Definition at line 351 of file chan_iax2.c.

Referenced by iax2_key_rotate(), and socket_process().

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

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

Definition at line 432 of file chan_iax2.c.

Referenced by socket_process().

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

Needs to be deleted

Definition at line 408 of file chan_iax2.c.

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

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

dynamic peer

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

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

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

Forces call encryption, if encryption not possible hangup

Definition at line 437 of file chan_iax2.c.

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

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

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

Definition at line 427 of file chan_iax2.c.

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

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

CallerID has been specified

Definition at line 407 of file chan_iax2.c.

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

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

Allow immediate off-hook to extension s

Definition at line 434 of file chan_iax2.c.

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

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

Whether we have a key populated

Definition at line 420 of file chan_iax2.c.

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

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

Maximum outstanding AUTHREQ restriction is in place

Definition at line 431 of file chan_iax2.c.

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

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

Don't native bridge

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

Referenced by iax2_provision(), and socket_process().

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

Whether or not we quelch audio

Definition at line 418 of file chan_iax2.c.

Referenced by iax2_write(), and socket_process().

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

Allow receiving of connected line updates

Definition at line 436 of file chan_iax2.c.

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

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

erase me on expire

Definition at line 426 of file chan_iax2.c.

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

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

let realtime stay till your reload

Definition at line 424 of file chan_iax2.c.

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

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

When using realtime, ignore registration expiration

Definition at line 428 of file chan_iax2.c.

Referenced by set_config().

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

Save Systname on Realtime Updates

Definition at line 415 of file chan_iax2.c.

Referenced by realtime_update_peer(), and set_config().

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

Send a realtime update

Definition at line 425 of file chan_iax2.c.

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

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

Send ANI along with CallerID

Definition at line 414 of file chan_iax2.c.

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

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

Allow sending of connected line updates

Definition at line 435 of file chan_iax2.c.

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

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

Turn on and off caller id shrinking

Definition at line 438 of file chan_iax2.c.

Referenced by check_access(), and set_config().

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

Temporary (realtime)

Definition at line 409 of file chan_iax2.c.

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

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

When doing IAX2 transfers, transfer media only

Definition at line 430 of file chan_iax2.c.

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

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

Treat as a trunk

Definition at line 410 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 429 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 412 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 632 of file chan_iax2.c.

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

#define MAX_JITTER_BUFFER   50

Definition at line 621 of file chan_iax2.c.

#define MAX_PEER_BUCKETS   563

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

Referenced by load_objects().

#define MAX_RETRY_TIME   10000

Definition at line 619 of file chan_iax2.c.

Referenced by __attempt_transmit(), and iax2_send().

#define MAX_TIMESTAMP_SKEW   160

maximum difference between actual and predicted ts for sending

Definition at line 626 of file chan_iax2.c.

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

#define MAX_TRUNK_MTU   1240

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

Definition at line 265 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_mtu(), and set_config().

#define MAX_TRUNKDATA   640 * 200

40ms, uncompressed linear * 200 channels

Definition at line 289 of file chan_iax2.c.

Referenced by set_config(), and set_config_destroy().

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

Definition at line 887 of file chan_iax2.c.

Referenced by load_module(), and load_objects().

#define MEMORY_SIZE   100

Definition at line 248 of file chan_iax2.c.

#define MIN_JITTER_BUFFER   10

Definition at line 622 of file chan_iax2.c.

#define MIN_RETRY_TIME   100

Definition at line 618 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME   60

Definition at line 253 of file chan_iax2.c.

Referenced by make_trunk(), and sched_delay_remove().

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

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

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

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

#define TS_GAP_FOR_JB_RESYNC   5000

Definition at line 629 of file chan_iax2.c.

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

Definition at line 2048 of file chan_iax2.c.

Referenced by __find_callno(), and make_trunk().

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

Definition at line 2047 of file chan_iax2.c.

Referenced by iax2_destroy(), and make_trunk().


Enumeration Type Documentation

anonymous enum

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

Definition at line 943 of file chan_iax2.c.

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

anonymous enum

Enumerator:
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 1974 of file chan_iax2.c.

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

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

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

enum iax2_state

Enumerator:
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 395 of file chan_iax2.c.

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

enum iax2_thread_iostate

Enumerator:
IAX_IOSTATE_IDLE 
IAX_IOSTATE_READY 
IAX_IOSTATE_PROCESSING 
IAX_IOSTATE_SCHEDREADY 

Definition at line 984 of file chan_iax2.c.

enum iax2_thread_type

Enumerator:
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 991 of file chan_iax2.c.

00991                       {
00992    IAX_THREAD_TYPE_POOL,
00993    IAX_THREAD_TYPE_DYNAMIC,
00994 };

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


Function Documentation

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

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

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

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

Definition at line 8993 of file chan_iax2.c.

References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, IAX_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().

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

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

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

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

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

Definition at line 9042 of file chan_iax2.c.

References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, IAX_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().

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

static int __do_deliver ( void *  data  )  [static]

Note:
This function assumes that iaxsl[callno] is locked when called.

IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function calls iax2_queue_frame(), which may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.

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

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

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

Definition at line 8619 of file chan_iax2.c.

References iax2_peer::addr, ast_db_del(), ast_debug, AST_DEVICE_UNAVAILABLE, ast_devstate_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().

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

static int __find_callno ( unsigned short  callno,
unsigned short  dcallno,
struct sockaddr_in *  sin,
int  new,
int  sockfd,
int  return_locked,
int  check_dcallno 
) [static]

Definition at line 2779 of file chan_iax2.c.

References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ao2_find, ao2_ref, ast_copy_flags64, ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_set, 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, and update_max_nontrunk.

Referenced by find_callno(), and find_callno_locked().

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

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

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

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

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

Definition at line 8290 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

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

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

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

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

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

Definition at line 9102 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

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

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

Definition at line 6654 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_to_sin, ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, astman_append(), iax2_peer::encmethods, encmethods_to_str(), FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, 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().

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

static void __reg_module ( void   )  [static]

Definition at line 14844 of file chan_iax2.c.

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

Definition at line 1461 of file chan_iax2.c.

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

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

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

Definition at line 7481 of file chan_iax2.c.

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

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

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

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

Definition at line 1572 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, 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().

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

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

Definition at line 1505 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, 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().

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

static int __unload_module ( void   )  [static]

Definition at line 14347 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, peercnts, peers, reload_firmware(), sched, timer, and users.

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

static void __unreg_module ( void   )  [static]

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

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

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

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

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

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

Definition at line 9840 of file chan_iax2.c.

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

09841 {
09842    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09843    AST_LIST_HEAD(, ast_var_t) *varlist;
09844    struct ast_var_t *var;
09845 
09846    if (!variablestore) {
09847       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09848       if (!variablestore) {
09849          ast_log(LOG_ERROR, "Memory allocation error\n");
09850          return -1;
09851       }
09852       varlist = ast_calloc(1, sizeof(*varlist));
09853       if (!varlist) {
09854          ast_datastore_free(variablestore);
09855          ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09856          return -1;
09857       }
09858 
09859       AST_LIST_HEAD_INIT(varlist);
09860       variablestore->data = varlist;
09861       variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09862       ast_channel_datastore_add(chan, variablestore);
09863    } else
09864       varlist = variablestore->data;
09865 
09866    AST_LIST_LOCK(varlist);
09867    AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09868       if (strcmp(var->name, data) == 0) {
09869          AST_LIST_REMOVE_CURRENT(entries);
09870          ast_var_delete(var);
09871          break;
09872       }
09873    }
09874    AST_LIST_TRAVERSE_SAFE_END;
09875    var = ast_var_assign(data, value);
09876    if (var)
09877       AST_LIST_INSERT_TAIL(varlist, var, entries);
09878    else
09879       ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09880    AST_LIST_UNLOCK(varlist);
09881    return 0;
09882 }

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

Definition at line 2514 of file chan_iax2.c.

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

Referenced by set_config().

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

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

Definition at line 4751 of file chan_iax2.c.

References iax_ie_data::buf, 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().

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

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

Definition at line 2165 of file chan_iax2.c.

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

Referenced by load_objects().

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

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

Definition at line 2150 of file chan_iax2.c.

References addr_range::delme.

Referenced by set_config_destroy().

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

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

Definition at line 2157 of file chan_iax2.c.

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

Referenced by load_objects().

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

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

Definition at line 2185 of file chan_iax2.c.

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

Referenced by calltoken_required(), and set_peercnt_limit().

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

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

Definition at line 7539 of file chan_iax2.c.

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

Referenced by check_access().

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

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

Definition at line 7240 of file chan_iax2.c.

References ACN_FORMAT1, ACN_FORMAT2, ARRAY_LEN, ast_cli(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, astman_append(), jb_info::current, 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().

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

AST_DATA_STRUCTURE ( iax2_user  ,
DATA_EXPORT_IAX2_USER   
)

AST_DATA_STRUCTURE ( iax2_peer  ,
DATA_EXPORT_IAX2_PEER   
)

static struct ast_channel* ast_iax2_new ( int  callno,
int  state,
format_t  capability,
const char *  linkedid 
) [static]

Create new call, interface with the PBX core.

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

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

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

Definition at line 3566 of file chan_iax2.c.

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and transmit_frame().

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

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

Definition at line 9027 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

Definition at line 9013 of file chan_iax2.c.

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

Referenced by auth_fail().

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

static int authenticate ( const char *  challenge,
const char *  secret,
const char *  keyn,
int  authmethods,
struct iax_ie_data ied,
struct sockaddr_in *  sin,
struct chan_iax2_pvt pvt 
) [static]

Definition at line 8112 of file chan_iax2.c.

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

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

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

static int authenticate_reply ( struct chan_iax2_pvt p,
struct sockaddr_in *  sin,
struct iax_ies ies,
const char *  override,
const char *  okey 
) [static]

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

Definition at line 8170 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_calloc, ast_channel_datastore_add(), ast_datastore_alloc, ast_datastore_free(), AST_FRAME_IAX, ast_free, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_sockaddr_to_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_assign(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, 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().

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

static int authenticate_request ( int  call_num  )  [static]

Precondition:
iaxsl[call_num] is locked
Note:
Since this function calls send_command_final(), the pvt struct for the given call number may disappear while executing this function.

Definition at line 7818 of file chan_iax2.c.

References ao2_find, AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_random(), ast_set_flag64, ast_string_field_set, ast_test_flag64, chan_iax2_pvt::authmethods, 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().

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

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

Definition at line 7871 of file chan_iax2.c.

References ao2_find, ast_atomic_fetchadd_int(), ast_check_signature(), ast_clear_flag64, ast_copy_string(), ast_key_get(), AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, 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().

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

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

Definition at line 4686 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

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

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

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

Definition at line 9057 of file chan_iax2.c.

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

Referenced by iax2_dprequest(), and iax2_provision().

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

static void build_callno_limits ( struct ast_variable v  )  [static]

Definition at line 2459 of file chan_iax2.c.

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

Referenced by set_config().

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

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

Definition at line 12249 of file chan_iax2.c.

References ast_calloc, and ast_copy_string().

Referenced by build_user().

12250 {
12251    struct iax2_context *con;
12252 
12253    if ((con = ast_calloc(1, sizeof(*con))))
12254       ast_copy_string(con->context, context, sizeof(con->context));
12255    
12256    return con;
12257 }

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

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

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

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

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

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

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 12400 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, 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(), peers, prefs, S_OR, sched, secret, ast_sockaddr::ss, strsep(), timer, unlink_peer(), ast_variable::value, and zonetag.

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

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

Definition at line 6181 of file chan_iax2.c.

References ast_random().

Referenced by build_ecx_key(), and update_packet().

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 2682 of file chan_iax2.c.

References ast_random().

Referenced by create_callno_pools().

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

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

Definition at line 2206 of file chan_iax2.c.

References addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, calltoken_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().

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

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

Definition at line 7550 of file chan_iax2.c.

References 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_SENSE_ALLOW, AST_SENSE_DENY, ast_set2_flag64, ast_set_flag64, ast_shrink_phone_number(), ast_sockaddr_from_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_variable_new(), 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().

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

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

Definition at line 9424 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

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

Referenced by peer_set_srcaddr().

12276 {
12277    int sd;
12278    int res;
12279    
12280    sd = socket(AF_INET, SOCK_DGRAM, 0);
12281    if (sd < 0) {
12282       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12283       return -1;
12284    }
12285 
12286    res = bind(sd, sa, salen);
12287    if (res < 0) {
12288       ast_debug(1, "Can't bind: %s\n", strerror(errno));
12289       close(sd);
12290       return 1;
12291    }
12292 
12293    close(sd);
12294    return 0;
12295 }

static void cleanup_thread_list ( void *  head  )  [static]

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

14328 {
14329    AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14330    struct iax2_thread_list *list_head = head;
14331    struct iax2_thread *thread;
14332 
14333    AST_LIST_LOCK(list_head);
14334    while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
14335       pthread_t thread_id = thread->threadid;
14336 
14337       thread->stop = 1;
14338       signal_condition(&thread->lock, &thread->cond);
14339 
14340       AST_LIST_UNLOCK(list_head);
14341       pthread_join(thread_id, NULL);
14342       AST_LIST_LOCK(list_head);
14343    }
14344    AST_LIST_UNLOCK(list_head);
14345 }

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

Definition at line 8340 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

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

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

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

Definition at line 6903 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_unregister().

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

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

Definition at line 8387 of file chan_iax2.c.

References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, AST_LIST_TRAVERSE, ast_log(), iax_ies::callno, jb_frame::data, DEFAULT_RETRY_TIME, 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().

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

static unsigned char compress_subclass ( format_t  subclass  )  [static]

Definition at line 1608 of file chan_iax2.c.

References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.

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

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

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

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

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

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

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

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

static int create_callno_pools ( void   )  [static]

Definition at line 2687 of file chan_iax2.c.

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

Referenced by load_objects().

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

static int decode_frame ( ast_aes_decrypt_key dcx,
struct ast_iax2_full_hdr fh,
struct ast_frame f,
int *  datalen 
) [static]

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

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

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

Definition at line 6343 of file chan_iax2.c.

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

Referenced by socket_process().

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

static void defer_full_frame ( struct iax2_thread from_here,
struct iax2_thread to_here 
) [static]

Queue the last read full frame for processing by a certain thread.

If there are already any full frames queued, they are sorted by sequence number.

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

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

static void delete_users ( void   )  [static]

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

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

static void destroy_firmware ( struct iax_firmware cur  )  [static]

Definition at line 3017 of file chan_iax2.c.

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

Referenced by reload_firmware().

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

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

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

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

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

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

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

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

Definition at line 1542 of file chan_iax2.c.

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

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

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

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

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

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

Definition at line 8655 of file chan_iax2.c.

References __expire_registry(), and schedule_action.

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

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

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

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

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

static int find_callno ( unsigned short  callno,
unsigned short  dcallno,
struct sockaddr_in *  sin,
int  new,
int  sockfd,
int  full_frame 
) [static]

Definition at line 2942 of file chan_iax2.c.

References __find_callno().

Referenced by iax2_poke_peer(), and socket_process().

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

static int find_callno_locked ( unsigned short  callno,
unsigned short  dcallno,
struct sockaddr_in *  sin,
int  new,
int  sockfd,
int  full_frame 
) [static]

Definition at line 2946 of file chan_iax2.c.

References __find_callno().

Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process_meta().

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

static struct iax2_thread* find_idle_thread ( void   )  [static]

Definition at line 1394 of file chan_iax2.c.

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

Referenced by __schedule_action(), and socket_read().

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

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

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

Definition at line 1686 of file chan_iax2.c.

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

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

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

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

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

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

Definition at line 1714 of file chan_iax2.c.

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

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

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

Definition at line 5887 of file chan_iax2.c.

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

Referenced by socket_process_meta().

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

static void free_context ( struct iax2_context con  )  [static]

Definition at line 12106 of file chan_iax2.c.

References ast_free, and iax2_context::next.

Referenced by build_user(), and user_destructor().

12107 {
12108    struct iax2_context *conl;
12109    while(con) {
12110       conl = con;
12111       con = con->next;
12112       ast_free(conl);
12113    }
12114 }

static void free_signaling_queue_entry ( struct signaling_queue_entry s  )  [static]

Definition at line 1820 of file chan_iax2.c.

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

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

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

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

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

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

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

Definition at line 12259 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

12260 {
12261    int methods = 0;
12262    if (strstr(value, "rsa"))
12263       methods |= IAX_AUTH_RSA;
12264    if (strstr(value, "md5"))
12265       methods |= IAX_AUTH_MD5;
12266    if (strstr(value, "plaintext"))
12267       methods |= IAX_AUTH_PLAINTEXT;
12268    return methods;
12269 }

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

Definition at line 1558 of file chan_iax2.c.

References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.

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

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

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

Definition at line 4143 of file chan_iax2.c.

References __get_from_jb(), and schedule_action.

Referenced by update_jbsched().

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

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

Definition at line 2620 of file chan_iax2.c.

References ao2_container_count(), ao2_find, ao2_lock, ao2_unlock, ast_log(), LOG_WARNING, OBJ_CONTINUE, OBJ_POINTER, OBJ_UNLINK, and callno_entry::validated.

Referenced by __find_callno(), and make_trunk().

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

static int handle_call_token ( struct ast_iax2_full_hdr fh,
struct iax_ies ies,
struct sockaddr_in *  sin,
int  fd 
) [static]

Definition at line 4883 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

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

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

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

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

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

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

Definition at line 13568 of file chan_iax2.c.

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

13569 {
13570    switch (cmd) {
13571    case CLI_INIT:
13572       e->command = "iax2 reload";
13573       e->usage =
13574          "Usage: iax2 reload\n"
13575          "       Reloads IAX configuration from iax.conf\n";
13576       return NULL;
13577    case CLI_GENERATE:
13578       return NULL;
13579    }
13580 
13581    reload_config();
13582 
13583    return CLI_SUCCESS;
13584 }

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

Definition at line 7347 of file chan_iax2.c.

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

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

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

Definition at line 7426 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), and ast_cli_entry::usage.

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

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

Definition at line 7400 of file chan_iax2.c.

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

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

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

Set trunk MTU from CLI.

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

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

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

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

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

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

Definition at line 2555 of file chan_iax2.c.

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

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

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

Definition at line 7174 of file chan_iax2.c.

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

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

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

Definition at line 6960 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_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.

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

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

Definition at line 7324 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli(), ast_cli_netstats(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

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

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

Show one peer in detail.

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

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

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

Definition at line 6928 of file chan_iax2.c.

References __iax2_show_peers(), ast_cli_args::argc, ast_cli_args::argv, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, RESULT_FAILURE, RESULT_SHOWUSAGE, and ast_cli_entry::usage.

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

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

Definition at line 7083 of file chan_iax2.c.

References iax2_registry::addr, ast_cli_args::argc, ast_cli(), ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_registry::dnsmgr, 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.

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

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

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

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

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

Definition at line 6790 of file chan_iax2.c.

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

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

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

Definition at line 6581 of file chan_iax2.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_strlen_zero(), ast_test_flag64, 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.

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

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

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

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

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

Definition at line 6859 of file chan_iax2.c.

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

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

static void handle_deferred_full_frames ( struct iax2_thread thread  )  [static]

Handle any deferred full frames for this thread.

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

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

static int handle_error ( void   )  [static]

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

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

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

Acknowledgment received for OUR registration.

Definition at line 8449 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

Definition at line 2756 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_FWDOWNL, IAX_COMMAND_NEW, IAX_COMMAND_POKE, IAX_COMMAND_REGREL, and IAX_COMMAND_REGREQ.

Referenced by resend_with_token(), and socket_process().

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

static void iax2_ami_channelupdate ( struct chan_iax2_pvt pvt  )  [static]

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

Definition at line 1323 of file chan_iax2.c.

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

Referenced by ast_iax2_new(), and iax2_answer().

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

static int iax2_answer ( struct ast_channel c  )  [static]

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

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

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

Definition at line 8515 of file chan_iax2.c.

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

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

static enum ast_bridge_result iax2_bridge ( struct ast_channel c0,
struct ast_channel c1,
int  flags,
struct ast_frame **  fo,
struct ast_channel **  rc,
int  timeoutms 
) [static]

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

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

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

Definition at line 5026 of file chan_iax2.c.

References ast_channel::_state, add_empty_calltoken_ie(), 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.

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

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

part of the IAX2 dial plan switch interface

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

13818 {
13819    int res = 0;
13820    struct iax2_dpcache *dp = NULL;
13821 #if 0
13822    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13823 #endif
13824    if ((priority != 1) && (priority != 2))
13825       return 0;
13826 
13827    AST_LIST_LOCK(&dpcache);
13828    if ((dp = find_cache(chan, data, context, exten, priority))) {
13829       if (dp->flags & CACHE_FLAG_CANEXIST)
13830          res = 1;
13831    } else {
13832       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13833    }
13834    AST_LIST_UNLOCK(&dpcache);
13835 
13836    return res;
13837 }

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

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

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

static void iax2_destroy ( int  callno  )  [static]

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

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

static void iax2_destroy_helper ( struct chan_iax2_pvt pvt  )  [static]

Note:
Assumes the lock on the pvt is already held, when iax2_destroy_helper() is called.

Definition at line 1771 of file chan_iax2.c.

References ao2_find, ast_atomic_fetchadd_int(), ast_clear_flag64, AST_SCHED_DEL_SPINLOCK, ast_sched_thread_del, ast_sched_thread_get_context(), ast_test_flag64, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::callno, 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().

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

static int iax2_devicestate ( void *  data  )  [static]

Part of the device state notification system ---.

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

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

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

Definition at line 4296 of file chan_iax2.c.

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

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

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

Definition at line 4301 of file chan_iax2.c.

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

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

static int iax2_do_register ( struct iax2_registry reg  )  [static]

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

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

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

Definition at line 8297 of file chan_iax2.c.

References __iax2_do_register_s(), and schedule_action.

Referenced by iax2_ack_registry(), and iax2_do_register().

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

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

Definition at line 9072 of file chan_iax2.c.

References AST_FRAME_IAX, auto_hangup(), chan_iax2_pvt::autoid, 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().

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

static void * iax2_dup_variable_datastore ( void *   )  [static]

Definition at line 1337 of file chan_iax2.c.

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

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

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

Execute IAX2 dialplan switch.

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

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

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

13795 {
13796    int res = 0;
13797    struct iax2_dpcache *dp = NULL;
13798 #if 0
13799    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13800 #endif
13801    if ((priority != 1) && (priority != 2))
13802       return 0;
13803 
13804    AST_LIST_LOCK(&dpcache);
13805    if ((dp = find_cache(chan, data, context, exten, priority))) {
13806       if (dp->flags & CACHE_FLAG_EXISTS)
13807          res = 1;
13808    } else {
13809       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13810    }
13811    AST_LIST_UNLOCK(&dpcache);
13812 
13813    return res;
13814 }

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

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

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

static void iax2_frame_free ( struct iax_frame fr  )  [static]

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

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

static void iax2_free_variable_datastore ( void *   )  [static]

Definition at line 1361 of file chan_iax2.c.

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

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

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

Definition at line 1734 of file chan_iax2.c.

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

Referenced by __find_callno().

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

static int iax2_getpeertrunk ( struct sockaddr_in  sin  )  [static]

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

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

static int iax2_hangup ( struct ast_channel c  )  [static]

Definition at line 5234 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_add(), ast_test_flag64, ast_verb, 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.

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

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

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

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

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

Definition at line 5396 of file chan_iax2.c.

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

Referenced by iax2_send().

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

static void iax2_lock_owner ( int  callno  )  [static]

Definition at line 1260 of file chan_iax2.c.

References ast_channel_trylock, DEADLOCK_AVOIDANCE, iaxs, and iaxsl.

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

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

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

Part of the IAX2 Switch interface.

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

13841 {
13842    int res = 0;
13843    struct iax2_dpcache *dp = NULL;
13844 #if 0
13845    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13846 #endif
13847    if ((priority != 1) && (priority != 2))
13848       return 0;
13849 
13850    AST_LIST_LOCK(&dpcache);
13851    if ((dp = find_cache(chan, data, context, exten, priority))) {
13852       if (dp->flags & CACHE_FLAG_MATCHMORE)
13853          res = 1;
13854    } else {
13855       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13856    }
13857    AST_LIST_UNLOCK(&dpcache);
13858 
13859    return res;
13860 }

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

Definition at line 12015 of file chan_iax2.c.

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

Referenced by iax2_poke_peer().

12016 {
12017    struct iax2_peer *peer = (struct iax2_peer *)data;
12018    peer->pokeexpire = -1;
12019 #ifdef SCHED_MULTITHREADED
12020    if (schedule_action(__iax2_poke_noanswer, data))
12021 #endif      
12022       __iax2_poke_noanswer(data);
12023    peer_unref(peer);
12024    return 0;
12025 }

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

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

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

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

Definition at line 12027 of file chan_iax2.c.

References iax2_poke_peer().

Referenced by load_module().

12028 {
12029    struct iax2_peer *peer = obj;
12030 
12031    iax2_poke_peer(peer, 0);
12032 
12033    return 0;
12034 }

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

Definition at line 9109 of file chan_iax2.c.

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

Referenced by __iax2_poke_noanswer(), and socket_process().

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

static int iax2_predestroy ( int  callno  )  [static]

Note:
Since this function calls iax2_queue_hangup(), the pvt struct for the given call number may disappear during its execution.

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

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

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

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

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

static void iax2_process_thread_cleanup ( void *  data  )  [static]

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

11655 {
11656    struct iax2_thread *thread = data;
11657    ast_mutex_destroy(&thread->lock);
11658    ast_cond_destroy(&thread->cond);
11659    ast_mutex_destroy(&thread->init_lock);
11660    ast_cond_destroy(&thread->init_cond);
11661    ast_free(thread);
11662    /* Ignore check_return warning from Coverity for ast_atomic_dec_and_test below */
11663    ast_atomic_dec_and_test(&iaxactivethreadcount);
11664 }

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

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

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

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

Definition at line 5373 of file chan_iax2.c.

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

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

static int iax2_queue_control_data ( int  callno,
enum ast_control_frame_type  control,
const void *  data,
size_t  datalen 
) [static]

Queue a control frame on the ast_channel owner.

This function queues a control frame on the owner of the IAX2 pvt struct that is active for the given call number.

Precondition:
Assumes lock for callno is already held.
Note:
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.

Definition at line 3007 of file chan_iax2.c.

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

Referenced by socket_process().

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

static int iax2_queue_frame ( int  callno,
struct ast_frame f 
) [static]

Queue a frame to a call's owning asterisk channel.

Precondition:
This function assumes that iaxsl[callno] is locked when called.
Note:
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.

Definition at line 2961 of file chan_iax2.c.

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

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

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

static int iax2_queue_hangup ( int  callno  )  [static]

Queue a hangup frame on the ast_channel owner.

This function queues a hangup frame on the owner of the IAX2 pvt struct that is active for the given call number.

Precondition:
Assumes lock for callno is already held.
Note:
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.

Definition at line 2984 of file chan_iax2.c.

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

Referenced by iax2_predestroy().

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

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

Definition at line 5390 of file chan_iax2.c.

References ast_debug, and ast_null_frame.

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

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

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

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

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

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

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

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

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

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

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

Definition at line 1489 of file chan_iax2.c.

References ast_sched_thread_add(), and ast_sched_thread_del.

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

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

static int iax2_send ( struct chan_iax2_pvt pvt,
struct ast_frame f,
unsigned int  ts,
int  seqno,
int  now,
int  transfer,
int  final 
) [static]

Definition at line 6371 of file chan_iax2.c.

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

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

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

Definition at line 4318 of file chan_iax2.c.

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

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

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

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

04314 {
04315    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1);
04316 }

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

Definition at line 4306 of file chan_iax2.c.

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

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

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

Definition at line 5301 of file chan_iax2.c.

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

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

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

Definition at line 5429 of file chan_iax2.c.

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

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

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

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

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

static int iax2_transmit ( struct iax_frame fr  )  [static]

Definition at line 4289 of file chan_iax2.c.

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

Referenced by iax2_send().

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

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

Definition at line 9163 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

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

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

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

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

static int iax2_vnak ( int  callno  )  [static]

Definition at line 9084 of file chan_iax2.c.

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

Referenced by socket_process(), and socket_process_meta().

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

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

Definition at line 7452 of file chan_iax2.c.

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

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

static int iax_check_version ( char *  dev  )  [static]

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

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

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

Definition at line 1120 of file chan_iax2.c.

References ast_verbose.

Referenced by load_module().

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

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

Definition at line 1126 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

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

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

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

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

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

Definition at line 1103 of file chan_iax2.c.

References debugaddr, f, and iax_showframe().

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

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

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

DO NOT hold any locks while calling iax_park

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

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

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

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

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

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

Definition at line 1957 of file chan_iax2.c.

References iax_frame::af, iax_frame::afdatalen, iax_frame::cacheable, ast_frame::datalen, DIRECTION_INGRESS, iax_frame_new(), and iax_frame_wrap().

Referenced by socket_process(), and socket_process_meta().

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

static void insert_idle_thread ( struct iax2_thread thread  )  [static]

Definition at line 1379 of file chan_iax2.c.

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

Referenced by iax2_process_thread().

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

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

Definition at line 1155 of file chan_iax2.c.

References args, and ast_verbose.

Referenced by handle_cli_iax2_set_debug_jb().

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

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

Definition at line 1131 of file chan_iax2.c.

References args, ast_log(), and LOG_ERROR.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

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

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

Definition at line 1143 of file chan_iax2.c.

References args, ast_log(), and LOG_WARNING.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

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

static int load_module ( void   )  [static]

Load IAX2 module, load configuraiton ---.

Definition at line 14721 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, peer_set_sock_cb(), peers, reload_firmware(), RQ_CHAR, RQ_UINTEGER2, sched, SENTINEL, set_config(), start_network_thread(), and timer.

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

static int load_objects ( void   )  [static]

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

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

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

Definition at line 5464 of file chan_iax2.c.

References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.

Referenced by iax2_bridge().

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

static void log_jitterstats ( unsigned short  callno  )  [static]

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

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

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

Definition at line 2052 of file chan_iax2.c.

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

Referenced by iax2_request(), and socket_process().

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

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

Definition at line 6953 of file chan_iax2.c.

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

Referenced by load_module().

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

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

callback to display iax peers in manager format

Definition at line 7016 of file chan_iax2.c.

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

Referenced by load_module().

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

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

callback to display iax peers in manager

Definition at line 6992 of file chan_iax2.c.

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

Referenced by load_module().

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

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

Definition at line 7124 of file chan_iax2.c.

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

Referenced by load_module().

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

static int match ( struct sockaddr_in *  sin,
unsigned short  callno,
unsigned short  dcallno,
const struct chan_iax2_pvt cur,
int  check_dcallno 
) [static]

Definition at line 1986 of file chan_iax2.c.

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

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

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

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

Definition at line 6207 of file chan_iax2.c.

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

Referenced by decode_frame().

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

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

Definition at line 6231 of file chan_iax2.c.

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

Referenced by encrypt_frame().

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

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

Definition at line 7797 of file chan_iax2.c.

References chan_iax2_pvt::encmethods, IAX_ENCRYPT_AES128, IAX_ENCRYPT_KEYROTATE, and chan_iax2_pvt::keyrotateid.

Referenced by authenticate_reply(), and socket_process().

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

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

Definition at line 1276 of file chan_iax2.c.

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

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

Definition at line 1311 of file chan_iax2.c.

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

Referenced by network_change_event_subscribe().

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

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

Definition at line 1298 of file chan_iax2.c.

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

Referenced by network_change_event_cb().

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

static void network_change_event_subscribe ( void   )  [static]

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

References ast_event_unsubscribe(), and network_change_event_subscription.

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

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

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

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

12196 {
12197    if (timer) {
12198       ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12199    }
12200 
12201    for (;;) {
12202       pthread_testcancel();
12203       /* Wake up once a second just in case SIGURG was sent while
12204        * we weren't in poll(), to make sure we don't hang when trying
12205        * to unload. */
12206       ast_io_wait(io, 1000);
12207    }
12208 
12209    return NULL;
12210 }

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

Definition at line 1915 of file chan_iax2.c.

References ao2_alloc, ao2_ref, AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_string_field_set, 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().

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

static void parse_dial_string ( char *  data,
struct parsed_dial_string pds 
) [static]

Parses an IAX dial string into its component parts.

Parameters:
data the string to be parsed
pds pointer to a struct parsed_dial_string to be filled in
Returns:
nothing
This function parses the string and fills the structure with pointers to its component parts. The input string will be modified.

Note:
This function supports both plaintext passwords and RSA key names; if the password string is formatted as '[keyname]', then the keyname will be placed into the key field, and the password field will be set to NULL.

The dial string format is: [username[:password]@]peer[:port][/exten[@context]][/options]

Definition at line 4986 of file chan_iax2.c.

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

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

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

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

Note:
The only member of the peer passed here guaranteed to be set is the name field

Definition at line 1655 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, and iax2_peer::name.

Referenced by load_module(), and load_objects().

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

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

Definition at line 12946 of file chan_iax2.c.

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

12947 {
12948    struct iax2_peer *peer = obj;
12949 
12950    ast_set_flag64(peer, IAX_DELME);
12951 
12952    return 0;
12953 }

static void peer_destructor ( void *  obj  )  [static]

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

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

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

Note:
The only member of the peer passed here guaranteed to be set is the name field

Definition at line 1645 of file chan_iax2.c.

References ast_str_hash(), and iax2_peer::name.

Referenced by load_module(), and load_objects().

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

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

Definition at line 1702 of file chan_iax2.c.

References ao2_ref.

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

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

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

Definition at line 14437 of file chan_iax2.c.

References iax2_peer::sockfd.

Referenced by load_module().

14438 {
14439    struct iax2_peer *peer = obj;
14440 
14441    if (peer->sockfd < 0)
14442       peer->sockfd = defaultsockfd;
14443 
14444    return 0;
14445 }

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

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

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

peer_status: Report Peer status in character string

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

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

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

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

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

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

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

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

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

Definition at line 2179 of file chan_iax2.c.

References peercnt::addr, CMP_MATCH, and CMP_STOP.

Referenced by load_objects().

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

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

Definition at line 2173 of file chan_iax2.c.

References peercnt::addr.

Referenced by load_objects().

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

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

Definition at line 2316 of file chan_iax2.c.

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

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

static void peercnt_remove ( struct peercnt peercnt  )  [static]

Definition at line 2401 of file chan_iax2.c.

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

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

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

Definition at line 2441 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

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

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

Definition at line 2427 of file chan_iax2.c.

References ao2_ref, and peercnt_remove().

Referenced by sched_delay_remove().

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

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

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

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

static void poke_all_peers ( void   )  [static]

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

13526 {
13527    struct ao2_iterator i;
13528    struct iax2_peer *peer;
13529 
13530    i = ao2_iterator_init(peers, 0);
13531    while ((peer = ao2_iterator_next(&i))) {
13532       iax2_poke_peer(peer, 0);
13533       peer_unref(peer);
13534    }
13535    ao2_iterator_destroy(&i);
13536 }

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

Definition at line 2305 of file chan_iax2.c.

References CMP_MATCH, and addr_range::delme.

Referenced by reload_config().

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

static void prune_peers ( void   )  [static]

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

13010 {
13011    struct iax2_peer *peer;
13012    struct ao2_iterator i;
13013 
13014    i = ao2_iterator_init(peers, 0);
13015    while ((peer = ao2_iterator_next(&i))) {
13016       if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
13017          unlink_peer(peer);
13018       }
13019       peer_unref(peer);
13020    }
13021    ao2_iterator_destroy(&i);
13022 }

static void prune_users ( void   )  [static]

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

12994 {
12995    struct iax2_user *user;
12996    struct ao2_iterator i;
12997 
12998    i = ao2_iterator_init(users, 0);
12999    while ((user = ao2_iterator_next(&i))) {
13000       if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
13001          ao2_unlink(users, user);
13002       }
13003       user_unref(user);
13004    }
13005    ao2_iterator_destroy(&i);
13006 }

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

Definition at line 14454 of file chan_iax2.c.

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

14455 {
14456    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14457 
14458    /* The frames_received field is used to hold whether we're matching
14459     * against a full frame or not ... */
14460 
14461    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
14462       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14463 }

static void pvt_destructor ( void *  obj  )  [static]

Definition at line 1868 of file chan_iax2.c.

References chan_iax2_pvt::addr, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, jb_frame::data, 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.

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

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

Definition at line 14447 of file chan_iax2.c.

References chan_iax2_pvt::peercallno.

14448 {
14449    const struct chan_iax2_pvt *pvt = obj;
14450 
14451    return pvt->peercallno;
14452 }

static int queue_signalling ( struct chan_iax2_pvt pvt,
struct ast_frame f 
) [static]

All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.

Definition at line 1843 of file chan_iax2.c.

References ast_calloc, AST_FRAME_IAX, AST_LIST_INSERT_TAIL, ast_malloc, ast_frame::data, ast_frame::datalen, signaling_queue_entry::f, f, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_trunk_peer::next, ast_frame::ptr, and chan_iax2_pvt::signaling_queue.

Referenced by __send_command().

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

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

Definition at line 7778 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

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

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

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

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

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

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

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

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

static void reg_source_db ( struct iax2_peer p  )  [static]

Definition at line 8666 of file chan_iax2.c.

References iax2_peer::addr, ast_db_get(), AST_DEVICE_UNKNOWN, ast_devstate_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().

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

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

Definition at line 8581 of file chan_iax2.c.

References ast_add_extension(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_strdup, ast_strlen_zero(), ext, 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().

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

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

Verify inbound registration.

Definition at line 7952 of file chan_iax2.c.

References ast_apply_ha(), ast_check_signature(), ast_clear_flag, ast_copy_string(), ast_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().

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

static int registry_authrequest ( int  callno  )  [static]

Definition at line 8888 of file chan_iax2.c.

References AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::authmethods, iax2_peer::authmethods, 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().

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

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

Definition at line 8936 of file chan_iax2.c.

References add_empty_calltoken_ie(), iax2_registry::addr, ast_copy_string(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_sockaddr_to_sin, ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax_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().

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

static char* regstate2str ( int  regstate  )  [static]

Definition at line 7061 of file chan_iax2.c.

References REG_STATE_AUTHSENT, REG_STATE_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().

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

static int reload ( void   )  [static]

Definition at line 13586 of file chan_iax2.c.

References reload_config().

13587 {
13588    return reload_config();
13589 }

static int reload_config ( void   )  [static]

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

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

static void reload_firmware ( int  unload  )  [static]

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

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

static void remove_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2140 of file chan_iax2.c.

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

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

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

static void remove_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2121 of file chan_iax2.c.

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

Referenced by complete_transfer(), and iax2_destroy().

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

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

Definition at line 2657 of file chan_iax2.c.

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

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

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

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

Definition at line 4843 of file chan_iax2.c.

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

Referenced by handle_call_token().

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

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

Definition at line 4761 of file chan_iax2.c.

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

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

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

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

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

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

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

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

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

Definition at line 2729 of file chan_iax2.c.

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

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

static int schedule_delivery ( struct iax_frame fr,
int  updatehistory,
int  fromtrunk,
unsigned int *  tsout 
) [static]

Note:
This function assumes fr->callno is locked

IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it.

Definition at line 4158 of file chan_iax2.c.

References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_channel_unlock, ast_codec_get_samples(), ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_samp2tv(), ast_sched_thread_del, ast_test_flag64, ast_tv(), ast_tvadd(), ast_tvzero(), ast_channel::bridge, calc_rxstamp(), iax_frame::callno, ast_frame_subclass::codec, jb_frame::data, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_lock_owner(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, 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().

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

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

Definition at line 1806 of file chan_iax2.c.

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

Referenced by iax2_hangup().

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

static int send_apathetic_reply ( unsigned short  callno,
unsigned short  dcallno,
struct sockaddr_in *  sin,
int  command,
int  ts,
unsigned char  seqno,
int  sockfd,
struct iax_ie_data ied 
) [static]

Definition at line 4721 of file chan_iax2.c.

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

Referenced by handle_call_token(), and socket_process().

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

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

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

07501 {
07502    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07503 }

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

Note:
Since this function calls iax2_predestroy() -> iax2_queue_hangup(), the pvt struct for the given call number may disappear during its execution.

Definition at line 7519 of file chan_iax2.c.

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

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

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

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

Definition at line 7529 of file chan_iax2.c.

References __send_command().

Referenced by iax2_vnak(), and socket_process().

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

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

Definition at line 7505 of file chan_iax2.c.

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

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

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

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

Definition at line 7534 of file chan_iax2.c.

References __send_command().

Referenced by socket_process(), and try_transfer().

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

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

Definition at line 1592 of file chan_iax2.c.

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

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

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

static int send_packet ( struct iax_frame f  )  [static]

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

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

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

Definition at line 1525 of file chan_iax2.c.

References __send_ping(), ast_mutex_lock, ast_mutex_unlock, 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().

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

static void send_signaling ( struct chan_iax2_pvt pvt  )  [static]

This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.

Definition at line 1830 of file chan_iax2.c.

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

Referenced by socket_process().

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

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

Definition at line 9120 of file chan_iax2.c.

References iax2_trunk_peer::addr, iax_frame::afdata, ast_debug, ast_inet_ntoa(), ast_test_flag64, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, 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().

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

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

Load configuration.

Definition at line 13041 of file chan_iax2.c.

References add_calltoken_ignore(), ao2_link, ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_clear_flag64, ast_config_destroy(), ast_config_load, ast_context_find_or_create(), ast_copy_string(), ast_false(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_test_flag64, ast_timer_set_rate(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, build_callno_limits(), build_peer(), build_user(), capability, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), 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(), timer, user, user_unref(), users, and ast_variable::value.

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

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

static void set_config_destroy ( void   )  [static]

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

References ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_mutex_lock, ast_mutex_unlock, ast_set_hangupsource(), ast_strdupa, ast_channel::hangupcause, iax2_lock_owner(), iaxs, iaxsl, ast_channel::name, name, and chan_iax2_pvt::owner.

Referenced by socket_process().

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

static void set_peercnt_limit ( struct peercnt peercnt  )  [static]

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

02266 {
02267    uint16_t limit = global_maxcallno;
02268    struct addr_range *addr_range;
02269    struct sockaddr_in sin = {
02270       .sin_addr.s_addr = peercnt->addr,
02271    };
02272 
02273 
02274    if (peercnt->reg && peercnt->limit) {
02275       return; /* this peercnt has a custom limit set by a registration */
02276    }
02277 
02278    if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02279       limit = addr_range->limit;
02280       ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02281       ao2_ref(addr_range, -1);
02282    }
02283 
02284    peercnt->limit = limit;
02285 }

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

Definition at line 2291 of file chan_iax2.c.

References ast_debug, and set_peercnt_limit().

Referenced by reload_config().

02292 {
02293    struct peercnt *peercnt = obj;
02294 
02295    set_peercnt_limit(peercnt);
02296    ast_debug(1, "Reset limits for peercnts table\n");
02297 
02298    return 0;
02299 }

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

Definition at line 1052 of file chan_iax2.c.

References ast_cond_signal, ast_mutex_lock, and ast_mutex_unlock.

Referenced by __schedule_action(), cleanup_thread_list(), iax2_process_thread(), and socket_read().

01053 {
01054    ast_mutex_lock(lock);
01055    ast_cond_signal(cond);
01056    ast_mutex_unlock(lock);
01057 }

static int socket_process ( struct iax2_thread thread  )  [static]

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

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

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

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

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

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

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

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

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

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

static int start_network_thread ( void   )  [static]

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

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

static void stop_stuff ( int  callno  )  [static]

Definition at line 8988 of file chan_iax2.c.

References iax2_destroy_helper(), and iaxs.

Referenced by socket_process().

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

static void store_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2130 of file chan_iax2.c.

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

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

02131 {
02132    if (!pvt->peercallno) {
02133       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02134       return;
02135    }
02136 
02137    ao2_link(iax_peercallno_pvts, pvt);
02138 }

static void store_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2111 of file chan_iax2.c.

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

Referenced by try_transfer().

02112 {
02113    if (!pvt->transfercallno) {
02114       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02115       return;
02116    }
02117 
02118    ao2_link(iax_transfercallno_pvts, pvt);
02119 }

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

Definition at line 9171 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_debug, ast_free, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_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().

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

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

Definition at line 14472 of file chan_iax2.c.

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

Referenced by load_objects().

14473 {
14474    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14475 
14476    /* The frames_received field is used to hold whether we're matching
14477     * against a full frame or not ... */
14478 
14479    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14480       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14481 }

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

Definition at line 14465 of file chan_iax2.c.

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

14466 {
14467    const struct chan_iax2_pvt *pvt = obj;
14468 
14469    return pvt->transfercallno;
14470 }

static int transmit_frame ( void *  data  )  [static]

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

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

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

Definition at line 3325 of file chan_iax2.c.

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

Referenced by send_trunk().

03326 {
03327    int res;
03328    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03329                sizeof(*sin));
03330    if (res < 0) {
03331       ast_debug(1, "Received error: %s\n", strerror(errno));
03332       handle_error();
03333    } else
03334       res = 0;
03335    return res;
03336 }

static int try_firmware ( char *  s  )  [static]

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

03028 {
03029    struct stat stbuf;
03030    struct iax_firmware *cur = NULL;
03031    int ifd, fd, res, len, chunk;
03032    struct ast_iax2_firmware_header *fwh, fwh2;
03033    struct MD5Context md5;
03034    unsigned char sum[16], buf[1024];
03035    char *s2, *last;
03036 
03037    if (!(s2 = alloca(strlen(s) + 100))) {
03038       ast_log(LOG_WARNING, "Alloca failed!\n");
03039       return -1;
03040    }
03041 
03042    last = strrchr(s, '/');
03043    if (last)
03044       last++;
03045    else
03046       last = s;
03047 
03048    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
03049 
03050    if ((res = stat(s, &stbuf) < 0)) {
03051       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03052       return -1;
03053    }
03054 
03055    /* Make sure it's not a directory */
03056    if (S_ISDIR(stbuf.st_mode))
03057       return -1;
03058    ifd = open(s, O_RDONLY);
03059    if (ifd < 0) {
03060       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03061       return -1;
03062    }
03063    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03064    if (fd < 0) {
03065       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03066       close(ifd);
03067       return -1;
03068    }
03069    /* Unlink our newly created file */
03070    unlink(s2);
03071    
03072    /* Now copy the firmware into it */
03073    len = stbuf.st_size;
03074    while(len) {
03075       chunk = len;
03076       if (chunk > sizeof(buf))
03077          chunk = sizeof(buf);
03078       res = read(ifd, buf, chunk);
03079       if (res != chunk) {
03080          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03081          close(ifd);
03082          close(fd);
03083          return -1;
03084       }
03085       res = write(fd, buf, chunk);
03086       if (res != chunk) {
03087          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03088          close(ifd);
03089          close(fd);
03090          return -1;
03091       }
03092       len -= chunk;
03093    }
03094    close(ifd);
03095    /* Return to the beginning */
03096    lseek(fd, 0, SEEK_SET);
03097    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03098       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03099       close(fd);
03100       return -1;
03101    }
03102    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03103       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03104       close(fd);
03105       return -1;
03106    }
03107    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03108       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03109       close(fd);
03110       return -1;
03111    }
03112    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03113       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03114       close(fd);
03115       return -1;
03116    }
03117    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
03118    if (fwh == MAP_FAILED) {
03119       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03120       close(fd);
03121       return -1;
03122    }
03123    MD5Init(&md5);
03124    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03125    MD5Final(sum, &md5);
03126    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03127       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03128       munmap((void*)fwh, stbuf.st_size);
03129       close(fd);
03130       return -1;
03131    }
03132 
03133    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03134       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03135          /* Found a candidate */
03136          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03137             /* The version we have on loaded is older, load this one instead */
03138             break;
03139          /* This version is no newer than what we have.  Don't worry about it.
03140             We'll consider it a proper load anyhow though */
03141          munmap((void*)fwh, stbuf.st_size);
03142          close(fd);
03143          return 0;
03144       }
03145    }
03146    
03147    if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03148       cur->fd = -1;
03149       AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03150    }
03151    
03152    if (cur) {
03153       if (cur->fwh)
03154          munmap((void*)cur->fwh, cur->mmaplen);
03155       if (cur->fd > -1)
03156          close(cur->fd);
03157       cur->fwh = fwh;
03158       cur->fd = fd;
03159       cur->mmaplen = stbuf.st_size;
03160       cur->dead = 0;
03161    }
03162    
03163    return 0;
03164 }

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

Definition at line 8306 of file chan_iax2.c.

References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_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().

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

static format_t uncompress_subclass ( unsigned char  csub  )  [static]

Definition at line 1628 of file chan_iax2.c.

References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

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

01629 {
01630    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01631    if (csub & IAX_FLAG_SC_LOG) {
01632       /* special case for 'compressed' -1 */
01633       if (csub == 0xff)
01634          return -1;
01635       else
01636          return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01637    }
01638    else
01639       return csub;
01640 }

static void unlink_peer ( struct iax2_peer peer  )  [static]

Definition at line 8600 of file chan_iax2.c.

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

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

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

static int unload_module ( void   )  [static]

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

References ast_mutex_unlock, and iaxsl.

Referenced by iax2_bridge().

05473 {
05474    ast_mutex_unlock(&iaxsl[callno1]);
05475    ast_mutex_unlock(&iaxsl[callno0]);
05476 }

static void unwrap_timestamp ( struct iax_frame fr  )  [static]

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

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

static void update_jbsched ( struct chan_iax2_pvt pvt  )  [static]

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

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

static int update_packet ( struct iax_frame f  )  [static]

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

03464 {
03465    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
03466    struct ast_iax2_full_hdr *fh = f->data;
03467    struct ast_frame af;
03468 
03469    /* if frame is encrypted. decrypt before updating it. */
03470    if (f->encmethods) {
03471       decode_frame(&f->mydcx, fh, &af, &f->datalen);
03472    }
03473    /* Mark this as a retransmission */
03474    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03475    /* Update iseqno */
03476    f->iseqno = iaxs[f->callno]->iseqno;
03477    fh->iseqno = f->iseqno;
03478 
03479    /* Now re-encrypt the frame */
03480    if (f->encmethods) {
03481    /* since this is a retransmit frame, create a new random padding
03482     * before re-encrypting. */
03483       build_rand_pad(f->semirand, sizeof(f->semirand));
03484       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03485    }
03486    return 0;
03487 }

static int update_registry ( struct sockaddr_in *  sin,
int  callno,
char *  devtype,
int  fd,
unsigned short  refresh 
) [static]

Precondition:
iaxsl[callno] is locked
Note:
Since this function calls send_command_final(), the pvt struct for the given call number may disappear while executing this function.

Definition at line 8720 of file chan_iax2.c.

References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_devstate_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().

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

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

Note:
The only member of the user passed here guaranteed to be set is the name field

Definition at line 1675 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, and user.

Referenced by load_objects().

01676 {
01677    struct iax2_user *user = obj, *user2 = arg;
01678 
01679    return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01680 }

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

Definition at line 12955 of file chan_iax2.c.

References ast_set_flag64, IAX_DELME, and user.

Referenced by delete_users().

12956 {
12957    struct iax2_user *user = obj;
12958 
12959    ast_set_flag64(user, IAX_DELME);
12960 
12961    return 0;
12962 }

static void user_destructor ( void *  obj  )  [static]

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

12681 {
12682    struct iax2_user *user = obj;
12683 
12684    ast_free_ha(user->ha);
12685    free_context(user->contexts);
12686    if(user->vars) {
12687       ast_variables_destroy(user->vars);
12688       user->vars = NULL;
12689    }
12690    ast_string_field_free_memory(user);
12691 }

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

Note:
The only member of the user passed here guaranteed to be set is the name field

Definition at line 1665 of file chan_iax2.c.

References ast_str_hash(), and user.

Referenced by load_objects().

01666 {
01667    const struct iax2_user *user = obj;
01668 
01669    return ast_str_hash(user->name);
01670 }

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

Definition at line 1722 of file chan_iax2.c.

References ao2_ref, and user.

01723 {
01724    ao2_ref(user, +1);
01725    return user;
01726 }

static struct iax2_user* user_unref ( struct iax2_user user  )  [inline, static]

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

01729 {
01730    ao2_ref(user, -1);
01731    return NULL;
01732 }

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

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

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

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

Definition at line 9089 of file chan_iax2.c.

References AST_LIST_TRAVERSE, f, frame_queue, iax_frame::list, and send_packet().

Referenced by socket_process().

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

static int wait_for_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Note:
expects the pvt to be locked

Definition at line 5282 of file chan_iax2.c.

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

Referenced by iax2_indicate(), and iax2_setoption().

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


Variable Documentation

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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", } [static]

Definition at line 14844 of file chan_iax2.c.

char accountcode[AST_MAX_ACCOUNT_CODE] [static]

Definition at line 383 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(), dial_exec_full(), 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 387 of file chan_iax2.c.

int amaflags = 0 [static]

Definition at line 386 of file chan_iax2.c.

Referenced by ast_async_goto().

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 14844 of file chan_iax2.c.

int authdebug = 1 [static]

Definition at line 294 of file chan_iax2.c.

int autokill = 0 [static]

Definition at line 295 of file chan_iax2.c.

struct ao2_container* callno_limits [static]

Table containing custom callno limit rules for a range of ip addresses.

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

const unsigned int CALLNO_POOL_BUCKETS = 2699 [static]

Definition at line 854 of file chan_iax2.c.

struct ao2_container* callno_pool_trunk [static]

table of available trunk call numbers

Definition at line 852 of file chan_iax2.c.

struct ao2_container* calltoken_ignores [static]

Table containing ip addresses not requiring calltoken validation

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

Referenced by __unload_module(), and load_module().

unsigned int cos

Definition at line 305 of file chan_iax2.c.

struct sockaddr_in debugaddr [static]

Definition at line 1101 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_debug(), iax_outputframe(), 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 899 of file chan_iax2.c.

uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static]

Definition at line 901 of file chan_iax2.c.

char default_parkinglot[AST_MAX_CONTEXT] [static]

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

int delayreject = 0 [static]

Definition at line 388 of file chan_iax2.c.

struct iax_frame* first

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

uint16_t global_maxcallno [static]

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

int global_rtautoclear = 120 [static]

Definition at line 439 of file chan_iax2.c.

struct ast_flags64 globalflags = { 0 } [static]

Definition at line 391 of file chan_iax2.c.

format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static]

Definition at line 369 of file chan_iax2.c.

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

Referenced by load_module().

int iax2_encryption = 0 [static]

Definition at line 389 of file chan_iax2.c.

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

Definition at line 319 of file chan_iax2.c.

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

struct ast_switch iax2_switch [static]

Definition at line 14062 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

struct ast_channel_tech iax2_tech [static]

Definition at line 1216 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 1331 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 1078 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 1094 of file chan_iax2.c.

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_transfercallno(), and store_by_transfercallno().

int iaxactivethreadcount = 0 [static]

Definition at line 638 of file chan_iax2.c.

Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().

int iaxcompat = 0 [static]

Definition at line 296 of file chan_iax2.c.

int iaxdebug = 0 [static]

Definition at line 371 of file chan_iax2.c.

int iaxdefaultdpcache = 10 * 60 [static]

Definition at line 299 of file chan_iax2.c.

int iaxdefaulttimeout = 5 [static]

Definition at line 301 of file chan_iax2.c.

int iaxdynamicthreadcount = 0 [static]

Definition at line 636 of file chan_iax2.c.

Referenced by find_idle_thread().

int iaxdynamicthreadnum = 0 [static]

Definition at line 637 of file chan_iax2.c.

Referenced by find_idle_thread().

int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static]

Definition at line 635 of file chan_iax2.c.

Referenced by find_idle_thread(), and set_config().

struct ast_custom_function iaxpeer_function [static]

Initial value:

 {
   .name = "IAXPEER",
   .read = function_iaxpeer,
}

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

Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __find_callno(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), acf_channel_read(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), handle_cli_iax2_show_channels(), iax2_ack_registry(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_lock_owner(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queryoption(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_setoption(), iax2_start_transfer(), iax2_vnak(), iax2_write(), load_module(), log_jitterstats(), make_trunk(), register_verify(), registry_authrequest(), registry_rerequest(), resend_with_token(), save_osptoken(), save_rr(), schedule_delivery(), scheduled_destroy(), send_command_final(), send_command_locked(), send_lagrq(), send_packet(), send_ping(), set_hangup_source_and_cause(), socket_process(), socket_process_meta(), stop_stuff(), transmit_frame(), unwrap_timestamp(), update_packet(), update_registry(), and wait_for_peercallno().

ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static]

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 1087 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(), set_hangup_source_and_cause(), socket_process(), socket_process_meta(), transmit_frame(), unlock_both(), update_registry(), and wait_for_peercallno().

int iaxthreadcount = DEFAULT_THREAD_COUNT [static]

Definition at line 634 of file chan_iax2.c.

Referenced by handle_cli_iax2_show_threads(), set_config(), and start_network_thread().

int iaxtrunkdebug = 0 [static]

Definition at line 373 of file chan_iax2.c.

struct ast_custom_function iaxvar_function [static]

Initial value:

 {
   .name = "IAXVAR",
   .read = acf_iaxvar_read,
   .write = acf_iaxvar_write,
}

Definition at line 9884 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct io_context* io [static]

Definition at line 364 of file chan_iax2.c.

int jittertargetextra = 40 [static]

Definition at line 287 of file chan_iax2.c.

int lagrq_time = 10 [static]

Definition at line 283 of file chan_iax2.c.

char language[MAX_LANGUAGE] = "" [static]

Definition at line 274 of file chan_iax2.c.

struct iax_frame* last

Definition at line 865 of file chan_iax2.c.

int last_authmethod = 0 [static]

Definition at line 297 of file chan_iax2.c.

const time_t MAX_CALLTOKEN_DELAY = 10 [static]

Definition at line 871 of file chan_iax2.c.

int max_reg_expire [static]

Definition at line 309 of file chan_iax2.c.

int max_retries = 4 [static]

Definition at line 281 of file chan_iax2.c.

int maxauthreq = 3 [static]

Definition at line 280 of file chan_iax2.c.

int maxjitterbuffer = 1000 [static]

Definition at line 284 of file chan_iax2.c.

int maxjitterinterps = 10 [static]

Definition at line 286 of file chan_iax2.c.

int min_reg_expire [static]

Definition at line 308 of file chan_iax2.c.

char mohinterpret[MAX_MUSICCLASS] [static]

Definition at line 384 of file chan_iax2.c.

char mohsuggest[MAX_MUSICCLASS] [static]

Definition at line 385 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 315 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 393 of file chan_iax2.c.

int network_change_event_sched_id = -1 [static]

Definition at line 278 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 277 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 316 of file chan_iax2.c.

Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().

char* papp = "IAX2Provision" [static]

Definition at line 11919 of file chan_iax2.c.

struct ao2_container* peercnts [static]

Table containing peercnt objects for every ip address consuming a callno

Definition at line 891 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 885 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 14705 of file chan_iax2.c.

int ping_time = 21 [static]

Definition at line 282 of file chan_iax2.c.

struct ast_codec_pref prefs [static]

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

char regcontext[AST_MAX_CONTEXT] = "" [static]

Definition at line 275 of file chan_iax2.c.

int resyncthreshold = 1000 [static]

Definition at line 285 of file chan_iax2.c.

struct ast_sched_thread* sched [static]

Definition at line 365 of file chan_iax2.c.

int srvlookup = 0 [static]

Definition at line 311 of file chan_iax2.c.

Referenced by build_peer().

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

Definition at line 260 of file chan_iax2.c.

int test_losspct = 0 [static]

Definition at line 375 of file chan_iax2.c.

struct ast_timer* timer [static]

Definition at line 313 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(), set_config(), 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 304 of file chan_iax2.c.

uint16_t total_nonval_callno_used = 0 [static]

Definition at line 908 of file chan_iax2.c.

struct ast_taskprocessor* transmit_processor [static]

Definition at line 867 of file chan_iax2.c.

int trunk_maxmtu [static]

Definition at line 268 of file chan_iax2.c.

int trunk_nmaxmtu [static]

Trunk MTU statistics

Definition at line 268 of file chan_iax2.c.

int trunk_timed [static]

Definition at line 268 of file chan_iax2.c.

int trunk_untimed [static]

Definition at line 268 of file chan_iax2.c.

int trunkfreq = 20 [static]

Definition at line 291 of file chan_iax2.c.

int trunkmaxsize = MAX_TRUNKDATA [static]

Definition at line 292 of file chan_iax2.c.

struct ao2_container* users [static]

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


Generated on Mon Oct 8 12:39:14 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7