Wed Oct 28 13:32:02 2009

Asterisk developer's documentation


chan_iax2.c File Reference

Implementation of Inter-Asterisk eXchange Version 2. More...

#include "asterisk.h"
#include <sys/mman.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <signal.h>
#include <strings.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/md5.h"
#include "asterisk/cdr.h"
#include "asterisk/crypto.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/localtime.h"
#include "asterisk/aes.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/event.h"
#include "asterisk/astobj2.h"
#include "asterisk/timing.h"
#include "asterisk/taskprocessor.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 DEBUG_SCHED_MULTITHREAD
#define DEBUG_SUPPORT
#define DEFAULT_CONTEXT   "default"
#define DEFAULT_DROP   3
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAX_THREAD_COUNT   100
#define DEFAULT_MAXMS   2000
#define DEFAULT_RETRY_TIME   1000
#define DEFAULT_THREAD_COUNT   10
#define DEFAULT_TRUNKDATA   640 * 10
#define FORMAT   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n"
#define FORMAT   "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
#define FORMAT   "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
#define FORMAT   "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
#define FORMAT2   "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
#define FORMAT2   "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
#define FORMAT2   "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
#define FORMAT2   "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
#define FORMATB   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
#define GAMMA   (0.01)
#define IAX2_TRUNK_PREFACE   (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
#define IAX_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   ARRAY_LEN(iaxs) / 2
#define TS_GAP_FOR_JB_RESYNC   5000

Enumerations

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

Functions

static void __attempt_transmit (const void *data)
static void __auth_reject (const void *nothing)
static void __auto_congest (const void *nothing)
static void __auto_hangup (const void *nothing)
static int __do_deliver (void *data)
static void __expire_registry (const void *data)
static int __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
static void __get_from_jb (const void *p)
static void __iax2_do_register_s (const void *data)
static void __iax2_poke_noanswer (const void *data)
static void __iax2_poke_peer_s (const void *data)
static int __iax2_show_peers (int manager, int fd, struct mansession *s, 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_channel_write (struct ast_channel *chan, const char *function, char *data, const char *value)
static int acf_iaxvar_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int acf_iaxvar_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
static int add_calltoken_ignore (const char *addr)
static void add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
static int addr_range_cmp_cb (void *obj, void *arg, int flags)
static int addr_range_delme_cb (void *obj, void *arg, int flags)
static int addr_range_hash_cb (const void *obj, const int flags)
static int addr_range_match_address_cb (void *obj, void *arg, int flags)
static int apply_context (struct iax2_context *con, const char *context)
static int ast_cli_netstats (struct mansession *s, int fd, int limit_fmt)
static struct ast_channelast_iax2_new (int callno, int state, int capability, 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 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 (int subclass)
static void construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
static int create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
static int create_callno_pools (void)
static int decode_frame (ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static int decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static void defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here)
 Queue the last read full frame for processing by a certain thread.
static void delete_users (void)
static void destroy_firmware (struct iax_firmware *cur)
static void dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
static void * dp_lookup_thread (void *data)
static 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 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_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen)
 Queue a control frame on the ast_channel owner.
static int iax2_queue_frame (int callno, struct ast_frame *f)
 Queue a frame to a call's owning asterisk channel.
static int iax2_queue_hangup (int callno)
 Queue a hangup frame on the ast_channel owner.
static struct ast_frameiax2_read (struct ast_channel *c)
static int iax2_register (const char *value, int lineno)
static struct ast_channeliax2_request (const char *type, int format, 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)
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_thread (void *ignore)
static struct chan_iax2_pvtnew_iax (struct sockaddr_in *sin, const char *host)
static void parse_dial_string (char *data, struct parsed_dial_string *pds)
 Parses an IAX dial string into its component parts.
static int peer_cmp_cb (void *obj, void *arg, int flags)
static int peer_delme_cb (void *obj, void *arg, int flags)
static void peer_destructor (void *obj)
static int peer_hash_cb (const void *obj, const int flags)
static struct iax2_peerpeer_ref (struct iax2_peer *peer)
static int peer_set_sock_cb (void *obj, void *arg, int flags)
static int peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr)
 Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found.
static int peer_status (struct iax2_peer *peer, char *status, int statuslen)
 peer_status: Report Peer status in character string
static struct iax2_peerpeer_unref (struct iax2_peer *peer)
static int peercnt_add (struct sockaddr_in *sin)
static int peercnt_cmp_cb (void *obj, void *arg, int flags)
static int peercnt_hash_cb (const void *obj, const int flags)
static void peercnt_modify (unsigned char reg, uint16_t limit, struct sockaddr_in *sin)
static void peercnt_remove (struct peercnt *peercnt)
static int peercnt_remove_by_addr (struct sockaddr_in *sin)
static int peercnt_remove_cb (const void *obj)
static void poke_all_peers (void)
static int prune_addr_range_cb (void *obj, void *arg, int flags)
static void prune_peers (void)
static void prune_users (void)
static int pvt_cmp_cb (void *obj, void *arg, int flags)
static void pvt_destructor (void *obj)
static int pvt_hash_cb (const void *obj, const int flags)
static int queue_signalling (struct chan_iax2_pvt *pvt, struct ast_frame *f)
 All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.
static int raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
static struct iax2_peerrealtime_peer (const char *peername, struct sockaddr_in *sin)
static void realtime_update_peer (const char *peername, struct sockaddr_in *sin, time_t regtime)
static struct iax2_userrealtime_user (const char *username, struct sockaddr_in *sin)
static void reg_source_db (struct iax2_peer *p)
static void register_peer_exten (struct iax2_peer *peer, int onoff)
static int register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies)
 Verify inbound registration.
static int registry_authrequest (int callno)
static int registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin)
static char * regstate2str (int regstate)
static int reload (void)
static int reload_config (void)
static void reload_firmware (int unload)
static void remove_by_peercallno (struct chan_iax2_pvt *pvt)
static void remove_by_transfercallno (struct chan_iax2_pvt *pvt)
static int replace_callno (const void *obj)
static void requirecalltoken_mark_auto (const char *name, int subclass)
static void resend_with_token (int callno, struct iax_frame *f, const char *newtoken)
static void save_osptoken (struct iax_frame *fr, struct iax_ies *ies)
static void save_rr (struct iax_frame *fr, struct iax_ies *ies)
static void sched_delay_remove (struct sockaddr_in *sin, struct callno_entry *callno_entry)
static 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 int uncompress_subclass (unsigned char csub)
static void unlink_peer (struct iax2_peer *peer)
static int unload_module (void)
static void unlock_both (unsigned short callno0, unsigned short callno1)
static void unwrap_timestamp (struct iax_frame *fr)
static void update_jbsched (struct chan_iax2_pvt *pvt)
static void update_max_nontrunk (void)
static void update_max_trunk (void)
static int update_packet (struct iax_frame *f)
static int update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
static int user_cmp_cb (void *obj, void *arg, int flags)
static int user_delme_cb (void *obj, void *arg, int flags)
static void user_destructor (void *obj)
static int user_hash_cb (const void *obj, const int flags)
static struct iax2_useruser_ref (struct iax2_user *user)
static struct iax2_useruser_unref (struct iax2_user *user)
static void vnak_retransmit (int callno, int last)
static int wait_for_peercallno (struct chan_iax2_pvt *pvt)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, }
static char accountcode [AST_MAX_ACCOUNT_CODE]
static int adsi = 0
static int amaflags = 0
static struct ast_module_infoast_module_info = &__mod_info
static int authdebug = 1
static int autokill = 0
static struct ao2_containercallno_limits
static struct ao2_containercallno_pool
static const unsigned int CALLNO_POOL_BUCKETS = 2699
static struct ao2_containercallno_pool_trunk
static struct ao2_containercalltoken_ignores
static struct ast_cli_entry cli_iax2 []
static struct sockaddr_in debugaddr
static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048
static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192
static char default_parkinglot [AST_MAX_CONTEXT]
static int defaultsockfd = -1
static int delayreject = 0
struct {
   struct iax_frame *   first
   struct iax_frame *   last
frame_queue [IAX_MAX_CALLS]
 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 int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH
static int iax2_encryption = 0
static int(* iax2_regfunk )(const char *username, int onoff) = NULL
static struct ast_switch iax2_switch
static struct ast_channel_tech iax2_tech
static struct ast_datastore_info iax2_variable_datastore_info
static struct ao2_containeriax_peercallno_pvts
 Another container of iax2_pvt structures.
static struct ao2_containeriax_transfercallno_pvts
 Another container of iax2_pvt structures.
static int iaxactivethreadcount = 0
static int iaxcompat = 0
static int iaxdebug = 0
static int iaxdefaultdpcache = 10 * 60
static int iaxdefaulttimeout = 5
static int iaxdynamicthreadcount = 0
static int iaxdynamicthreadnum = 0
static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT
static struct ast_custom_function iaxpeer_function
static struct chan_iax2_pvtiaxs [IAX_MAX_CALLS]
 an array of iax2 pvt structures
static ast_mutex_t iaxsl [ARRAY_LEN(iaxs)]
 chan_iax2_pvt structure locks
static int iaxthreadcount = DEFAULT_THREAD_COUNT
static int iaxtrunkdebug = 0
static struct ast_custom_function iaxvar_function
static struct io_contextio
static int jittertargetextra = 40
static int lagrq_time = 10
static char language [MAX_LANGUAGE] = ""
static int last_authmethod = 0
static const time_t MAX_CALLTOKEN_DELAY = 10
static int max_reg_expire
static int max_retries = 4
static int maxauthreq = 3
static int maxjitterbuffer = 1000
static int maxjitterinterps = 10
static int maxnontrunkcall = 1
static int maxtrunkcall = TRUNK_CALL_START
static int min_reg_expire
static char mohinterpret [MAX_MUSICCLASS]
static char mohsuggest [MAX_MUSICCLASS]
static struct ast_netsock_listnetsock
static pthread_t netthreadid = AST_PTHREADT_NULL
static struct ast_netsock_listoutsock
static char * papp = "IAX2Provision"
static struct ao2_containerpeercnts
static struct ao2_containerpeers
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


Detailed Description

Implementation of Inter-Asterisk eXchange Version 2.

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

Definition in file chan_iax2.c.


Define Documentation

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

Referenced by ast_cli_netstats().

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

Referenced by ast_cli_netstats().

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

Definition at line 235 of file chan_iax2.c.

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

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

Referenced by handle_call_token().

#define CALLTOKEN_IE_FORMAT   "%u?%s"

Referenced by handle_call_token().

#define DEBUG_SCHED_MULTITHREAD

Definition at line 227 of file chan_iax2.c.

#define DEBUG_SUPPORT

Definition at line 243 of file chan_iax2.c.

#define DEFAULT_CONTEXT   "default"

Definition at line 262 of file chan_iax2.c.

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

#define DEFAULT_DROP   3

Definition at line 241 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

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

Referenced by build_peer().

#define DEFAULT_MAX_THREAD_COUNT   100

Definition at line 238 of file chan_iax2.c.

#define DEFAULT_MAXMS   2000

Definition at line 331 of file chan_iax2.c.

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

#define DEFAULT_RETRY_TIME   1000

Definition at line 239 of file chan_iax2.c.

Referenced by __find_callno(), and complete_transfer().

#define DEFAULT_THREAD_COUNT   10

Definition at line 237 of file chan_iax2.c.

#define DEFAULT_TRUNKDATA   640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 610 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

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

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

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

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

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

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

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

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

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

#define GAMMA   (0.01)

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

Referenced by iax2_trunk_queue().

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

Allow the FWDOWNL command?

Definition at line 419 of file chan_iax2.c.

Referenced by set_config(), and socket_process().

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

Already disconnected

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

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

#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF

Definition at line 311 of file chan_iax2.c.

Referenced by cache_get_callno_locked(), and set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH

Value:

Definition at line 322 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWFREE

Value:

Definition at line 327 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH

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

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

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

Force old behaviour by turning off prefs

Definition at line 408 of file chan_iax2.c.

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

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

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

Definition at line 407 of file chan_iax2.c.

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

#define IAX_DEBUGDIGEST ( msg,
key   ) 

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

Referenced by socket_process().

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

Needs to be deleted

Definition at line 394 of file chan_iax2.c.

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

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

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

Whether we should assume encrypted tx/rx

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

Referenced by __find_callno(), authenticate_reply(), authenticate_verify(), build_peer(), build_user(), check_access(), create_addr(), iax2_call(), 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 413 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 393 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 420 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 406 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 417 of file chan_iax2.c.

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

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

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

This is a provisioning request

Definition at line 403 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 404 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 422 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 412 of file chan_iax2.c.

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

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

let realtime stay till your reload

Definition at line 410 of file chan_iax2.c.

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

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

When using realtime, ignore registration expiration

Definition at line 414 of file chan_iax2.c.

Referenced by realtime_peer(), and set_config().

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

Save Systname on Realtime Updates

Definition at line 401 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 411 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 400 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 421 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 424 of file chan_iax2.c.

Referenced by check_access(), and set_config().

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

Temporary (realtime)

Definition at line 395 of file chan_iax2.c.

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

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

When doing IAX2 transfers, transfer media only

Definition at line 416 of file chan_iax2.c.

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

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

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

Send trunk timestamps

Definition at line 415 of file chan_iax2.c.

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

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

#define MARK_IAX_SUBCLASS_TX   0x8000

Definition at line 618 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 607 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 869 of file chan_iax2.c.

Referenced by load_objects().

#define MAX_RETRY_TIME   10000

Definition at line 605 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 612 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 257 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 278 of file chan_iax2.c.

Referenced by set_config(), and set_config_destroy().

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

Definition at line 873 of file chan_iax2.c.

Referenced by load_module(), and load_objects().

#define MEMORY_SIZE   100

Definition at line 240 of file chan_iax2.c.

#define MIN_JITTER_BUFFER   10

Definition at line 608 of file chan_iax2.c.

#define MIN_RETRY_TIME   100

Definition at line 604 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME   60

Definition at line 245 of file chan_iax2.c.

Referenced by make_trunk(), and sched_delay_remove().

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

#define SCHED_MULTITHREADED

Definition at line 223 of file chan_iax2.c.

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

#define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2

#define TS_GAP_FOR_JB_RESYNC   5000

Definition at line 615 of file chan_iax2.c.


Enumeration Type Documentation

anonymous enum

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

Definition at line 929 of file chan_iax2.c.

00929      {
00930    /*! Extension exists */
00931    CACHE_FLAG_EXISTS      = (1 << 0),
00932    /*! Extension is nonexistent */
00933    CACHE_FLAG_NONEXISTENT = (1 << 1),
00934    /*! Extension can exist */
00935    CACHE_FLAG_CANEXIST    = (1 << 2),
00936    /*! Waiting to hear back response */
00937    CACHE_FLAG_PENDING     = (1 << 3),
00938    /*! Timed out */
00939    CACHE_FLAG_TIMEOUT     = (1 << 4),
00940    /*! Request transmitted */
00941    CACHE_FLAG_TRANSMITTED = (1 << 5),
00942    /*! Timeout */
00943    CACHE_FLAG_UNKNOWN     = (1 << 6),
00944    /*! Matchmore */
00945    CACHE_FLAG_MATCHMORE   = (1 << 7),
00946 };

anonymous enum

Enumerator:
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 1866 of file chan_iax2.c.

01866      {
01867    /* do not allow a new call number, only search ones in use for match */
01868    NEW_PREVENT = 0,
01869    /* search for match first, then allow a new one to be allocated */
01870    NEW_ALLOW = 1,
01871    /* do not search for match, force a new call number */
01872    NEW_FORCE = 2,
01873    /* do not search for match, force a new call number.  Signifies call number
01874     * has been calltoken validated */
01875    NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01876 };

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

00432                          {
00433    /*! \brief Default calltoken required unless the ip is in the ignorelist */
00434    CALLTOKEN_DEFAULT = 0,
00435    /*! \brief Require call token validation. */
00436    CALLTOKEN_YES = 1,
00437    /*! \brief Require call token validation after a successful registration
00438     *         using call token validation occurs. */
00439    CALLTOKEN_AUTO = 2,
00440    /*! \brief Do not require call token validation. */
00441    CALLTOKEN_NO = 3,
00442 };

enum iax2_state

Enumerator:
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 381 of file chan_iax2.c.

00381                 {
00382    IAX_STATE_STARTED =        (1 << 0),
00383    IAX_STATE_AUTHENTICATED =  (1 << 1),
00384    IAX_STATE_TBD =            (1 << 2),
00385 };

Enumerator:
IAX_IOSTATE_IDLE 
IAX_IOSTATE_READY 
IAX_IOSTATE_PROCESSING 
IAX_IOSTATE_SCHEDREADY 

Definition at line 970 of file chan_iax2.c.

Enumerator:
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 977 of file chan_iax2.c.

00977                       {
00978    IAX_THREAD_TYPE_POOL,
00979    IAX_THREAD_TYPE_DYNAMIC,
00980 };

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

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

Definition at line 573 of file chan_iax2.c.


Function Documentation

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

Definition at line 3351 of file chan_iax2.c.

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

Referenced by attempt_transmit().

03352 {
03353    /* Attempt to transmit the frame to the remote peer...
03354       Called without iaxsl held. */
03355    struct iax_frame *f = (struct iax_frame *)data;
03356    int freeme = 0;
03357    int callno = f->callno;
03358    /* Make sure this call is still active */
03359    if (callno) 
03360       ast_mutex_lock(&iaxsl[callno]);
03361    if (callno && iaxs[callno]) {
03362       if ((f->retries < 0) /* Already ACK'd */ ||
03363           (f->retries >= max_retries) /* Too many attempts */) {
03364             /* Record an error if we've transmitted too many times */
03365             if (f->retries >= max_retries) {
03366                if (f->transfer) {
03367                   /* Transfer timeout */
03368                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03369                } else if (f->final) {
03370                   iax2_destroy(callno);
03371                } else {
03372                   if (iaxs[callno]->owner)
03373                      ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno);
03374                   iaxs[callno]->error = ETIMEDOUT;
03375                   if (iaxs[callno]->owner) {
03376                      struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03377                      /* Hangup the fd */
03378                      iax2_queue_frame(callno, &fr); /* XXX */
03379                      /* Remember, owner could disappear */
03380                      if (iaxs[callno] && iaxs[callno]->owner)
03381                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03382                   } else {
03383                      if (iaxs[callno]->reg) {
03384                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03385                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03386                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03387                      }
03388                      iax2_destroy(callno);
03389                   }
03390                }
03391 
03392             }
03393             freeme = 1;
03394       } else {
03395          /* Update it if it needs it */
03396          update_packet(f);
03397          /* Attempt transmission */
03398          send_packet(f);
03399          f->retries++;
03400          /* Try again later after 10 times as long */
03401          f->retrytime *= 10;
03402          if (f->retrytime > MAX_RETRY_TIME)
03403             f->retrytime = MAX_RETRY_TIME;
03404          /* Transfer messages max out at one second */
03405          if (f->transfer && (f->retrytime > 1000))
03406             f->retrytime = 1000;
03407          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03408       }
03409    } else {
03410       /* Make sure it gets freed */
03411       f->retries = -1;
03412       freeme = 1;
03413    }
03414 
03415    if (freeme) {
03416       /* Don't attempt delivery, just remove it from the queue */
03417       AST_LIST_REMOVE(&frame_queue[callno], f, list);
03418       ast_mutex_unlock(&iaxsl[callno]);
03419       f->retrans = -1; /* this is safe because this is the scheduled function */
03420       /* Free the IAX frame */
03421       iax2_frame_free(f);
03422    } else if (callno) {
03423       ast_mutex_unlock(&iaxsl[callno]);
03424    }
03425 }

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

Definition at line 8679 of file chan_iax2.c.

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

Referenced by auth_reject().

08680 {
08681    /* Called from IAX thread only, without iaxs lock */
08682    int callno = (int)(long)(nothing);
08683    struct iax_ie_data ied;
08684    ast_mutex_lock(&iaxsl[callno]);
08685    if (iaxs[callno]) {
08686       memset(&ied, 0, sizeof(ied));
08687       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08688          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08689          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08690       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08691          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08692          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08693       }
08694       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08695    }
08696    ast_mutex_unlock(&iaxsl[callno]);
08697 }

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

Definition at line 4498 of file chan_iax2.c.

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

Referenced by auto_congest().

04499 {
04500    int callno = PTR_TO_CALLNO(nothing);
04501    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
04502    ast_mutex_lock(&iaxsl[callno]);
04503    if (iaxs[callno]) {
04504       iaxs[callno]->initid = -1;
04505       iax2_queue_frame(callno, &f);
04506       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04507    }
04508    ast_mutex_unlock(&iaxsl[callno]);
04509 }

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

Definition at line 8728 of file chan_iax2.c.

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

Referenced by auto_hangup().

08729 {
08730    /* Called from IAX thread only, without iaxs lock */
08731    int callno = (int)(long)(nothing);
08732    struct iax_ie_data ied;
08733    ast_mutex_lock(&iaxsl[callno]);
08734    if (iaxs[callno]) {
08735       memset(&ied, 0, sizeof(ied));
08736       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
08737       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
08738       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
08739    }
08740    ast_mutex_unlock(&iaxsl[callno]);
08741 }

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

Referenced by __get_from_jb(), and schedule_delivery().

03147 {
03148    /* Just deliver the packet by using queueing.  This is called by
03149      the IAX thread with the iaxsl lock held. */
03150    struct iax_frame *fr = data;
03151    fr->retrans = -1;
03152    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03153    if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03154       iax2_queue_frame(fr->callno, &fr->af);
03155    /* Free our iax frame */
03156    iax2_frame_free(fr);
03157    /* And don't run again */
03158    return 0;
03159 }

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

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

08328 {
08329    struct iax2_peer *peer = (struct iax2_peer *) data;
08330 
08331    if (!peer)
08332       return;
08333 
08334    peer->expire = -1;
08335 
08336    ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08337    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08338       realtime_update_peer(peer->name, &peer->addr, 0);
08339    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08340    /* modify entry in peercnts table as _not_ registered */
08341    peercnt_modify(0, 0, &peer->addr);
08342    /* Reset the address */
08343    memset(&peer->addr, 0, sizeof(peer->addr));
08344    /* Reset expiry value */
08345    peer->expiry = min_reg_expire;
08346    if (!ast_test_flag64(peer, IAX_TEMPONLY))
08347       ast_db_del("IAX/Registry", peer->name);
08348    register_peer_exten(peer, 0);
08349    ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
08350    if (iax2_regfunk)
08351       iax2_regfunk(peer->name, 0);
08352 
08353    if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08354       unlink_peer(peer);
08355 
08356    peer_unref(peer);
08357 }

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

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

Referenced by find_callno(), and find_callno_locked().

02625 {
02626    int res = 0;
02627    int x;
02628    /* this call is calltoken validated as long as it is either NEW_FORCE
02629     * or NEW_ALLOW_CALLTOKEN_VALIDATED */
02630    int validated = (new > NEW_ALLOW) ? 1 : 0;
02631    char host[80];
02632 
02633    if (new <= NEW_ALLOW) {
02634       if (callno) {
02635          struct chan_iax2_pvt *pvt;
02636          struct chan_iax2_pvt tmp_pvt = {
02637             .callno = dcallno,
02638             .peercallno = callno,
02639             .transfercallno = callno,
02640             /* hack!! */
02641             .frames_received = check_dcallno,
02642          };
02643 
02644          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02645          /* this works for finding normal call numbers not involving transfering */ 
02646          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02647             if (return_locked) {
02648                ast_mutex_lock(&iaxsl[pvt->callno]);
02649             }
02650             res = pvt->callno;
02651             ao2_ref(pvt, -1);
02652             pvt = NULL;
02653             return res;
02654          }
02655          /* this searches for transfer call numbers that might not get caught otherwise */
02656          memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02657          memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02658          if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02659             if (return_locked) {
02660                ast_mutex_lock(&iaxsl[pvt->callno]);
02661             }
02662             res = pvt->callno;
02663             ao2_ref(pvt, -1);
02664             pvt = NULL;
02665             return res;
02666          }
02667       }
02668          /* This will occur on the first response to a message that we initiated,
02669        * such as a PING. */
02670       if (dcallno) {
02671          ast_mutex_lock(&iaxsl[dcallno]);
02672       }
02673       if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02674          iaxs[dcallno]->peercallno = callno;
02675          res = dcallno;
02676          store_by_peercallno(iaxs[dcallno]);
02677          if (!res || !return_locked) {
02678             ast_mutex_unlock(&iaxsl[dcallno]);
02679          }
02680          return res;
02681       }
02682       if (dcallno) {
02683          ast_mutex_unlock(&iaxsl[dcallno]);
02684       }
02685 #ifdef IAX_OLD_FIND
02686       /* If we get here, we SHOULD NOT find a call structure for this
02687          callno; if we do, it means that there is a call structure that
02688          has a peer callno but did NOT get entered into the hash table,
02689          which is bad.
02690 
02691          If we find a call structure using this old, slow method, output a log
02692          message so we'll know about it. After a few months of leaving this in
02693          place, if we don't hear about people seeing these messages, we can
02694          remove this code for good.
02695       */
02696 
02697       for (x = 1; !res && x < maxnontrunkcall; x++) {
02698          ast_mutex_lock(&iaxsl[x]);
02699          if (iaxs[x]) {
02700             /* Look for an exact match */
02701             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02702                res = x;
02703             }
02704          }
02705          if (!res || !return_locked)
02706             ast_mutex_unlock(&iaxsl[x]);
02707       }
02708       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02709          ast_mutex_lock(&iaxsl[x]);
02710          if (iaxs[x]) {
02711             /* Look for an exact match */
02712             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02713                res = x;
02714             }
02715          }
02716          if (!res || !return_locked)
02717             ast_mutex_unlock(&iaxsl[x]);
02718       }
02719 #endif
02720    }
02721    if (!res && (new >= NEW_ALLOW)) {
02722       struct callno_entry *callno_entry;
02723       /* It may seem odd that we look through the peer list for a name for
02724        * this *incoming* call.  Well, it is weird.  However, users don't
02725        * have an IP address/port number that we can match against.  So,
02726        * this is just checking for a peer that has that IP/port and
02727        * assuming that we have a user of the same name.  This isn't always
02728        * correct, but it will be changed if needed after authentication. */
02729       if (!iax2_getpeername(*sin, host, sizeof(host)))
02730          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02731 
02732       if (peercnt_add(sin)) {
02733          /* This address has hit its callnumber limit.  When the limit
02734           * is reached, the connection is not added to the peercnts table.*/
02735          return 0;
02736       }
02737 
02738       if (!(callno_entry = get_unused_callno(0, validated))) {
02739          /* since we ran out of space, remove the peercnt
02740           * entry we added earlier */
02741          peercnt_remove_by_addr(sin);
02742          ast_log(LOG_WARNING, "No more space\n");
02743          return 0;
02744       }
02745       x = callno_entry->callno;
02746       ast_mutex_lock(&iaxsl[x]);
02747 
02748       iaxs[x] = new_iax(sin, host);
02749       update_max_nontrunk();
02750       if (iaxs[x]) {
02751          if (iaxdebug)
02752             ast_debug(1, "Creating new call structure %d\n", x);
02753          iaxs[x]->callno_entry = callno_entry;
02754          iaxs[x]->sockfd = sockfd;
02755          iaxs[x]->addr.sin_port = sin->sin_port;
02756          iaxs[x]->addr.sin_family = sin->sin_family;
02757          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02758          iaxs[x]->peercallno = callno;
02759          iaxs[x]->callno = x;
02760          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02761          iaxs[x]->expiry = min_reg_expire;
02762          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02763          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02764          iaxs[x]->amaflags = amaflags;
02765          ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
02766          ast_string_field_set(iaxs[x], accountcode, accountcode);
02767          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02768          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02769          ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02770 
02771          if (iaxs[x]->peercallno) {
02772             store_by_peercallno(iaxs[x]);
02773          }
02774       } else {
02775          ast_log(LOG_WARNING, "Out of resources\n");
02776          ast_mutex_unlock(&iaxsl[x]);
02777          replace_callno(callno_entry);
02778          return 0;
02779       }
02780       if (!return_locked)
02781          ast_mutex_unlock(&iaxsl[x]);
02782       res = x;
02783    }
02784    return res;
02785 }

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

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

Referenced by get_from_jb().

03925 {
03926    int callno = PTR_TO_CALLNO(p);
03927    struct chan_iax2_pvt *pvt = NULL;
03928    struct iax_frame *fr;
03929    jb_frame frame;
03930    int ret;
03931    long ms;
03932    long next;
03933    struct timeval now = ast_tvnow();
03934    
03935    /* Make sure we have a valid private structure before going on */
03936    ast_mutex_lock(&iaxsl[callno]);
03937    pvt = iaxs[callno];
03938    if (!pvt) {
03939       /* No go! */
03940       ast_mutex_unlock(&iaxsl[callno]);
03941       return;
03942    }
03943 
03944    pvt->jbid = -1;
03945    
03946    /* round up a millisecond since ast_sched_runq does; */
03947    /* prevents us from spinning while waiting for our now */
03948    /* to catch up with runq's now */
03949    now.tv_usec += 1000;
03950    
03951    ms = ast_tvdiff_ms(now, pvt->rxcore);
03952    
03953    if(ms >= (next = jb_next(pvt->jb))) {
03954       ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
03955       switch(ret) {
03956       case JB_OK:
03957          fr = frame.data;
03958          __do_deliver(fr);
03959          /* __do_deliver() can cause the call to disappear */
03960          pvt = iaxs[callno];
03961          break;
03962       case JB_INTERP:
03963       {
03964          struct ast_frame af = { 0, };
03965          
03966          /* create an interpolation frame */
03967          af.frametype = AST_FRAME_VOICE;
03968          af.subclass = pvt->voiceformat;
03969          af.samples  = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
03970          af.src  = "IAX2 JB interpolation";
03971          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03972          af.offset = AST_FRIENDLY_OFFSET;
03973          
03974          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
03975           * which we'd need to malloc, and then it would free it.  That seems like a drag */
03976          if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
03977             iax2_queue_frame(callno, &af);
03978             /* iax2_queue_frame() could cause the call to disappear */
03979             pvt = iaxs[callno];
03980          }
03981       }
03982          break;
03983       case JB_DROP:
03984          iax2_frame_free(frame.data);
03985          break;
03986       case JB_NOFRAME:
03987       case JB_EMPTY:
03988          /* do nothing */
03989          break;
03990       default:
03991          /* shouldn't happen */
03992          break;
03993       }
03994    }
03995    if (pvt)
03996       update_jbsched(pvt);
03997    ast_mutex_unlock(&iaxsl[callno]);
03998 }

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

Definition at line 8009 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

08010 {
08011    struct iax2_registry *reg = (struct iax2_registry *)data;
08012    reg->expire = -1;
08013    iax2_do_register(reg);
08014 }

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

Definition at line 11553 of file chan_iax2.c.

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

Referenced by iax2_poke_noanswer().

11554 {
11555    struct iax2_peer *peer = (struct iax2_peer *)data;
11556    int callno;
11557 
11558    if (peer->lastms > -1) {
11559       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11560       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11561       ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
11562    }
11563    if ((callno = peer->callno) > 0) {
11564       ast_mutex_lock(&iaxsl[callno]);
11565       iax2_destroy(callno);
11566       ast_mutex_unlock(&iaxsl[callno]);
11567    }
11568    peer->callno = 0;
11569    peer->lastms = -1;
11570    /* Try again quickly */
11571    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11572    if (peer->pokeexpire == -1)
11573       peer_unref(peer);
11574 }

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

Definition at line 8788 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

08789 {
08790    struct iax2_peer *peer = (struct iax2_peer *)data;
08791    iax2_poke_peer(peer, 0);
08792    peer_unref(peer);
08793 }

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

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

Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().

06406 {
06407    regex_t regexbuf;
06408    int havepattern = 0;
06409    int total_peers = 0;
06410    int online_peers = 0;
06411    int offline_peers = 0;
06412    int unmonitored_peers = 0;
06413    struct ao2_iterator i;
06414 
06415 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
06416 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
06417 
06418    struct iax2_peer *peer = NULL;
06419    char name[256];
06420    struct ast_str *encmethods = ast_str_alloca(256);
06421    int registeredonly=0;
06422    char *term = manager ? "\r\n" : "\n";
06423    char idtext[256] = "";
06424    switch (argc) {
06425    case 6:
06426       if (!strcasecmp(argv[3], "registered"))
06427          registeredonly = 1;
06428       else
06429          return RESULT_SHOWUSAGE;
06430       if (!strcasecmp(argv[4], "like")) {
06431          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06432             return RESULT_SHOWUSAGE;
06433          havepattern = 1;
06434       } else
06435          return RESULT_SHOWUSAGE;
06436       break;
06437    case 5:
06438       if (!strcasecmp(argv[3], "like")) {
06439          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06440             return RESULT_SHOWUSAGE;
06441          havepattern = 1;
06442       } else
06443          return RESULT_SHOWUSAGE;
06444       break;
06445    case 4:
06446       if (!strcasecmp(argv[3], "registered"))
06447          registeredonly = 1;
06448       else
06449          return RESULT_SHOWUSAGE;
06450       break;
06451    case 3:
06452       break;
06453    default:
06454       return RESULT_SHOWUSAGE;
06455    }
06456 
06457 
06458    if (!s)
06459       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
06460 
06461    i = ao2_iterator_init(peers, 0);
06462    for (peer = ao2_iterator_next(&i); peer; 
06463       peer_unref(peer), peer = ao2_iterator_next(&i)) {
06464       char nm[20];
06465       char status[20];
06466       int retstatus;
06467 
06468       if (registeredonly && !peer->addr.sin_addr.s_addr)
06469          continue;
06470       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
06471          continue;
06472 
06473       if (!ast_strlen_zero(peer->username))
06474          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06475       else
06476          ast_copy_string(name, peer->name, sizeof(name));
06477 
06478       encmethods_to_str(peer->encmethods, encmethods);
06479       retstatus = peer_status(peer, status, sizeof(status));
06480       if (retstatus > 0)
06481          online_peers++;
06482       else if (!retstatus)
06483          offline_peers++;
06484       else
06485          unmonitored_peers++;
06486 
06487       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06488 
06489       if (s) {
06490          astman_append(s,
06491             "Event: PeerEntry\r\n%s"
06492             "Channeltype: IAX2\r\n"
06493             "ChanObjectType: peer\r\n"
06494             "ObjectName: %s\r\n"
06495             "IPaddress: %s\r\n"
06496             "IPport: %d\r\n"
06497             "Dynamic: %s\r\n"
06498             "Trunk: %s\r\n"
06499             "Encryption: %s\r\n"
06500             "Status: %s\r\n\r\n",
06501             idtext,
06502             name,
06503             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
06504             ntohs(peer->addr.sin_port),
06505             ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06506             ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06507             peer->encmethods ? ast_str_buffer(encmethods) : "no",
06508             status);
06509       } else {
06510          ast_cli(fd, FORMAT, name,
06511             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
06512             ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06513             nm,
06514             ntohs(peer->addr.sin_port),
06515             ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : "   ",
06516             peer->encmethods ? "(E)" : "   ",
06517             status,
06518             term);
06519       }
06520       total_peers++;
06521    }
06522    ao2_iterator_destroy(&i);
06523 
06524    if (!s)
06525       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
06526 
06527    if (havepattern)
06528       regfree(&regexbuf);
06529 
06530    return RESULT_SUCCESS;
06531 #undef FORMAT
06532 #undef FORMAT2
06533 }

static void __reg_module ( void   )  [static]

Definition at line 14038 of file chan_iax2.c.

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

Definition at line 1373 of file chan_iax2.c.

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

01374 {
01375    struct iax2_thread *thread = NULL;
01376    static time_t lasterror;
01377    static time_t t;
01378 
01379    thread = find_idle_thread();
01380 
01381    if (thread != NULL) {
01382       thread->schedfunc = func;
01383       thread->scheddata = data;
01384       thread->iostate = IAX_IOSTATE_SCHEDREADY;
01385 #ifdef DEBUG_SCHED_MULTITHREAD
01386       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01387 #endif
01388       signal_condition(&thread->lock, &thread->cond);
01389       return 0;
01390    }
01391    time(&t);
01392    if (t != lasterror) 
01393       ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01394    lasterror = t;
01395 
01396    return -1;
01397 }

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

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

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

07211 {
07212    struct ast_frame f = { 0, };
07213    int res = 0;
07214 
07215    f.frametype = type;
07216    f.subclass = command;
07217    f.datalen = datalen;
07218    f.src = __FUNCTION__;
07219    f.data.ptr = (void *) data;
07220 
07221    if ((res = queue_signalling(i, &f)) <= 0) {
07222       return res;
07223    }
07224 
07225    return iax2_send(i, &f, ts, seqno, now, transfer, final);
07226 }

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

Definition at line 1478 of file chan_iax2.c.

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

Referenced by send_lagrq().

01479 {
01480    int callno = (long) data;
01481 
01482    ast_mutex_lock(&iaxsl[callno]);
01483 
01484    if (iaxs[callno]) {
01485       if (iaxs[callno]->peercallno) {
01486          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01487          iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01488       } else {
01489          /* I am the schedule, so I'm allowed to do this */
01490          iaxs[callno]->lagid = -1;
01491       }
01492    } else {
01493       ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01494    }
01495 
01496    ast_mutex_unlock(&iaxsl[callno]);
01497 }

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

Definition at line 1417 of file chan_iax2.c.

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

Referenced by send_ping().

01418 {
01419    int callno = (long) data;
01420 
01421    ast_mutex_lock(&iaxsl[callno]);
01422 
01423    if (iaxs[callno]) {
01424       if (iaxs[callno]->peercallno) {
01425          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01426          iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01427       } else {
01428          /* I am the schedule, so I'm allowed to do this */
01429          iaxs[callno]->pingid = -1;
01430       }
01431    } else {
01432       ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01433    }
01434 
01435    ast_mutex_unlock(&iaxsl[callno]);
01436 }

static int __unload_module ( void   )  [static]

Definition at line 13739 of file chan_iax2.c.

References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_destroy(), ast_netsock_release(), AST_PTHREADT_NULL, ast_sched_thread_destroy(), ast_taskprocessor_unreference(), ast_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), delete_users(), iax2_destroy(), iax_provision_unload(), iaxactivethreadcount, reload_firmware(), thread, and iax2_thread::threadid.

13740 {
13741    struct iax2_thread *thread = NULL;
13742    struct ast_context *con;
13743    int x;
13744 
13745    if (netthreadid != AST_PTHREADT_NULL) {
13746       pthread_cancel(netthreadid);
13747       pthread_kill(netthreadid, SIGURG);
13748       pthread_join(netthreadid, NULL);
13749    }
13750 
13751    sched = ast_sched_thread_destroy(sched);
13752 
13753    /* Call for all threads to halt */
13754    AST_LIST_LOCK(&idle_list);
13755    while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list)))
13756       pthread_cancel(thread->threadid);
13757    AST_LIST_UNLOCK(&idle_list);
13758 
13759    AST_LIST_LOCK(&active_list);
13760    while ((thread = AST_LIST_REMOVE_HEAD(&active_list, list)))
13761       pthread_cancel(thread->threadid);
13762    AST_LIST_UNLOCK(&active_list);
13763 
13764    AST_LIST_LOCK(&dynamic_list);
13765    while ((thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list)))
13766       pthread_cancel(thread->threadid);
13767    AST_LIST_UNLOCK(&dynamic_list);
13768    
13769    /* Wait for threads to exit */
13770    while(0 < iaxactivethreadcount)
13771       usleep(10000);
13772    
13773    ast_netsock_release(netsock);
13774    ast_netsock_release(outsock);
13775    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13776       if (iaxs[x]) {
13777          iax2_destroy(x);
13778       }
13779    }
13780    ast_manager_unregister( "IAXpeers" );
13781    ast_manager_unregister( "IAXpeerlist" );
13782    ast_manager_unregister( "IAXnetstats" );
13783    ast_manager_unregister( "IAXregistry" );
13784    ast_unregister_application(papp);
13785    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
13786    ast_unregister_switch(&iax2_switch);
13787    ast_channel_unregister(&iax2_tech);
13788    delete_users();
13789    iax_provision_unload();
13790    reload_firmware(1);
13791 
13792    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13793       ast_mutex_destroy(&iaxsl[x]);
13794    }
13795 
13796    ao2_ref(peers, -1);
13797    ao2_ref(users, -1);
13798    ao2_ref(iax_peercallno_pvts, -1);
13799    ao2_ref(iax_transfercallno_pvts, -1);
13800    ao2_ref(peercnts, -1);
13801    ao2_ref(callno_limits, -1);
13802    ao2_ref(calltoken_ignores, -1);
13803    ao2_ref(callno_pool, -1);
13804    ao2_ref(callno_pool_trunk, -1);
13805    if (timer) {
13806       ast_timer_close(timer);
13807    }
13808    transmit_processor = ast_taskprocessor_unreference(transmit_processor);
13809 
13810    con = ast_context_find(regcontext);
13811    if (con)
13812       ast_context_destroy(con, "IAX2");
13813    ast_unload_realtime("iaxpeers");
13814    return 0;
13815 }

static void __unreg_module ( void   )  [static]

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

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

13525 {
13526    struct chan_iax2_pvt *pvt;
13527    unsigned int callno;
13528    int res = 0;
13529 
13530    if (!chan || chan->tech != &iax2_tech) {
13531       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13532       return -1;
13533    }
13534 
13535    callno = PTR_TO_CALLNO(chan->tech_pvt);
13536    ast_mutex_lock(&iaxsl[callno]);
13537    if (!(pvt = iaxs[callno])) {
13538       ast_mutex_unlock(&iaxsl[callno]);
13539       return -1;
13540    }
13541 
13542    if (!strcasecmp(args, "osptoken")) {
13543       ast_copy_string(buf, pvt->osptoken, buflen);
13544    } else if (!strcasecmp(args, "peerip")) {
13545       ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13546    } else if (!strcasecmp(args, "peername")) {
13547       ast_copy_string(buf, pvt->username, buflen);
13548    } else {
13549       res = -1;
13550    }
13551 
13552    ast_mutex_unlock(&iaxsl[callno]);
13553 
13554    return res;
13555 }

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

Definition at line 13496 of file chan_iax2.c.

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

13497 {
13498    struct chan_iax2_pvt *pvt;
13499    unsigned int callno;
13500    int res = 0;
13501 
13502    if (!chan || chan->tech != &iax2_tech) {
13503       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13504       return -1;
13505    }
13506 
13507    callno = PTR_TO_CALLNO(chan->tech_pvt);
13508    ast_mutex_lock(&iaxsl[callno]);
13509    if (!(pvt = iaxs[callno])) {
13510       ast_mutex_unlock(&iaxsl[callno]);
13511       return -1;
13512    }
13513 
13514    if (!strcasecmp(args, "osptoken"))
13515       ast_string_field_set(pvt, osptoken, value);
13516    else
13517       res = -1;
13518 
13519    ast_mutex_unlock(&iaxsl[callno]);
13520 
13521    return res;
13522 }

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

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

09454 {
09455    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09456    AST_LIST_HEAD(, ast_var_t) *varlist;
09457    struct ast_var_t *var;
09458 
09459    if (!variablestore) {
09460       *buf = '\0';
09461       return 0;
09462    }
09463    varlist = variablestore->data;
09464 
09465    AST_LIST_LOCK(varlist);
09466    AST_LIST_TRAVERSE(varlist, var, entries) {
09467       if (strcmp(var->name, data) == 0) {
09468          ast_copy_string(buf, var->value, len);
09469          break;
09470       }
09471    }
09472    AST_LIST_UNLOCK(varlist);
09473    return 0;
09474 }

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

Definition at line 9476 of file chan_iax2.c.

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

09477 {
09478    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09479    AST_LIST_HEAD(, ast_var_t) *varlist;
09480    struct ast_var_t *var;
09481 
09482    if (!variablestore) {
09483       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09484       if (!variablestore) {
09485          ast_log(LOG_ERROR, "Memory allocation error\n");
09486          return -1;
09487       }
09488       varlist = ast_calloc(1, sizeof(*varlist));
09489       if (!varlist) {
09490          ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09491          return -1;
09492       }
09493 
09494       AST_LIST_HEAD_INIT(varlist);
09495       variablestore->data = varlist;
09496       variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09497       ast_channel_datastore_add(chan, variablestore);
09498    } else
09499       varlist = variablestore->data;
09500 
09501    AST_LIST_LOCK(varlist);
09502    AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09503       if (strcmp(var->name, data) == 0) {
09504          AST_LIST_REMOVE_CURRENT(entries);
09505          ast_var_delete(var);
09506          break;
09507       }
09508    }
09509    AST_LIST_TRAVERSE_SAFE_END;
09510    var = ast_var_assign(data, value);
09511    if (var)
09512       AST_LIST_INSERT_TAIL(varlist, var, entries);
09513    else
09514       ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09515    AST_LIST_UNLOCK(varlist);
09516    return 0;
09517 }

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

Definition at line 2377 of file chan_iax2.c.

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

Referenced by set_config().

02378 {
02379    struct addr_range tmp;
02380    struct addr_range *addr_range = NULL;
02381    struct ast_ha *ha = NULL;
02382    int error = 0;
02383 
02384    if (ast_strlen_zero(addr)) {
02385       ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02386       return -1;
02387    }
02388 
02389    ha = ast_append_ha("permit", addr, NULL, &error);
02390 
02391    /* check for valid config information */
02392    if (error) {
02393       ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02394       return -1;
02395    }
02396 
02397    ast_copy_ha(ha, &tmp.ha);
02398    /* find or create the addr_range */
02399    if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02400       ao2_lock(addr_range);
02401       addr_range->delme = 0;
02402       ao2_unlock(addr_range);
02403    } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02404       /* copy over config data into addr_range object */
02405       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
02406       ao2_link(calltoken_ignores, addr_range);
02407    } else {
02408       ast_free_ha(ha);
02409       return -1;
02410    }
02411 
02412    ast_free_ha(ha);
02413    ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02414 
02415    return 0;
02416 }

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

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

04573 {
04574    /* first make sure their are two empty bytes left in ied->buf */
04575    if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04576       ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;  /* type */
04577       ied->buf[ied->pos++] = 0;   /* data size,  ZERO in this case */
04578       pvt->calltoken_ie_len = 2;
04579    }
04580 }

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

Definition at line 2039 of file chan_iax2.c.

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

Referenced by load_objects().

02040 {
02041    struct addr_range *lim1 = obj, *lim2 = arg;
02042    return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) &&
02043       (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ?
02044       CMP_MATCH | CMP_STOP : 0;
02045 }

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

Definition at line 2026 of file chan_iax2.c.

References addr_range::delme.

Referenced by set_config_destroy().

02027 {
02028    struct addr_range *lim = obj;
02029    lim->delme = 1;
02030    return 0;
02031 }

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

Definition at line 2033 of file chan_iax2.c.

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

Referenced by load_objects().

02034 {
02035    const struct addr_range *lim = obj;
02036    return abs((int) lim->ha.netaddr.s_addr);
02037 }

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

Definition at line 2059 of file chan_iax2.c.

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

Referenced by calltoken_required(), and set_peercnt_limit().

02060 {
02061    struct addr_range *addr_range = obj;
02062    struct sockaddr_in *sin = arg;
02063 
02064    if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) {
02065       return CMP_MATCH | CMP_STOP;
02066    }
02067    return 0;
02068 }

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

Definition at line 7267 of file chan_iax2.c.

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

Referenced by check_access().

07268 {
07269    while(con) {
07270       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07271          return -1;
07272       con = con->next;
07273    }
07274    return 0;
07275 }

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

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

06973 {
06974    int x;
06975    int numchans = 0;
06976    char first_message[10] = { 0, };
06977    char last_message[10] = { 0, };
06978 #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"
06979 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
06980    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06981       ast_mutex_lock(&iaxsl[x]);
06982       if (iaxs[x]) {
06983          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
06984          jb_info jbinfo;
06985          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06986          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06987 
06988          if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
06989             jb_getinfo(iaxs[x]->jb, &jbinfo);
06990             localjitter = jbinfo.jitter;
06991             localdelay = jbinfo.current - jbinfo.min;
06992             locallost = jbinfo.frames_lost;
06993             locallosspct = jbinfo.losspct/1000;
06994             localdropped = jbinfo.frames_dropped;
06995             localooo = jbinfo.frames_ooo;
06996          } else {
06997             localjitter = -1;
06998             localdelay = 0;
06999             locallost = -1;
07000             locallosspct = -1;
07001             localdropped = 0;
07002             localooo = -1;
07003          }
07004          if (s)
07005             astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07006                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07007                iaxs[x]->pingtime,
07008                localjitter,
07009                localdelay,
07010                locallost,
07011                locallosspct,
07012                localdropped,
07013                localooo,
07014                iaxs[x]->frames_received/1000,
07015                iaxs[x]->remote_rr.jitter,
07016                iaxs[x]->remote_rr.delay,
07017                iaxs[x]->remote_rr.losscnt,
07018                iaxs[x]->remote_rr.losspct,
07019                iaxs[x]->remote_rr.dropped,
07020                iaxs[x]->remote_rr.ooo,
07021                iaxs[x]->remote_rr.packets/1000,
07022                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07023                first_message,
07024                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07025                last_message);
07026          else
07027             ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07028                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07029                iaxs[x]->pingtime,
07030                localjitter,
07031                localdelay,
07032                locallost,
07033                locallosspct,
07034                localdropped,
07035                localooo,
07036                iaxs[x]->frames_received/1000,
07037                iaxs[x]->remote_rr.jitter,
07038                iaxs[x]->remote_rr.delay,
07039                iaxs[x]->remote_rr.losscnt,
07040                iaxs[x]->remote_rr.losspct,
07041                iaxs[x]->remote_rr.dropped,
07042                iaxs[x]->remote_rr.ooo,
07043                iaxs[x]->remote_rr.packets/1000,
07044                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07045                first_message,
07046                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07047                last_message);
07048          numchans++;
07049       }
07050       ast_mutex_unlock(&iaxsl[x]);
07051    }
07052 
07053    return numchans;
07054 }

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

Create new call, interface with the PBX core.

Definition at line 5496 of file chan_iax2.c.

References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, chan_iax2_pvt::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_calloc, ast_channel_alloc, ast_channel_datastore_add(), ast_channel_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(), chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, chan_iax2_pvt::cid_name, chan_iax2_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, chan_iax2_pvt::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, chan_iax2_pvt::dnid, ast_var_t::entries, ast_channel::exten, chan_iax2_pvt::exten, chan_iax2_pvt::host, iax2_ami_channelupdate(), chan_iax2_pvt::iaxvars, ast_datastore::inheritance, chan_iax2_pvt::language, LOG_ERROR, LOG_WARNING, ast_channel::name, ast_variable::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, parkinglot, chan_iax2_pvt::parkinglot, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_channel::rawreadformat, ast_channel::rawwriteformat, chan_iax2_pvt::rdnis, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, ast_variable::value, var, chan_iax2_pvt::vars, and ast_channel::writeformat.

Referenced by iax2_request(), and socket_process().

05497 {
05498    struct ast_channel *tmp;
05499    struct chan_iax2_pvt *i;
05500    struct ast_variable *v = NULL;
05501 
05502    if (!(i = iaxs[callno])) {
05503       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05504       return NULL;
05505    }
05506 
05507    /* Don't hold call lock */
05508    ast_mutex_unlock(&iaxsl[callno]);
05509    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);
05510    ast_mutex_lock(&iaxsl[callno]);
05511    if (i != iaxs[callno]) {
05512       if (tmp) {
05513          /* unlock and relock iaxsl[callno] to preserve locking order */
05514          ast_mutex_unlock(&iaxsl[callno]);
05515          tmp = ast_channel_release(tmp);
05516          ast_mutex_lock(&iaxsl[callno]);
05517       }
05518       return NULL;
05519    }
05520    iax2_ami_channelupdate(i);
05521    if (!tmp)
05522       return NULL;
05523    tmp->tech = &iax2_tech;
05524    /* We can support any format by default, until we get restricted */
05525    tmp->nativeformats = capability;
05526    tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05527    tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05528    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05529 
05530    if (!ast_strlen_zero(i->parkinglot))
05531       ast_string_field_set(tmp, parkinglot, i->parkinglot);
05532    /* Don't use ast_set_callerid() here because it will
05533     * generate a NewCallerID event before the NewChannel event */
05534    if (!ast_strlen_zero(i->ani))
05535       tmp->cid.cid_ani = ast_strdup(i->ani);
05536    else
05537       tmp->cid.cid_ani = ast_strdup(i->cid_num);
05538    tmp->cid.cid_dnid = ast_strdup(i->dnid);
05539    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05540    tmp->cid.cid_pres = i->calling_pres;
05541    tmp->cid.cid_ton = i->calling_ton;
05542    tmp->cid.cid_tns = i->calling_tns;
05543    if (!ast_strlen_zero(i->language))
05544       ast_string_field_set(tmp, language, i->language);
05545    if (!ast_strlen_zero(i->accountcode))
05546       ast_string_field_set(tmp, accountcode, i->accountcode);
05547    if (i->amaflags)
05548       tmp->amaflags = i->amaflags;
05549    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05550    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05551    if (i->adsi)
05552       tmp->adsicpe = i->peeradsicpe;
05553    else
05554       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05555    i->owner = tmp;
05556    i->capability = capability;
05557 
05558    /* Set inherited variables */
05559    if (i->vars) {
05560       for (v = i->vars ; v ; v = v->next)
05561          pbx_builtin_setvar_helper(tmp, v->name, v->value);
05562    }
05563    if (i->iaxvars) {
05564       struct ast_datastore *variablestore;
05565       struct ast_variable *var, *prev = NULL;
05566       AST_LIST_HEAD(, ast_var_t) *varlist;
05567       ast_debug(1, "Loading up the channel with IAXVARs\n");
05568       varlist = ast_calloc(1, sizeof(*varlist));
05569       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05570       if (variablestore && varlist) {
05571          variablestore->data = varlist;
05572          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05573          AST_LIST_HEAD_INIT(varlist);
05574          for (var = i->iaxvars; var; var = var->next) {
05575             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05576             if (prev)
05577                ast_free(prev);
05578             prev = var;
05579             if (!newvar) {
05580                /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
05581                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05582             } else {
05583                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05584             }
05585          }
05586          if (prev)
05587             ast_free(prev);
05588          i->iaxvars = NULL;
05589          ast_channel_datastore_add(i->owner, variablestore);
05590       } else {
05591          if (variablestore) {
05592             ast_datastore_free(variablestore);
05593          }
05594          if (varlist) {
05595             ast_free(varlist);
05596          }
05597       }
05598    }
05599 
05600    if (state != AST_STATE_DOWN) {
05601       if (ast_pbx_start(tmp)) {
05602          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05603          ast_hangup(tmp);
05604          i->owner = NULL;
05605          return NULL;
05606       }
05607    }
05608 
05609    ast_module_ref(ast_module_info->self);
05610    return tmp;
05611 }

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

Definition at line 3427 of file chan_iax2.c.

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and transmit_frame().

03428 {
03429 #ifdef SCHED_MULTITHREADED
03430    if (schedule_action(__attempt_transmit, data))
03431 #endif      
03432       __attempt_transmit(data);
03433    return 0;
03434 }

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

Definition at line 8713 of file chan_iax2.c.

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

Referenced by socket_process().

08714 {
08715    /* Schedule sending the authentication failure in one second, to prevent
08716       guessing */
08717    if (iaxs[callno]) {
08718       iaxs[callno]->authfail = failcode;
08719       if (delayreject) {
08720          iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 
08721             sched, 1000, auth_reject, (void *)(long)callno);
08722       } else
08723          auth_reject((void *)(long)callno);
08724    }
08725    return 0;
08726 }

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

Definition at line 8699 of file chan_iax2.c.

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

Referenced by auth_fail().

08700 {
08701    int callno = (int)(long)(data);
08702    ast_mutex_lock(&iaxsl[callno]);
08703    if (iaxs[callno])
08704       iaxs[callno]->authid = -1;
08705    ast_mutex_unlock(&iaxsl[callno]);
08706 #ifdef SCHED_MULTITHREADED
08707    if (schedule_action(__auth_reject, data))
08708 #endif      
08709       __auth_reject(data);
08710    return 0;
08711 }

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

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

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

07836 {
07837    int res = -1;
07838    int x;
07839    if (!ast_strlen_zero(keyn)) {
07840       if (!(authmethods & IAX_AUTH_RSA)) {
07841          if (ast_strlen_zero(secret)) 
07842             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));
07843       } else if (ast_strlen_zero(challenge)) {
07844          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
07845       } else {
07846          char sig[256];
07847          struct ast_key *key;
07848          key = ast_key_get(keyn, AST_KEY_PRIVATE);
07849          if (!key) {
07850             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
07851          } else {
07852             if (ast_sign(key, (char*)challenge, sig)) {
07853                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
07854                res = -1;
07855             } else {
07856                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
07857                res = 0;
07858             }
07859          }
07860       }
07861    } 
07862    /* Fall back */
07863    if (res && !ast_strlen_zero(secret)) {
07864       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
07865          struct MD5Context md5;
07866          unsigned char digest[16];
07867          char digres[128];
07868          MD5Init(&md5);
07869          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
07870          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
07871          MD5Final(digest, &md5);
07872          /* If they support md5, authenticate with it.  */
07873          for (x=0;x<16;x++)
07874             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
07875          if (pvt) {
07876             build_encryption_keys(digest, pvt);
07877          }
07878          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
07879          res = 0;
07880       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
07881          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
07882          res = 0;
07883       } else
07884          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
07885    }
07886    return res;
07887 }

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 7893 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_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_assign(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, iax_ie_data::buf, chan_iax2_pvt::callno, chan_iax2_pvt::challenge, iax_ies::challenge, ast_datastore::data, DATASTORE_INHERIT_FOREVER, chan_iax2_pvt::encmethods, iax_ies::encmethods, ast_var_t::entries, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_FORCE_ENCRYPT, IAX_KEYPOPULATED, ast_datastore::inheritance, LOG_ERROR, LOG_NOTICE, iax2_peer::mask, merge_encryption(), ast_variable::name, iax2_peer::name, ast_variable::next, iax2_peer::outkey, chan_iax2_pvt::owner, chan_iax2_pvt::peer, peer_unref(), iax_ie_data::pos, realtime_peer(), iax2_peer::secret, send_command(), chan_iax2_pvt::username, iax2_peer::username, iax_ies::username, ast_variable::value, var, and iax_ies::vars.

Referenced by socket_process().

07894 {
07895    struct iax2_peer *peer = NULL;
07896    /* Start pessimistic */
07897    int res = -1;
07898    int authmethods = 0;
07899    struct iax_ie_data ied;
07900    uint16_t callno = p->callno;
07901 
07902    memset(&ied, 0, sizeof(ied));
07903    
07904    if (ies->username)
07905       ast_string_field_set(p, username, ies->username);
07906    if (ies->challenge)
07907       ast_string_field_set(p, challenge, ies->challenge);
07908    if (ies->authmethods)
07909       authmethods = ies->authmethods;
07910    if (authmethods & IAX_AUTH_MD5)
07911       merge_encryption(p, ies->encmethods);
07912    else
07913       p->encmethods = 0;
07914 
07915    /* Check for override RSA authentication first */
07916    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
07917       /* Normal password authentication */
07918       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
07919    } else {
07920       struct ao2_iterator i = ao2_iterator_init(peers, 0);
07921       while ((peer = ao2_iterator_next(&i))) {
07922          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
07923              /* No peer specified at our end, or this is the peer */
07924              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
07925              /* No username specified in peer rule, or this is the right username */
07926              && (!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)))
07927              /* No specified host, or this is our host */
07928             ) {
07929             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
07930             if (!res) {
07931                peer_unref(peer);
07932                break;
07933             }
07934          }
07935          peer_unref(peer);
07936       }
07937       ao2_iterator_destroy(&i);
07938       if (!peer) {
07939          /* We checked our list and didn't find one.  It's unlikely, but possible, 
07940             that we're trying to authenticate *to* a realtime peer */
07941          const char *peer_name = ast_strdupa(p->peer);
07942          ast_mutex_unlock(&iaxsl[callno]);
07943          if ((peer = realtime_peer(peer_name, NULL))) {
07944             ast_mutex_lock(&iaxsl[callno]);
07945             if (!(p = iaxs[callno])) {
07946                peer_unref(peer);
07947                return -1;
07948             }
07949             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
07950             peer_unref(peer);
07951          }
07952          if (!peer) {
07953             ast_mutex_lock(&iaxsl[callno]);
07954             if (!(p = iaxs[callno]))
07955                return -1;
07956          }
07957       }
07958    }
07959 
07960    if (ies->encmethods) {
07961       ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
07962    } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
07963       ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
07964       return -1;             /* if force encryption is yes, and no encryption methods, then return -1 to hangup */
07965    }
07966    if (!res) {
07967       struct ast_datastore *variablestore;
07968       struct ast_variable *var, *prev = NULL;
07969       AST_LIST_HEAD(, ast_var_t) *varlist;
07970       varlist = ast_calloc(1, sizeof(*varlist));
07971       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
07972       if (variablestore && varlist && p->owner) {
07973          variablestore->data = varlist;
07974          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
07975          AST_LIST_HEAD_INIT(varlist);
07976          for (var = ies->vars; var; var = var->next) {
07977             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
07978             if (prev)
07979                ast_free(prev);
07980             prev = var;
07981             if (!newvar) {
07982                /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */
07983                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07984             } else {
07985                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
07986             }
07987          }
07988          if (prev)
07989             ast_free(prev);
07990          ies->vars = NULL;
07991          ast_channel_datastore_add(p->owner, variablestore);
07992       } else {
07993          if (p->owner)
07994             ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07995          if (variablestore)
07996             ast_datastore_free(variablestore);
07997          if (varlist)
07998             ast_free(varlist);
07999       }
08000    }
08001 
08002    if (!res)
08003       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08004    return res;
08005 }

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

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

Referenced by socket_process().

07544 {
07545    struct iax_ie_data ied;
07546    int res = -1, authreq_restrict = 0;
07547    char challenge[10];
07548    struct chan_iax2_pvt *p = iaxs[call_num];
07549 
07550    memset(&ied, 0, sizeof(ied));
07551 
07552    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
07553    if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07554       struct iax2_user *user, tmp_user = {
07555          .name = p->username, 
07556       };
07557 
07558       user = ao2_find(users, &tmp_user, OBJ_POINTER);
07559       if (user) {
07560          if (user->curauthreq == user->maxauthreq)
07561             authreq_restrict = 1;
07562          else
07563             user->curauthreq++;
07564          user = user_unref(user);
07565       }
07566    }
07567 
07568    /* If the AUTHREQ limit test failed, send back an error */
07569    if (authreq_restrict) {
07570       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07571       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07572       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07573       return 0;
07574    }
07575 
07576    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07577    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07578       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07579       ast_string_field_set(p, challenge, challenge);
07580       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
07581       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07582    }
07583    if (p->encmethods)
07584       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07585 
07586    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07587 
07588    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07589 
07590    if (p->encmethods)
07591       ast_set_flag64(p, IAX_ENCRYPTED);
07592 
07593    return res;
07594 }

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

Definition at line 7596 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, iax2_user::curauthreq, 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, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_user::name, OBJ_POINTER, iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user_unref(), and chan_iax2_pvt::username.

Referenced by socket_process().

07597 {
07598    char requeststr[256];
07599    char md5secret[256] = "";
07600    char secret[256] = "";
07601    char rsasecret[256] = "";
07602    int res = -1; 
07603    int x;
07604    struct iax2_user *user, tmp_user = {
07605       .name = p->username, 
07606    };
07607 
07608    if (p->authrej) {
07609       return res;
07610    }
07611    user = ao2_find(users, &tmp_user, OBJ_POINTER);
07612    if (user) {
07613       if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07614          ast_atomic_fetchadd_int(&user->curauthreq, -1);
07615          ast_clear_flag64(p, IAX_MAXAUTHREQ);
07616       }
07617       ast_string_field_set(p, host, user->name);
07618       user = user_unref(user);
07619    }
07620    if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 
07621       ast_log(LOG_NOTICE, "Call Terminated, Incomming call is unencrypted while force encrypt is enabled.");
07622       return res;
07623    }
07624    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07625       return res;
07626    if (ies->password)
07627       ast_copy_string(secret, ies->password, sizeof(secret));
07628    if (ies->md5_result)
07629       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07630    if (ies->rsa_result)
07631       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07632    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07633       struct ast_key *key;
07634       char *keyn;
07635       char tmpkey[256];
07636       char *stringp=NULL;
07637       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07638       stringp=tmpkey;
07639       keyn = strsep(&stringp, ":");
07640       while(keyn) {
07641          key = ast_key_get(keyn, AST_KEY_PUBLIC);
07642          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07643             res = 0;
07644             break;
07645          } else if (!key)
07646             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07647          keyn = strsep(&stringp, ":");
07648       }
07649    } else if (p->authmethods & IAX_AUTH_MD5) {
07650       struct MD5Context md5;
07651       unsigned char digest[16];
07652       char *tmppw, *stringp;
07653       
07654       tmppw = ast_strdupa(p->secret);
07655       stringp = tmppw;
07656       while((tmppw = strsep(&stringp, ";"))) {
07657          MD5Init(&md5);
07658          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07659          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07660          MD5Final(digest, &md5);
07661          /* If they support md5, authenticate with it.  */
07662          for (x=0;x<16;x++)
07663             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
07664          if (!strcasecmp(requeststr, md5secret)) {
07665             res = 0;
07666             break;
07667          }
07668       }
07669    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07670       if (!strcmp(secret, p->secret))
07671          res = 0;
07672    }
07673    return res;
07674 }

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

Definition at line 4511 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

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

04512 {
04513 #ifdef SCHED_MULTITHREADED
04514    if (schedule_action(__auto_congest, data))
04515 #endif      
04516       __auto_congest(data);
04517    return 0;
04518 }

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

Definition at line 8743 of file chan_iax2.c.

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

Referenced by iax2_dprequest(), and iax2_provision().

08744 {
08745    int callno = (int)(long)(data);
08746    ast_mutex_lock(&iaxsl[callno]);
08747    if (iaxs[callno]) {
08748       iaxs[callno]->autoid = -1;
08749    }
08750    ast_mutex_unlock(&iaxsl[callno]);
08751 #ifdef SCHED_MULTITHREADED
08752    if (schedule_action(__auto_hangup, data))
08753 #endif      
08754       __auto_hangup(data);
08755    return 0;
08756 }

static void build_callno_limits ( struct ast_variable v  )  [static]

Definition at line 2322 of file chan_iax2.c.

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

Referenced by set_config().

02323 {
02324    struct addr_range *addr_range = NULL;
02325    struct addr_range tmp;
02326    struct ast_ha *ha;
02327    int limit;
02328    int error;
02329    int found;
02330 
02331    for (; v; v = v->next) {
02332       limit = -1;
02333       error = 0;
02334       found = 0;
02335       ha = ast_append_ha("permit", v->name, NULL, &error);
02336 
02337       /* check for valid config information */
02338       if (error) {
02339          ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02340          continue;
02341       } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02342          ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02343          ast_free_ha(ha);
02344          continue;
02345       }
02346 
02347       ast_copy_ha(ha, &tmp.ha);
02348       /* find or create the addr_range */
02349       if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02350          ao2_lock(addr_range);
02351          found = 1;
02352       } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02353          ast_free_ha(ha);
02354          return; /* out of memory */
02355       }
02356 
02357       /* copy over config data into addr_range object */
02358       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
02359       ast_free_ha(ha); /* cleanup the tmp ha */
02360       addr_range->limit = limit;
02361       addr_range->delme = 0;
02362 
02363       /* cleanup */
02364       if (found) {
02365          ao2_unlock(addr_range);
02366       } else {
02367          ao2_link(callno_limits, addr_range);
02368       }
02369       ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02370    }
02371 }

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

Definition at line 11796 of file chan_iax2.c.

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

Referenced by build_user().

11797 {
11798    struct iax2_context *con;
11799 
11800    if ((con = ast_calloc(1, sizeof(*con))))
11801       ast_copy_string(con->context, context, sizeof(con->context));
11802    
11803    return con;
11804 }

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

Definition at line 5954 of file chan_iax2.c.

References ast_aes_decrypt_key, ast_aes_encrypt_key, build_rand_pad(), chan_iax2_pvt::ecx, chan_iax2_pvt::mydcx, and chan_iax2_pvt::semirand.

Referenced by build_encryption_keys(), and iax2_key_rotate().

05955 {
05956    /* it is required to hold the corresponding decrypt key to our encrypt key
05957     * in the pvt struct because queued frames occasionally need to be decrypted and
05958     * re-encrypted when updated for a retransmission */
05959    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
05960    ast_aes_encrypt_key(digest, &pvt->ecx);
05961    ast_aes_decrypt_key(digest, &pvt->mydcx);
05962 }

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

Definition at line 5948 of file chan_iax2.c.

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

Referenced by authenticate(), and decrypt_frame().

05949 {
05950    build_ecx_key(digest, pvt);
05951    ast_aes_decrypt_key(digest, &pvt->dcx);
05952 }

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

Create peer structure based on configuration.

Definition at line 11944 of file chan_iax2.c.

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

11945 {
11946    struct iax2_peer *peer = NULL;
11947    struct ast_ha *oldha = NULL;
11948    int maskfound = 0;
11949    int found = 0;
11950    int firstpass = 1;
11951    struct iax2_peer tmp_peer = {
11952       .name = name,
11953    };
11954 
11955    if (!temponly) {
11956       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
11957       if (peer && !ast_test_flag64(peer, IAX_DELME))
11958          firstpass = 0;
11959    }
11960 
11961    if (peer) {
11962       found++;
11963       if (firstpass) {
11964          oldha = peer->ha;
11965          peer->ha = NULL;
11966       }
11967       unlink_peer(peer);
11968    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
11969       peer->expire = -1;
11970       peer->pokeexpire = -1;
11971       peer->sockfd = defaultsockfd;
11972       if (ast_string_field_init(peer, 32))
11973          peer = peer_unref(peer);
11974    }
11975 
11976    if (peer) {
11977       if (firstpass) {
11978          ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
11979          peer->encmethods = iax2_encryption;
11980          peer->adsi = adsi;
11981          ast_string_field_set(peer,secret,"");
11982          if (!found) {
11983             ast_string_field_set(peer, name, name);
11984             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
11985             peer->expiry = min_reg_expire;
11986          }
11987          peer->prefs = prefs;
11988          peer->capability = iax2_capability;
11989          peer->smoothing = 0;
11990          peer->pokefreqok = DEFAULT_FREQ_OK;
11991          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
11992          peer->maxcallno = 0;
11993          peercnt_modify(0, 0, &peer->addr);
11994          peer->calltoken_required = CALLTOKEN_DEFAULT;
11995          ast_string_field_set(peer,context,"");
11996          ast_string_field_set(peer,peercontext,"");
11997          ast_clear_flag64(peer, IAX_HASCALLERID);
11998          ast_string_field_set(peer, cid_name, "");
11999          ast_string_field_set(peer, cid_num, "");
12000          ast_string_field_set(peer, mohinterpret, mohinterpret);
12001          ast_string_field_set(peer, mohsuggest, mohsuggest);
12002       }
12003 
12004       if (!v) {
12005          v = alt;
12006          alt = NULL;
12007       }
12008       while(v) {
12009          if (!strcasecmp(v->name, "secret")) {
12010             ast_string_field_set(peer, secret, v->value);
12011          } else if (!strcasecmp(v->name, "mailbox")) {
12012             ast_string_field_set(peer, mailbox, v->value);
12013          } else if (!strcasecmp(v->name, "hasvoicemail")) {
12014             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12015                ast_string_field_set(peer, mailbox, name);
12016             }
12017          } else if (!strcasecmp(v->name, "mohinterpret")) {
12018             ast_string_field_set(peer, mohinterpret, v->value);
12019          } else if (!strcasecmp(v->name, "mohsuggest")) {
12020             ast_string_field_set(peer, mohsuggest, v->value);
12021          } else if (!strcasecmp(v->name, "dbsecret")) {
12022             ast_string_field_set(peer, dbsecret, v->value);
12023          } else if (!strcasecmp(v->name, "trunk")) {
12024             ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 
12025             if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12026                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12027                ast_clear_flag64(peer, IAX_TRUNK);
12028             }
12029          } else if (!strcasecmp(v->name, "auth")) {
12030             peer->authmethods = get_auth_methods(v->value);
12031          } else if (!strcasecmp(v->name, "encryption")) {
12032             peer->encmethods |= get_encrypt_methods(v->value);
12033             if (!peer->encmethods) {
12034                ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12035             }
12036          } else if (!strcasecmp(v->name, "forceencryption")) {
12037             if (ast_false(v->value)) {
12038                ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12039             } else {
12040                peer->encmethods |= get_encrypt_methods(v->value);
12041                if (peer->encmethods) {
12042                   ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12043                }
12044             }
12045          } else if (!strcasecmp(v->name, "transfer")) {
12046             if (!strcasecmp(v->value, "mediaonly")) {
12047                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12048             } else if (ast_true(v->value)) {
12049                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12050             } else
12051                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12052          } else if (!strcasecmp(v->name, "jitterbuffer")) {
12053             ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12054          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12055             ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12056          } else if (!strcasecmp(v->name, "host")) {
12057             if (!strcasecmp(v->value, "dynamic")) {
12058                /* They'll register with us */
12059                ast_set_flag64(peer, IAX_DYNAMIC);
12060                if (!found) {
12061                   /* Initialize stuff iff we're not found, otherwise
12062                      we keep going with what we had */
12063                   memset(&peer->addr.sin_addr, 0, 4);
12064                   if (peer->addr.sin_port) {
12065                      /* If we've already got a port, make it the default rather than absolute */
12066                      peer->defaddr.sin_port = peer->addr.sin_port;
12067                      peer->addr.sin_port = 0;
12068                   }
12069                }
12070             } else {
12071                /* Non-dynamic.  Make sure we become that way if we're not */
12072                ast_sched_thread_del(sched, peer->expire);
12073                ast_clear_flag64(peer, IAX_DYNAMIC);
12074                if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12075                   return peer_unref(peer);
12076                if (!peer->addr.sin_port)
12077                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
12078             }
12079             if (!maskfound)
12080                inet_aton("255.255.255.255", &peer->mask);
12081          } else if (!strcasecmp(v->name, "defaultip")) {
12082             if (ast_get_ip(&peer->defaddr, v->value))
12083                return peer_unref(peer);
12084          } else if (!strcasecmp(v->name, "sourceaddress")) {
12085             peer_set_srcaddr(peer, v->value);
12086          } else if (!strcasecmp(v->name, "permit") ||
12087                   !strcasecmp(v->name, "deny")) {
12088             peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12089          } else if (!strcasecmp(v->name, "mask")) {
12090             maskfound++;
12091             inet_aton(v->value, &peer->mask);
12092          } else if (!strcasecmp(v->name, "context")) {
12093             ast_string_field_set(peer, context, v->value);
12094          } else if (!strcasecmp(v->name, "regexten")) {
12095             ast_string_field_set(peer, regexten, v->value);
12096          } else if (!strcasecmp(v->name, "peercontext")) {
12097             ast_string_field_set(peer, peercontext, v->value);
12098          } else if (!strcasecmp(v->name, "port")) {
12099             if (ast_test_flag64(peer, IAX_DYNAMIC))
12100                peer->defaddr.sin_port = htons(atoi(v->value));
12101             else
12102                peer->addr.sin_port = htons(atoi(v->value));
12103          } else if (!strcasecmp(v->name, "username")) {
12104             ast_string_field_set(peer, username, v->value);
12105          } else if (!strcasecmp(v->name, "allow")) {
12106             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12107          } else if (!strcasecmp(v->name, "disallow")) {
12108             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12109          } else if (!strcasecmp(v->name, "callerid")) {
12110             if (!ast_strlen_zero(v->value)) {
12111                char name2[80];
12112                char num2[80];
12113                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12114                ast_string_field_set(peer, cid_name, name2);
12115                ast_string_field_set(peer, cid_num, num2);
12116             } else {
12117                ast_string_field_set(peer, cid_name, "");
12118                ast_string_field_set(peer, cid_num, "");
12119             }
12120             ast_set_flag64(peer, IAX_HASCALLERID);
12121          } else if (!strcasecmp(v->name, "fullname")) {
12122             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12123             ast_set_flag64(peer, IAX_HASCALLERID);
12124          } else if (!strcasecmp(v->name, "cid_number")) {
12125             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12126             ast_set_flag64(peer, IAX_HASCALLERID);
12127          } else if (!strcasecmp(v->name, "sendani")) {
12128             ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12129          } else if (!strcasecmp(v->name, "inkeys")) {
12130             ast_string_field_set(peer, inkeys, v->value);
12131          } else if (!strcasecmp(v->name, "outkey")) {
12132             ast_string_field_set(peer, outkey, v->value);
12133          } else if (!strcasecmp(v->name, "qualify")) {
12134             if (!strcasecmp(v->value, "no")) {
12135                peer->maxms = 0;
12136             } else if (!strcasecmp(v->value, "yes")) {
12137                peer->maxms = DEFAULT_MAXMS;
12138             } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12139                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);
12140                peer->maxms = 0;
12141             }
12142          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12143             peer->smoothing = ast_true(v->value);
12144          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12145             if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12146                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);
12147             }
12148          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12149             if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12150                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);
12151             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
12152          } else if (!strcasecmp(v->name, "timezone")) {
12153             ast_string_field_set(peer, zonetag, v->value);
12154          } else if (!strcasecmp(v->name, "adsi")) {
12155             peer->adsi = ast_true(v->value);
12156          } else if (!strcasecmp(v->name, "connectedline")) {
12157             if (ast_true(v->value)) {
12158                ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12159             } else if (!strcasecmp(v->value, "send")) {
12160                ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12161                ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12162             } else if (!strcasecmp(v->value, "receive")) {
12163                ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12164                ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12165             } else {
12166                ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12167             }
12168          } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12169             if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12170                ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12171             } else {
12172                peercnt_modify(1, peer->maxcallno, &peer->addr);
12173             }
12174          } else if (!strcasecmp(v->name, "requirecalltoken")) {
12175             /* default is required unless in optional ip list */
12176             if (ast_false(v->value)) {
12177                peer->calltoken_required = CALLTOKEN_NO;
12178             } else if (!strcasecmp(v->value, "auto")) {
12179                peer->calltoken_required = CALLTOKEN_AUTO;
12180             } else if (ast_true(v->value)) {
12181                peer->calltoken_required = CALLTOKEN_YES;
12182             } else {
12183                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12184             }
12185          } /* else if (strcasecmp(v->name,"type")) */
12186          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
12187          v = v->next;
12188          if (!v) {
12189             v = alt;
12190             alt = NULL;
12191          }
12192       }
12193       if (!peer->authmethods)
12194          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12195       ast_clear_flag64(peer, IAX_DELME);
12196       /* Make sure these are IPv4 addresses */
12197       peer->addr.sin_family = AF_INET;
12198    }
12199 
12200    if (oldha)
12201       ast_free_ha(oldha);
12202 
12203    if (!ast_strlen_zero(peer->mailbox)) {
12204       char *mailbox, *context;
12205       context = mailbox = ast_strdupa(peer->mailbox);
12206       strsep(&context, "@");
12207       if (ast_strlen_zero(context))
12208          context = "default";
12209       peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12210          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12211          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12212          AST_EVENT_IE_END);
12213    }
12214 
12215    return peer;
12216 }

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

Definition at line 5938 of file chan_iax2.c.

References ast_random().

Referenced by build_ecx_key(), and update_packet().

05939 {
05940    long tmp;
05941    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
05942       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
05943       buf += sizeof(tmp);
05944       len -= sizeof(tmp);
05945    }
05946 }

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

Create in-memory user structure from configuration.

Definition at line 12232 of file chan_iax2.c.

References iax2_user::adsi, iax2_user::amaflags, ao2_alloc, ao2_find, ao2_unlink, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag64, ast_copy_flags64, ast_false(), ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_true(), ast_variable_new(), iax2_user::authmethods, build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_user::calltoken_required, CALLTOKEN_YES, iax2_user::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, iax2_user::dbsecret, iax2_user::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_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, iax2_user::maxauthreq, ast_variable::name, iax2_user::name, ast_variable::next, iax2_context::next, OBJ_POINTER, parkinglot, prefs, iax2_user::prefs, secret, iax2_user::secret, user_destructor(), user_unref(), ast_variable::value, and iax2_user::vars.

12233 {
12234    struct iax2_user *user = NULL;
12235    struct iax2_context *con, *conl = NULL;
12236    struct ast_ha *oldha = NULL;
12237    struct iax2_context *oldcon = NULL;
12238    int format;
12239    int firstpass=1;
12240    int oldcurauthreq = 0;
12241    char *varname = NULL, *varval = NULL;
12242    struct ast_variable *tmpvar = NULL;
12243    struct iax2_user tmp_user = {
12244       .name = name,
12245    };
12246 
12247    if (!temponly) {
12248       user = ao2_find(users, &tmp_user, OBJ_POINTER);
12249       if (user && !ast_test_flag64(user, IAX_DELME))
12250          firstpass = 0;
12251    }
12252 
12253    if (user) {
12254       if (firstpass) {
12255          oldcurauthreq = user->curauthreq;
12256          oldha = user->ha;
12257          oldcon = user->contexts;
12258          user->ha = NULL;
12259          user->contexts = NULL;
12260       }
12261       /* Already in the list, remove it and it will be added back (or FREE'd) */
12262       ao2_unlink(users, user);
12263    } else {
12264       user = ao2_alloc(sizeof(*user), user_destructor);
12265    }
12266    
12267    if (user) {
12268       if (firstpass) {
12269          ast_string_field_free_memory(user);
12270          memset(user, 0, sizeof(struct iax2_user));
12271          if (ast_string_field_init(user, 32)) {
12272             user = user_unref(user);
12273             goto cleanup;
12274          }
12275          user->maxauthreq = maxauthreq;
12276          user->curauthreq = oldcurauthreq;
12277          user->prefs = prefs;
12278          user->capability = iax2_capability;
12279          user->encmethods = iax2_encryption;
12280          user->adsi = adsi;
12281          user->calltoken_required = CALLTOKEN_DEFAULT;
12282          ast_string_field_set(user, name, name);
12283          ast_string_field_set(user, language, language);
12284          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);
12285          ast_clear_flag64(user, IAX_HASCALLERID);
12286          ast_string_field_set(user, cid_name, "");
12287          ast_string_field_set(user, cid_num, "");
12288          ast_string_field_set(user, accountcode, accountcode);
12289          ast_string_field_set(user, mohinterpret, mohinterpret);
12290          ast_string_field_set(user, mohsuggest, mohsuggest);
12291       }
12292       if (!v) {
12293          v = alt;
12294          alt = NULL;
12295       }
12296       while(v) {
12297          if (!strcasecmp(v->name, "context")) {
12298             con = build_context(v->value);
12299             if (con) {
12300                if (conl)
12301                   conl->next = con;
12302                else
12303                   user->contexts = con;
12304                conl = con;
12305             }
12306          } else if (!strcasecmp(v->name, "permit") ||
12307                   !strcasecmp(v->name, "deny")) {
12308             user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12309          } else if (!strcasecmp(v->name, "setvar")) {
12310             varname = ast_strdupa(v->value);
12311             if (varname && (varval = strchr(varname,'='))) {
12312                *varval = '\0';
12313                varval++;
12314                if((tmpvar = ast_variable_new(varname, varval, ""))) {
12315                   tmpvar->next = user->vars; 
12316                   user->vars = tmpvar;
12317                }
12318             }
12319          } else if (!strcasecmp(v->name, "allow")) {
12320             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12321          } else if (!strcasecmp(v->name, "disallow")) {
12322             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12323          } else if (!strcasecmp(v->name, "trunk")) {
12324             ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 
12325             if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
12326                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12327                ast_clear_flag64(user, IAX_TRUNK);
12328             }
12329          } else if (!strcasecmp(v->name, "auth")) {
12330             user->authmethods = get_auth_methods(v->value);
12331          } else if (!strcasecmp(v->name, "encryption")) {
12332             user->encmethods |= get_encrypt_methods(v->value);
12333             if (!user->encmethods) {
12334                ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12335             }
12336          } else if (!strcasecmp(v->name, "forceencryption")) {
12337             if (ast_false(v->value)) {
12338                ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12339             } else {
12340                user->encmethods |= get_encrypt_methods(v->value);
12341                if (user->encmethods) {
12342                   ast_set_flag64(user, IAX_FORCE_ENCRYPT);
12343                }
12344             }
12345          } else if (!strcasecmp(v->name, "transfer")) {
12346             if (!strcasecmp(v->value, "mediaonly")) {
12347                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12348             } else if (ast_true(v->value)) {
12349                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12350             } else
12351                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12352          } else if (!strcasecmp(v->name, "codecpriority")) {
12353             if(!strcasecmp(v->value, "caller"))
12354                ast_set_flag64(user, IAX_CODEC_USER_FIRST);
12355             else if(!strcasecmp(v->value, "disabled"))
12356                ast_set_flag64(user, IAX_CODEC_NOPREFS);
12357             else if(!strcasecmp(v->value, "reqonly")) {
12358                ast_set_flag64(user, IAX_CODEC_NOCAP);
12359                ast_set_flag64(user, IAX_CODEC_NOPREFS);
12360             }
12361          } else if (!strcasecmp(v->name, "immediate")) {
12362             ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
12363          } else if (!strcasecmp(v->name, "jitterbuffer")) {
12364             ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
12365          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12366             ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12367          } else if (!strcasecmp(v->name, "dbsecret")) {
12368             ast_string_field_set(user, dbsecret, v->value);
12369          } else if (!strcasecmp(v->name, "secret")) {
12370             if (!ast_strlen_zero(user->secret)) {
12371                char *old = ast_strdupa(user->secret);
12372 
12373                ast_string_field_build(user, secret, "%s;%s", old, v->value);
12374             } else
12375                ast_string_field_set(user, secret, v->value);
12376          } else if (!strcasecmp(v->name, "callerid")) {
12377             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12378                char name2[80];
12379                char num2[80];
12380                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12381                ast_string_field_set(user, cid_name, name2);
12382                ast_string_field_set(user, cid_num, num2);
12383                ast_set_flag64(user, IAX_HASCALLERID);
12384             } else {
12385                ast_clear_flag64(user, IAX_HASCALLERID);
12386                ast_string_field_set(user, cid_name, "");
12387                ast_string_field_set(user, cid_num, "");
12388             }
12389          } else if (!strcasecmp(v->name, "fullname")) {
12390             if (!ast_strlen_zero(v->value)) {
12391                ast_string_field_set(user, cid_name, v->value);
12392                ast_set_flag64(user, IAX_HASCALLERID);
12393             } else {
12394                ast_string_field_set(user, cid_name, "");
12395                if (ast_strlen_zero(user->cid_num))
12396                   ast_clear_flag64(user, IAX_HASCALLERID);
12397             }
12398          } else if (!strcasecmp(v->name, "cid_number")) {
12399             if (!ast_strlen_zero(v->value)) {
12400                ast_string_field_set(user, cid_num, v->value);
12401                ast_set_flag64(user, IAX_HASCALLERID);
12402             } else {
12403                ast_string_field_set(user, cid_num, "");
12404                if (ast_strlen_zero(user->cid_name))
12405                   ast_clear_flag64(user, IAX_HASCALLERID);
12406             }
12407          } else if (!strcasecmp(v->name, "accountcode")) {
12408             ast_string_field_set(user, accountcode, v->value);
12409          } else if (!strcasecmp(v->name, "mohinterpret")) {
12410             ast_string_field_set(user, mohinterpret, v->value);
12411          } else if (!strcasecmp(v->name, "mohsuggest")) {
12412             ast_string_field_set(user, mohsuggest, v->value);
12413          } else if (!strcasecmp(v->name, "parkinglot")) {
12414             ast_string_field_set(user, parkinglot, v->value);
12415          } else if (!strcasecmp(v->name, "language")) {
12416             ast_string_field_set(user, language, v->value);
12417          } else if (!strcasecmp(v->name, "amaflags")) {
12418             format = ast_cdr_amaflags2int(v->value);
12419             if (format < 0) {
12420                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12421             } else {
12422                user->amaflags = format;
12423             }
12424          } else if (!strcasecmp(v->name, "inkeys")) {
12425             ast_string_field_set(user, inkeys, v->value);
12426          } else if (!strcasecmp(v->name, "maxauthreq")) {
12427             user->maxauthreq = atoi(v->value);
12428             if (user->maxauthreq < 0)
12429                user->maxauthreq = 0;
12430          } else if (!strcasecmp(v->name, "adsi")) {
12431             user->adsi = ast_true(v->value);
12432          } else if (!strcasecmp(v->name, "connectedline")) {
12433             if (ast_true(v->value)) {
12434                ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12435             } else if (!strcasecmp(v->value, "send")) {
12436                ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
12437                ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
12438             } else if (!strcasecmp(v->value, "receive")) {
12439                ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
12440                ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
12441             } else {
12442                ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12443             }
12444          } else if (!strcasecmp(v->name, "requirecalltoken")) {
12445             /* default is required unless in optional ip list */
12446             if (ast_false(v->value)) {
12447                user->calltoken_required = CALLTOKEN_NO;
12448             } else if (!strcasecmp(v->value, "auto")) {
12449                user->calltoken_required = CALLTOKEN_AUTO;
12450             } else if (ast_true(v->value)) {
12451                user->calltoken_required = CALLTOKEN_YES;
12452             } else {
12453                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12454             }
12455          } /* else if (strcasecmp(v->name,"type")) */
12456          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
12457          v = v->next;
12458          if (!v) {
12459             v = alt;
12460             alt = NULL;
12461          }
12462       }
12463       if (!user->authmethods) {
12464          if (!ast_strlen_zero(user->secret)) {
12465             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12466             if (!ast_strlen_zero(user->inkeys))
12467                user->authmethods |= IAX_AUTH_RSA;
12468          } else if (!ast_strlen_zero(user->inkeys)) {
12469             user->authmethods = IAX_AUTH_RSA;
12470          } else {
12471             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12472          }
12473       }
12474       ast_clear_flag64(user, IAX_DELME);
12475    }
12476 cleanup:
12477    if (oldha)
12478       ast_free_ha(oldha);
12479    if (oldcon)
12480       free_context(oldcon);
12481    return user;
12482 }

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

Definition at line 13101 of file chan_iax2.c.

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

Referenced by find_cache().

13102 {
13103    struct sockaddr_in sin;
13104    int x;
13105    int callno;
13106    struct iax_ie_data ied;
13107    struct create_addr_info cai;
13108    struct parsed_dial_string pds;
13109    char *tmpstr;
13110 
13111    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13112       /* Look for an *exact match* call.  Once a call is negotiated, it can only
13113          look up entries for a single context */
13114       if (!ast_mutex_trylock(&iaxsl[x])) {
13115          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13116             return x;
13117          ast_mutex_unlock(&iaxsl[x]);
13118       }
13119    }
13120 
13121    /* No match found, we need to create a new one */
13122 
13123    memset(&cai, 0, sizeof(cai));
13124    memset(&ied, 0, sizeof(ied));
13125    memset(&pds, 0, sizeof(pds));
13126 
13127    tmpstr = ast_strdupa(data);
13128    parse_dial_string(tmpstr, &pds);
13129 
13130    if (ast_strlen_zero(pds.peer)) {
13131       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13132       return -1;
13133    }
13134 
13135    /* Populate our address from the given */
13136    if (create_addr(pds.peer, NULL, &sin, &cai))
13137       return -1;
13138 
13139    ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13140       pds.peer, pds.username, pds.password, pds.context);
13141 
13142    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13143    if (callno < 1) {
13144       ast_log(LOG_WARNING, "Unable to create call\n");
13145       return -1;
13146    }
13147 
13148    ast_string_field_set(iaxs[callno], dproot, data);
13149    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13150 
13151    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13152    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13153    /* the string format is slightly different from a standard dial string,
13154       because the context appears in the 'exten' position
13155    */
13156    if (pds.exten)
13157       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13158    if (pds.username)
13159       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13160    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13161    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13162    /* Keep password handy */
13163    if (pds.password)
13164       ast_string_field_set(iaxs[callno], secret, pds.password);
13165    if (pds.key)
13166       ast_string_field_set(iaxs[callno], outkey, pds.key);
13167    /* Start the call going */
13168    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
13169    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13170 
13171    return callno;
13172 }

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

Definition at line 5790 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 ast_rtp_read(), and schedule_delivery().

05791 {
05792    /* Returns where in "receive time" we are.  That is, how many ms
05793       since we received (or would have received) the frame with timestamp 0 */
05794    int ms;
05795 #ifdef IAXTESTS
05796    int jit;
05797 #endif /* IAXTESTS */
05798    /* Setup rxcore if necessary */
05799    if (ast_tvzero(p->rxcore)) {
05800       p->rxcore = ast_tvnow();
05801       if (iaxdebug)
05802          ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
05803                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
05804       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
05805 #if 1
05806       if (iaxdebug)
05807          ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
05808                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
05809 #endif
05810    }
05811 
05812    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
05813 #ifdef IAXTESTS
05814    if (test_jit) {
05815       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
05816          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
05817          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
05818             jit = -jit;
05819          ms += jit;
05820       }
05821    }
05822    if (test_late) {
05823       ms += test_late;
05824       test_late = 0;
05825    }
05826 #endif /* IAXTESTS */
05827    return ms;
05828 }

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

Definition at line 5657 of file chan_iax2.c.

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

Referenced by iax2_send(), and socket_process().

05658 {
05659    int ms;
05660    int voice = 0;
05661    int genuine = 0;
05662    int adjust;
05663    int rate = ast_format_rate(f->subclass) / 1000;
05664    struct timeval *delivery = NULL;
05665 
05666 
05667    /* What sort of frame do we have?: voice is self-explanatory
05668       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
05669       non-genuine frames are CONTROL frames [ringing etc], DTMF
05670       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
05671       the others need a timestamp slaved to the voice frames so that they go in sequence
05672    */
05673    if (f) {
05674       if (f->frametype == AST_FRAME_VOICE) {
05675          voice = 1;
05676          delivery = &f->delivery;
05677       } else if (f->frametype == AST_FRAME_IAX) {
05678          genuine = 1;
05679       } else if (f->frametype == AST_FRAME_CNG) {
05680          p->notsilenttx = 0;  
05681       }
05682    }
05683    if (ast_tvzero(p->offset)) {
05684       p->offset = ast_tvnow();
05685       /* Round to nearest 20ms for nice looking traces */
05686       p->offset.tv_usec -= p->offset.tv_usec % 20000;
05687    }
05688    /* If the timestamp is specified, just send it as is */
05689    if (ts)
05690       return ts;
05691    /* If we have a time that the frame arrived, always use it to make our timestamp */
05692    if (delivery && !ast_tvzero(*delivery)) {
05693       ms = ast_tvdiff_ms(*delivery, p->offset);
05694       if (ms < 0) {
05695          ms = 0;
05696       }
05697       if (iaxdebug)
05698          ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05699    } else {
05700       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05701       if (ms < 0)
05702          ms = 0;
05703       if (voice) {
05704          /* On a voice frame, use predicted values if appropriate */
05705          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05706             /* Adjust our txcore, keeping voice and non-voice synchronized */
05707             /* AN EXPLANATION:
05708                When we send voice, we usually send "calculated" timestamps worked out
05709                on the basis of the number of samples sent. When we send other frames,
05710                we usually send timestamps worked out from the real clock.
05711                The problem is that they can tend to drift out of step because the 
05712                   source channel's clock and our clock may not be exactly at the same rate.
05713                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
05714                for this call.  Moving it adjusts timestamps for non-voice frames.
05715                We make the adjustment in the style of a moving average.  Each time we
05716                adjust p->offset by 10% of the difference between our clock-derived
05717                timestamp and the predicted timestamp.  That's why you see "10000"
05718                below even though IAX2 timestamps are in milliseconds.
05719                The use of a moving average avoids offset moving too radically.
05720                Generally, "adjust" roams back and forth around 0, with offset hardly
05721                changing at all.  But if a consistent different starts to develop it
05722                will be eliminated over the course of 10 frames (200-300msecs) 
05723             */
05724             adjust = (ms - p->nextpred);
05725             if (adjust < 0)
05726                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05727             else if (adjust > 0)
05728                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05729 
05730             if (!p->nextpred) {
05731                p->nextpred = ms; /*f->samples / rate;*/
05732                if (p->nextpred <= p->lastsent)
05733                   p->nextpred = p->lastsent + 3;
05734             }
05735             ms = p->nextpred;
05736          } else {
05737                 /* in this case, just use the actual
05738             * time, since we're either way off
05739             * (shouldn't happen), or we're  ending a
05740             * silent period -- and seed the next
05741             * predicted time.  Also, round ms to the
05742             * next multiple of frame size (so our
05743             * silent periods are multiples of
05744             * frame size too) */
05745 
05746             if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05747                ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05748                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05749 
05750             if (f->samples >= rate) /* check to make sure we dont core dump */
05751             {
05752                int diff = ms % (f->samples / rate);
05753                if (diff)
05754                    ms += f->samples/rate - diff;
05755             }
05756 
05757             p->nextpred = ms;
05758             p->notsilenttx = 1;
05759          }
05760       } else if ( f->frametype == AST_FRAME_VIDEO ) {
05761          /*
05762          * IAX2 draft 03 says that timestamps MUST be in order.
05763          * It does not say anything about several frames having the same timestamp
05764          * When transporting video, we can have a frame that spans multiple iax packets
05765          * (so called slices), so it would make sense to use the same timestamp for all of
05766          * them
05767          * We do want to make sure that frames don't go backwards though
05768          */
05769          if ( (unsigned int)ms < p->lastsent )
05770             ms = p->lastsent;
05771       } else {
05772          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
05773             it's a genuine frame */
05774          if (genuine) {
05775             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
05776             if (ms <= p->lastsent)
05777                ms = p->lastsent + 3;
05778          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05779             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
05780             ms = p->lastsent + 3;
05781          }
05782       }
05783    }
05784    p->lastsent = ms;
05785    if (voice)
05786       p->nextpred = p->nextpred + f->samples / rate;
05787    return ms;
05788 }

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

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

05614 {
05615    unsigned long int mssincetx; /* unsigned to handle overflows */
05616    long int ms, pred;
05617 
05618    tpeer->trunkact = *now;
05619    mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05620    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05621       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
05622       tpeer->txtrunktime = *now;
05623       tpeer->lastsent = 999999;
05624    }
05625    /* Update last transmit time now */
05626    tpeer->lasttxtime = *now;
05627    
05628    /* Calculate ms offset */
05629    ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05630    /* Predict from last value */
05631    pred = tpeer->lastsent + sampms;
05632    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05633       ms = pred;
05634    
05635    /* We never send the same timestamp twice, so fudge a little if we must */
05636    if (ms == tpeer->lastsent)
05637       ms = tpeer->lastsent + 1;
05638    tpeer->lastsent = ms;
05639    return ms;
05640 }

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

Definition at line 2527 of file chan_iax2.c.

References ast_random().

Referenced by create_callno_pools().

02528 {
02529    return abs(ast_random());
02530 }

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

Definition at line 2075 of file chan_iax2.c.

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

Referenced by handle_call_token().

02076 {
02077    struct addr_range *addr_range;
02078    struct iax2_peer *peer = NULL;
02079    struct iax2_user *user = NULL;
02080    /* if no username is given, check for guest accounts */
02081    const char *find = S_OR(name, "guest");
02082    int res = 1;  /* required by default */
02083    int optional = 0;
02084    enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02085    /* There are only two cases in which calltoken validation is not required.
02086     * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
02087     *         the peer definition has not set the requirecalltoken option.
02088     * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
02089     */
02090 
02091    /* ----- Case 1 ----- */
02092    if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02093       ao2_ref(addr_range, -1);
02094       optional = 1;
02095    }
02096 
02097    /* ----- Case 2 ----- */
02098    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02099       calltoken_required = user->calltoken_required;
02100    } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02101       calltoken_required = user->calltoken_required;
02102    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02103       calltoken_required = peer->calltoken_required;
02104    } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02105       calltoken_required = peer->calltoken_required;
02106    }
02107 
02108    if (peer) {
02109       peer_unref(peer);
02110    }
02111    if (user) {
02112       user_unref(user);
02113    }
02114 
02115    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);
02116    if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02117       (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02118       res = 0;
02119    }
02120 
02121    return res;
02122 }

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

Definition at line 7278 of file chan_iax2.c.

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

Referenced by socket_process().

07279 {
07280    /* Start pessimistic */
07281    int res = -1;
07282    int version = 2;
07283    struct iax2_user *user = NULL, *best = NULL;
07284    int bestscore = 0;
07285    int gotcapability = 0;
07286    struct ast_variable *v = NULL, *tmpvar = NULL;
07287    struct ao2_iterator i;
07288 
07289    if (!iaxs[callno])
07290       return res;
07291    if (ies->called_number)
07292       ast_string_field_set(iaxs[callno], exten, ies->called_number);
07293    if (ies->calling_number) {
07294       if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 
07295          ast_shrink_phone_number(ies->calling_number);
07296       }
07297       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07298    }
07299    if (ies->calling_name)
07300       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07301    if (ies->calling_ani)
07302       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07303    if (ies->dnid)
07304       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07305    if (ies->rdnis)
07306       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07307    if (ies->called_context)
07308       ast_string_field_set(iaxs[callno], context, ies->called_context);
07309    if (ies->language)
07310       ast_string_field_set(iaxs[callno], language, ies->language);
07311    if (ies->username)
07312       ast_string_field_set(iaxs[callno], username, ies->username);
07313    if (ies->calling_ton > -1)
07314       iaxs[callno]->calling_ton = ies->calling_ton;
07315    if (ies->calling_tns > -1)
07316       iaxs[callno]->calling_tns = ies->calling_tns;
07317    if (ies->calling_pres > -1)
07318       iaxs[callno]->calling_pres = ies->calling_pres;
07319    if (ies->format)
07320       iaxs[callno]->peerformat = ies->format;
07321    if (ies->adsicpe)
07322       iaxs[callno]->peeradsicpe = ies->adsicpe;
07323    if (ies->capability) {
07324       gotcapability = 1;
07325       iaxs[callno]->peercapability = ies->capability;
07326    } 
07327    if (ies->version)
07328       version = ies->version;
07329 
07330    /* Use provided preferences until told otherwise for actual preferences */
07331    if(ies->codec_prefs) {
07332       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07333       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07334    }
07335 
07336    if (!gotcapability) 
07337       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07338    if (version > IAX_PROTO_VERSION) {
07339       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
07340          ast_inet_ntoa(sin->sin_addr), version);
07341       return res;
07342    }
07343    /* Search the userlist for a compatible entry, and fill in the rest */
07344    i = ao2_iterator_init(users, 0);
07345    while ((user = ao2_iterator_next(&i))) {
07346       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
07347          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
07348          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
07349          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
07350               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
07351          if (!ast_strlen_zero(iaxs[callno]->username)) {
07352             /* Exact match, stop right now. */
07353             if (best)
07354                user_unref(best);
07355             best = user;
07356             break;
07357          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07358             /* No required authentication */
07359             if (user->ha) {
07360                /* There was host authentication and we passed, bonus! */
07361                if (bestscore < 4) {
07362                   bestscore = 4;
07363                   if (best)
07364                      user_unref(best);
07365                   best = user;
07366                   continue;
07367                }
07368             } else {
07369                /* No host access, but no secret, either, not bad */
07370                if (bestscore < 3) {
07371                   bestscore = 3;
07372                   if (best)
07373                      user_unref(best);
07374                   best = user;
07375                   continue;
07376                }
07377             }
07378          } else {
07379             if (user->ha) {
07380                /* Authentication, but host access too, eh, it's something.. */
07381                if (bestscore < 2) {
07382                   bestscore = 2;
07383                   if (best)
07384                      user_unref(best);
07385                   best = user;
07386                   continue;
07387                }
07388             } else {
07389                /* Authentication and no host access...  This is our baseline */
07390                if (bestscore < 1) {
07391                   bestscore = 1;
07392                   if (best)
07393                      user_unref(best);
07394                   best = user;
07395                   continue;
07396                }
07397             }
07398          }
07399       }
07400       user_unref(user);
07401    }
07402    ao2_iterator_destroy(&i);
07403    user = best;
07404    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07405       user = realtime_user(iaxs[callno]->username, sin);
07406       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
07407           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
07408          user = user_unref(user);
07409       }
07410    }
07411    if (user) {
07412       /* We found our match (use the first) */
07413       /* copy vars */
07414       for (v = user->vars ; v ; v = v->next) {
07415          if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07416             tmpvar->next = iaxs[callno]->vars; 
07417             iaxs[callno]->vars = tmpvar;
07418          }
07419       }
07420       /* If a max AUTHREQ restriction is in place, activate it */
07421       if (user->maxauthreq > 0)
07422          ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07423       iaxs[callno]->prefs = user->prefs;
07424       ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07425       iaxs[callno]->encmethods = user->encmethods;
07426       /* Store the requested username if not specified */
07427       if (ast_strlen_zero(iaxs[callno]->username))
07428          ast_string_field_set(iaxs[callno], username, user->name);
07429       /* Store whether this is a trunked call, too, of course, and move if appropriate */
07430       ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07431       iaxs[callno]->capability = user->capability;
07432       /* And use the default context */
07433       if (ast_strlen_zero(iaxs[callno]->context)) {
07434          if (user->contexts)
07435             ast_string_field_set(iaxs[callno], context, user->contexts->context);
07436          else
07437             ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07438       }
07439       /* And any input keys */
07440       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07441       /* And the permitted authentication methods */
07442       iaxs[callno]->authmethods = user->authmethods;
07443       iaxs[callno]->adsi = user->adsi;
07444       /* If the user has callerid, override the remote caller id. */
07445       if (ast_test_flag64(user, IAX_HASCALLERID)) {
07446          iaxs[callno]->calling_tns = 0;
07447          iaxs[callno]->calling_ton = 0;
07448          ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07449          ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07450          ast_string_field_set(iaxs[callno], ani, user->cid_num);
07451          iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07452       } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07453          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07454       } /* else user is allowed to set their own CID settings */
07455       if (!ast_strlen_zero(user->accountcode))
07456          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07457       if (!ast_strlen_zero(user->mohinterpret))
07458          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07459       if (!ast_strlen_zero(user->mohsuggest))
07460          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07461       if (!ast_strlen_zero(user->parkinglot))
07462          ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07463       if (user->amaflags)
07464          iaxs[callno]->amaflags = user->amaflags;
07465       if (!ast_strlen_zero(user->language))
07466          ast_string_field_set(iaxs[callno], language, user->language);
07467       ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 
07468       /* Keep this check last */
07469       if (!ast_strlen_zero(user->dbsecret)) {
07470          char *family, *key=NULL;
07471          char buf[80];
07472          family = ast_strdupa(user->dbsecret);
07473          key = strchr(family, '/');
07474          if (key) {
07475             *key = '\0';
07476             key++;
07477          }
07478          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07479             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07480          else
07481             ast_string_field_set(iaxs[callno], secret, buf);
07482       } else
07483          ast_string_field_set(iaxs[callno], secret, user->secret);
07484       res = 0;
07485       user = user_unref(user);
07486    } else {
07487        /* user was not found, but we should still fake an AUTHREQ.
07488         * Set authmethods to the last known authmethod used by the system
07489         * Set a fake secret, it's not looked at, just required to attempt authentication.
07490         * Set authrej so the AUTHREP is rejected without even looking at its contents */
07491       iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07492       ast_string_field_set(iaxs[callno], secret, "badsecret");
07493       iaxs[callno]->authrej = 1;
07494       if (!ast_strlen_zero(iaxs[callno]->username)) {
07495          /* only send the AUTHREQ if a username was specified. */
07496          res = 0;
07497       }
07498    }
07499    ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07500    return res;
07501 }

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

Definition at line 9061 of file chan_iax2.c.

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

Referenced by socket_process().

09062 {
09063    unsigned int ourver;
09064    char rsi[80];
09065    snprintf(rsi, sizeof(rsi), "si-%s", si);
09066    if (iax_provision_version(&ourver, rsi, 1))
09067       return 0;
09068    ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09069    if (ourver != ver) 
09070       iax2_provision(sin, sockfd, NULL, rsi, 1);
09071    return 0;
09072 }

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

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

Referenced by peer_set_srcaddr().

11823 {
11824    int sd;
11825    int res;
11826    
11827    sd = socket(AF_INET, SOCK_DGRAM, 0);
11828    if (sd < 0) {
11829       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
11830       return -1;
11831    }
11832 
11833    res = bind(sd, sa, salen);
11834    if (res < 0) {
11835       ast_debug(1, "Can't bind: %s\n", strerror(errno));
11836       close(sd);
11837       return 1;
11838    }
11839 
11840    close(sd);
11841    return 0;
11842 }

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

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

08056 {
08057    char exten[256] = "";
08058    int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08059    struct iax2_dpcache *dp = NULL;
08060    
08061    if (ies->called_number)
08062       ast_copy_string(exten, ies->called_number, sizeof(exten));
08063    
08064    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08065       status = CACHE_FLAG_EXISTS;
08066    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08067       status = CACHE_FLAG_CANEXIST;
08068    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08069       status = CACHE_FLAG_NONEXISTENT;
08070 
08071    if (ies->refresh)
08072       expiry = ies->refresh;
08073    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08074       matchmore = CACHE_FLAG_MATCHMORE;
08075    
08076    AST_LIST_LOCK(&dpcache);
08077    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08078       if (strcmp(dp->exten, exten))
08079          continue;
08080       AST_LIST_REMOVE_CURRENT(peer_list);
08081       dp->callno = 0;
08082       dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08083       if (dp->flags & CACHE_FLAG_PENDING) {
08084          dp->flags &= ~CACHE_FLAG_PENDING;
08085          dp->flags |= status;
08086          dp->flags |= matchmore;
08087       }
08088       /* Wake up waiters */
08089       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08090          if (dp->waiters[x] > -1) {
08091             if (write(dp->waiters[x], "asdf", 4) < 0) {
08092             }
08093          }
08094       }
08095    }
08096    AST_LIST_TRAVERSE_SAFE_END;
08097    AST_LIST_UNLOCK(&dpcache);
08098 
08099    return 0;
08100 }

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

Definition at line 3690 of file chan_iax2.c.

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

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

03691 {
03692    int which = 0;
03693    struct iax2_peer *peer;
03694    char *res = NULL;
03695    int wordlen = strlen(word);
03696    struct ao2_iterator i;
03697 
03698    i = ao2_iterator_init(peers, 0);
03699    while ((peer = ao2_iterator_next(&i))) {
03700       if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03701          && (!flags || ast_test_flag64(peer, flags))) {
03702          res = ast_strdup(peer->name);
03703          peer_unref(peer);
03704          break;
03705       }
03706       peer_unref(peer);
03707    }
03708    ao2_iterator_destroy(&i);
03709 
03710    return res;
03711 }

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

Definition at line 6647 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_unregister().

06648 {
06649    int which = 0;
06650    struct iax2_peer *p = NULL;
06651    char *res = NULL;
06652    int wordlen = strlen(word);
06653 
06654    /* 0 - iax2; 1 - unregister; 2 - <peername> */
06655    if (pos == 2) {
06656       struct ao2_iterator i = ao2_iterator_init(peers, 0);
06657       while ((p = ao2_iterator_next(&i))) {
06658          if (!strncasecmp(p->name, word, wordlen) && 
06659             ++which > state && p->expire > 0) {
06660             res = ast_strdup(p->name);
06661             peer_unref(p);
06662             break;
06663          }
06664          peer_unref(p);
06665       }
06666       ao2_iterator_destroy(&i);
06667    }
06668 
06669    return res;
06670 }

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

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

Referenced by socket_process().

08103 {
08104    int peercallno = 0;
08105    struct chan_iax2_pvt *pvt = iaxs[callno];
08106    struct iax_frame *cur;
08107    jb_frame frame;
08108 
08109    if (ies->callno)
08110       peercallno = ies->callno;
08111 
08112    if (peercallno < 1) {
08113       ast_log(LOG_WARNING, "Invalid transfer request\n");
08114       return -1;
08115    }
08116    remove_by_transfercallno(pvt);
08117    /* since a transfer has taken place, the address will change.
08118     * This must be accounted for in the peercnts table.  Remove
08119     * the old address and add the new one */
08120    peercnt_remove_by_addr(&pvt->addr);
08121    peercnt_add(&pvt->transfer);
08122    /* now copy over the new address */
08123    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08124    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08125    /* Reset sequence numbers */
08126    pvt->oseqno = 0;
08127    pvt->rseqno = 0;
08128    pvt->iseqno = 0;
08129    pvt->aseqno = 0;
08130 
08131    if (pvt->peercallno) {
08132       remove_by_peercallno(pvt);
08133    }
08134    pvt->peercallno = peercallno;
08135    /*this is where the transfering call swiches hash tables */
08136    store_by_peercallno(pvt);
08137    pvt->transferring = TRANSFER_NONE;
08138    pvt->svoiceformat = -1;
08139    pvt->voiceformat = 0;
08140    pvt->svideoformat = -1;
08141    pvt->videoformat = 0;
08142    pvt->transfercallno = -1;
08143    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08144    memset(&pvt->offset, 0, sizeof(pvt->offset));
08145    /* reset jitterbuffer */
08146    while(jb_getall(pvt->jb,&frame) == JB_OK)
08147       iax2_frame_free(frame.data);
08148    jb_reset(pvt->jb);
08149    pvt->lag = 0;
08150    pvt->last = 0;
08151    pvt->lastsent = 0;
08152    pvt->nextpred = 0;
08153    pvt->pingtime = DEFAULT_RETRY_TIME;
08154    AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08155       /* We must cancel any packets that would have been transmitted
08156          because now we're talking to someone new.  It's okay, they
08157          were transmitted to someone that didn't care anyway. */
08158       cur->retries = -1;
08159    }
08160    return 0;
08161 }

static unsigned char compress_subclass ( int  subclass  )  [static]

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

01510 {
01511    int x;
01512    int power=-1;
01513    /* If it's 128 or smaller, just return it */
01514    if (subclass < IAX_FLAG_SC_LOG)
01515       return subclass;
01516    /* Otherwise find its power */
01517    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01518       if (subclass & (1 << x)) {
01519          if (power > -1) {
01520             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01521             return 0;
01522          } else
01523             power = x;
01524       }
01525    }
01526    return power | IAX_FLAG_SC_LOG;
01527 }

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

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

09075 {
09076    jb_info stats;
09077    jb_getinfo(pvt->jb, &stats);
09078    
09079    memset(iep, 0, sizeof(*iep));
09080 
09081    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09082    if(stats.frames_in == 0) stats.frames_in = 1;
09083    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09084    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09085    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09086    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09087    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09088 }

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

Definition at line 4407 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_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, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.

04408 {
04409    struct iax2_peer *peer;
04410    int res = -1;
04411    struct ast_codec_pref ourprefs;
04412 
04413    ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04414    cai->sockfd = defaultsockfd;
04415    cai->maxtime = 0;
04416    sin->sin_family = AF_INET;
04417 
04418    if (!(peer = find_peer(peername, 1))) {
04419       cai->found = 0;
04420       if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
04421          ast_log(LOG_WARNING, "No such host: %s\n", peername);
04422          return -1;
04423       }
04424       sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04425       /* use global iax prefs for unknown peer/user */
04426       /* But move the calling channel's native codec to the top of the preference list */
04427       memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04428       if (c)
04429          ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04430       ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04431       return 0;
04432    }
04433 
04434    cai->found = 1;
04435    
04436    /* if the peer has no address (current or default), return failure */
04437    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
04438       goto return_unref;
04439 
04440    /* if the peer is being monitored and is currently unreachable, return failure */
04441    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04442       goto return_unref;
04443 
04444    ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04445    cai->maxtime = peer->maxms;
04446    cai->capability = peer->capability;
04447    cai->encmethods = peer->encmethods;
04448    cai->sockfd = peer->sockfd;
04449    cai->adsi = peer->adsi;
04450    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04451    /* Move the calling channel's native codec to the top of the preference list */
04452    if (c) {
04453       ast_debug(1, "prepending %x to prefs\n", c->nativeformats);
04454       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04455    }
04456    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04457    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04458    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04459    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04460    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04461    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04462    ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04463    ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04464    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04465    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04466    if (ast_strlen_zero(peer->dbsecret)) {
04467       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04468    } else {
04469       char *family;
04470       char *key = NULL;
04471 
04472       family = ast_strdupa(peer->dbsecret);
04473       key = strchr(family, '/');
04474       if (key)
04475          *key++ = '\0';
04476       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04477          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04478          goto return_unref;
04479       }
04480    }
04481 
04482    if (peer->addr.sin_addr.s_addr) {
04483       sin->sin_addr = peer->addr.sin_addr;
04484       sin->sin_port = peer->addr.sin_port;
04485    } else {
04486       sin->sin_addr = peer->defaddr.sin_addr;
04487       sin->sin_port = peer->defaddr.sin_port;
04488    }
04489 
04490    res = 0;
04491 
04492 return_unref:
04493    peer_unref(peer);
04494 
04495    return res;
04496 }

static int create_callno_pools ( void   )  [static]

Definition at line 2532 of file chan_iax2.c.

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

Referenced by load_objects().

02533 {
02534    uint16_t i;
02535 
02536    if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02537       return -1;
02538    }
02539 
02540    if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02541       return -1;
02542    }
02543 
02544    /* start at 2, 0 and 1 are reserved */
02545    for (i = 2; i <= IAX_MAX_CALLS; i++) {
02546       struct callno_entry *callno_entry;
02547 
02548       if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02549          return -1;
02550       }
02551 
02552       callno_entry->callno = i;
02553 
02554       if (i < TRUNK_CALL_START) {
02555          ao2_link(callno_pool, callno_entry);
02556       } else {
02557          ao2_link(callno_pool_trunk, callno_entry);
02558       }
02559 
02560       ao2_ref(callno_entry, -1);
02561    }
02562 
02563    return 0;
02564 }

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

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

Referenced by decrypt_frame(), and update_packet().

06013 {
06014    int padding;
06015    unsigned char *workspace;
06016 
06017    workspace = alloca(*datalen);
06018    memset(f, 0, sizeof(*f));
06019    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06020       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06021       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06022          return -1;
06023       /* Decrypt */
06024       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06025 
06026       padding = 16 + (workspace[15] & 0x0f);
06027       if (iaxdebug)
06028          ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06029       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06030          return -1;
06031 
06032       *datalen -= padding;
06033       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06034       f->frametype = fh->type;
06035       if (f->frametype == AST_FRAME_VIDEO) {
06036          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06037       } else {
06038          f->subclass = uncompress_subclass(fh->csub);
06039       }
06040    } else {
06041       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06042       if (iaxdebug)
06043          ast_debug(1, "Decoding mini with length %d\n", *datalen);
06044       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06045          return -1;
06046       /* Decrypt */
06047       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06048       padding = 16 + (workspace[15] & 0x0f);
06049       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06050          return -1;
06051       *datalen -= padding;
06052       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06053    }
06054    return 0;
06055 }

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

Definition at line 6098 of file chan_iax2.c.

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

Referenced by socket_process().

06099 {
06100    int res=-1;
06101    if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06102       /* Search for possible keys, given secrets */
06103       struct MD5Context md5;
06104       unsigned char digest[16];
06105       char *tmppw, *stringp;
06106       
06107       tmppw = ast_strdupa(iaxs[callno]->secret);
06108       stringp = tmppw;
06109       while ((tmppw = strsep(&stringp, ";"))) {
06110          MD5Init(&md5);
06111          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06112          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06113          MD5Final(digest, &md5);
06114          build_encryption_keys(digest, iaxs[callno]);
06115          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06116          if (!res) {
06117             ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06118             break;
06119          }
06120       }
06121    } else 
06122       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06123    return res;
06124 }

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

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

Referenced by socket_read().

09222 {
09223    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09224    struct ast_iax2_full_hdr *fh, *cur_fh;
09225 
09226    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09227       return;
09228 
09229    pkt_buf->len = from_here->buf_len;
09230    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09231 
09232    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09233    ast_mutex_lock(&to_here->lock);
09234    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09235       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09236       if (fh->oseqno < cur_fh->oseqno) {
09237          AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09238          break;
09239       }
09240    }
09241    AST_LIST_TRAVERSE_SAFE_END
09242 
09243    if (!cur_pkt_buf)
09244       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09245    
09246    ast_mutex_unlock(&to_here->lock);
09247 }

static void delete_users ( void   )  [static]

Definition at line 12502 of file chan_iax2.c.

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

12503 {
12504    struct iax2_registry *reg;
12505 
12506    ao2_callback(users, 0, user_delme_cb, NULL);
12507 
12508    AST_LIST_LOCK(&registrations);
12509    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
12510       if (sched) {
12511          ast_sched_thread_del(sched, reg->expire);
12512       }
12513       if (reg->callno) {
12514          int callno = reg->callno;
12515          ast_mutex_lock(&iaxsl[callno]);
12516          if (iaxs[callno]) {
12517             iaxs[callno]->reg = NULL;
12518             iax2_destroy(callno);
12519          }
12520          ast_mutex_unlock(&iaxsl[callno]);
12521       }
12522       if (reg->dnsmgr)
12523          ast_dnsmgr_release(reg->dnsmgr);
12524       ast_free(reg);
12525    }
12526    AST_LIST_UNLOCK(&registrations);
12527 
12528    ao2_callback(peers, 0, peer_delme_cb, NULL);
12529 }

static void destroy_firmware ( struct iax_firmware cur  )  [static]

Definition at line 2887 of file chan_iax2.c.

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

Referenced by reload_firmware().

02888 {
02889    /* Close firmware */
02890    if (cur->fwh) {
02891       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02892    }
02893    close(cur->fd);
02894    ast_free(cur);
02895 }

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

Definition at line 8925 of file chan_iax2.c.

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

Referenced by dp_lookup_thread(), and socket_process().

08926 {
08927    unsigned short dpstatus = 0;
08928    struct iax_ie_data ied1;
08929    int mm;
08930 
08931    memset(&ied1, 0, sizeof(ied1));
08932    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
08933    /* Must be started */
08934    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
08935       dpstatus = IAX_DPSTATUS_EXISTS;
08936    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
08937       dpstatus = IAX_DPSTATUS_CANEXIST;
08938    } else {
08939       dpstatus = IAX_DPSTATUS_NONEXISTENT;
08940    }
08941    if (ast_ignore_pattern(context, callednum))
08942       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
08943    if (mm)
08944       dpstatus |= IAX_DPSTATUS_MATCHMORE;
08945    if (!skiplock)
08946       ast_mutex_lock(&iaxsl[callno]);
08947    if (iaxs[callno]) {
08948       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
08949       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
08950       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
08951       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
08952    }
08953    if (!skiplock)
08954       ast_mutex_unlock(&iaxsl[callno]);
08955 }

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

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

08958 {
08959    /* Look up for dpreq */
08960    struct dpreq_data *dpr = data;
08961    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
08962    if (dpr->callerid)
08963       ast_free(dpr->callerid);
08964    ast_free(dpr);
08965    return NULL;
08966 }

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

Definition at line 1448 of file chan_iax2.c.

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

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

01449 {
01450    ast_str_set(&buf, 0, "(");
01451    if (e & IAX_ENCRYPT_AES128) {
01452       ast_str_append(&buf, 0, "aes128");
01453    }
01454    if (e & IAX_ENCRYPT_KEYROTATE) {
01455       ast_str_append(&buf, 0, ",keyrotate");
01456    }
01457    if (ast_str_strlen(buf) > 1) {
01458       ast_str_append(&buf, 0, ")");
01459    } else {
01460       ast_str_set(&buf, 0, "No");
01461    }
01462 }

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

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

06058 {
06059    int padding;
06060    unsigned char *workspace;
06061    workspace = alloca(*datalen + 32);
06062    if (!workspace)
06063       return -1;
06064    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06065       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06066       if (iaxdebug)
06067          ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06068       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06069       padding = 16 + (padding & 0xf);
06070       memcpy(workspace, poo, padding);
06071       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06072       workspace[15] &= 0xf0;
06073       workspace[15] |= (padding & 0xf);
06074       if (iaxdebug)
06075          ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06076       *datalen += padding;
06077       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06078       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06079          memcpy(poo, workspace + *datalen - 32, 32);
06080    } else {
06081       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06082       if (iaxdebug)
06083          ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06084       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06085       padding = 16 + (padding & 0xf);
06086       memcpy(workspace, poo, padding);
06087       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06088       workspace[15] &= 0xf0;
06089       workspace[15] |= (padding & 0x0f);
06090       *datalen += padding;
06091       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06092       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06093          memcpy(poo, workspace + *datalen - 32, 32);
06094    }
06095    return 0;
06096 }

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

Definition at line 8359 of file chan_iax2.c.

References __expire_registry(), and schedule_action.

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

08360 {
08361 #ifdef SCHED_MULTITHREADED
08362    if (schedule_action(__expire_registry, data))
08363 #endif      
08364       __expire_registry(data);
08365    return 0;
08366 }

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