chan_iax2.c File Reference

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

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

Go to the source code of this file.

Data Structures

struct  active_list
struct  addr_range
struct  call_number_pool
struct  chan_iax2_pvt
struct  chan_iax2_pvt::signaling_queue
struct  create_addr_info
struct  dpcache
struct  dpreq_data
struct  dynamic_list
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_rr
struct  idle_list
struct  parsed_dial_string
struct  peercnt
struct  registrations
struct  show_peers_context
 Used in the sip_show_peers functions to pass parameters. More...
struct  signaling_queue_entry
struct  tpeers

Defines

#define ACN_FORMAT1   "%-20.25s %4u %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
#define ACN_FORMAT2   "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
#define CALLNO_ENTRY_GET_CALLNO(a)   ((a) & 0x7FFF)
#define CALLNO_ENTRY_IS_VALIDATED(a)   ((a) & 0x8000)
#define CALLNO_ENTRY_SET_VALIDATED(a)   ((a) |= 0x8000)
#define CALLNO_ENTRY_TO_PTR(a)   ((void *)(unsigned long)(a))
#define CALLNO_TO_PTR(a)   ((void *)(unsigned long)(a))
#define CALLTOKEN_HASH_FORMAT   "%s%u%d"
#define CALLTOKEN_IE_FORMAT   "%u?%s"
#define DATA_EXPORT_IAX2_PEER(MEMBER)
#define DATA_EXPORT_IAX2_USER(MEMBER)
#define DEBUG_SCHED_MULTITHREAD
#define DEBUG_SUPPORT
#define DEFAULT_CONTEXT   "default"
#define DEFAULT_DROP   3
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAX_THREAD_COUNT   100
#define DEFAULT_MAXMS   2000
#define DEFAULT_RETRY_TIME   1000
#define DEFAULT_THREAD_COUNT   10
#define DEFAULT_TRUNKDATA   640 * 10
#define DONT_RESCHEDULE   -2
#define FORMAT   "%-20.20s %-40.40s %-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   "%-45.45s %-6.6s %-10.10s %-45.45s %8d %s\n"
#define FORMAT   "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
#define FORMAT2   "%-20.20s %-40.40s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
#define FORMAT2   "%-45.45s %-6.6s %-10.10s %-45.45s %8.8s %s\n"
#define FORMAT2   "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
#define FORMATB   "%-20.20s %-40.40s %-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_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 PEERS_FORMAT   "%-15.15s %-40.40s %s %-40.40s %-6s%s %s %-11s %-32.32s\n"
#define PEERS_FORMAT2   "%-15.15s %-40.40s %s %-40.40s %-9s %s %-11s %-32.32s\n"
#define PTR_TO_CALLNO(a)   ((unsigned short)(unsigned long)(a))
#define PTR_TO_CALLNO_ENTRY(a)   ((uint16_t)(unsigned long)(a))
#define SCHED_MULTITHREADED
#define schedule_action(func, data)   __schedule_action(func, data, __PRETTY_FUNCTION__)
#define TRUNK_CALL_START   (IAX_MAX_CALLS / 2)
#define TS_GAP_FOR_JB_RESYNC   5000

Typedefs

typedef uint16_t callno_entry

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  callno_type { CALLNO_TYPE_NORMAL, CALLNO_TYPE_TRUNK }
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 ast_sockaddr *addr, int new, int sockfd, int return_locked, int check_dcallno)
static void __get_from_jb (const void *p)
static void __iax2_do_register_s (const void *data)
static void __iax2_poke_noanswer (const void *data)
static void __iax2_poke_peer_s (const void *data)
static int __iax2_show_peers (int fd, int *total, struct mansession *s, const int argc, const char *const argv[])
static void __reg_module (void)
static int __schedule_action (void(*func)(const void *data), const void *data, const char *funcname)
static int __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final)
static void __send_lagrq (const void *data)
static void __send_ping (const void *data)
static int __unload_module (void)
static void __unreg_module (void)
static void _iax2_show_peers_one (int fd, struct mansession *s, struct show_peers_context *cont, struct iax2_peer *peer)
static int acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen)
static int acf_iaxvar_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int acf_iaxvar_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
static void acl_change_stasis_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
static void acl_change_stasis_subscribe (void)
static void acl_change_stasis_unsubscribe (void)
static int add_calltoken_ignore (const char *addr)
static void add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
static int addr_range_cmp_cb (void *obj, void *arg, int flags)
static int addr_range_delme_cb (void *obj, void *arg, int flags)
static int addr_range_hash_cb (const void *obj, const int flags)
static int addr_range_match_address_cb (void *obj, void *arg, int flags)
static int apply_context (struct iax2_context *con, const char *context)
static int ast_cli_netstats (struct mansession *s, int fd, int limit_fmt)
 AST_DATA_STRUCTURE (iax2_user, DATA_EXPORT_IAX2_USER)
 AST_DATA_STRUCTURE (iax2_peer, DATA_EXPORT_IAX2_PEER)
static struct ast_channelast_iax2_new (int callno, int state, iax2_format capability, struct iax2_codec_pref *prefs, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, unsigned int cachable)
 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 ast_sockaddr *addr, struct chan_iax2_pvt *pvt)
static int authenticate_reply (struct chan_iax2_pvt *p, struct ast_sockaddr *addr, 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 calltoken_required (struct ast_sockaddr *addr, const char *name, int subclass)
static int check_access (int callno, struct ast_sockaddr *addr, struct iax_ies *ies)
static int check_provisioning (struct ast_sockaddr *addr, int sockfd, char *si, unsigned int ver)
static int check_srcaddr (struct ast_sockaddr *addr)
 Check if address can be used as packet source.
static void cleanup_thread_list (void *head)
static struct ast_formatcodec_choose_from_prefs (struct iax2_codec_pref *pref, struct ast_format_cap *cap)
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 (iax2_format 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 ast_sockaddr *addr, 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 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 ast_sockaddr *addr, int new, int sockfd, int full_frame)
static int find_callno_locked (unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, 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 ast_sockaddr *addr, int fd)
static struct iax2_userfind_user (const char *name)
static int firmware_show_callback (struct ast_iax2_firmware_header *header, void *user_data)
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 int get_unused_callno (enum callno_type type, int validated, callno_entry *entry)
static int handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct ast_sockaddr *addr, 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 ast_sockaddr *addr, int callno)
 Acknowledgment received for OUR registration.
static int attribute_pure iax2_allow_new (int frametype, int subclass, int inbound)
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 int iax2_call (struct ast_channel *c, const 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 iax2_format iax2_codec_choose (struct iax2_codec_pref *pref, iax2_format formats)
static int iax2_data_add_codecs (struct ast_data *root, const char *node_name, iax2_format formats)
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 (const char *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 *)
const char * iax2_getformatname (iax2_format format)
 iax2 wrapper function for ast_getformatname
static const char * iax2_getformatname_multiple (iax2_format format, struct ast_str **codec_buf)
static int iax2_getpeername (struct ast_sockaddr addr, char *host, int len)
static int iax2_getpeertrunk (struct ast_sockaddr addr)
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_is_control_frame_allowed (int subtype)
static int iax2_key_rotate (const void *vpvt)
static void iax2_lock_owner (int callno)
static int iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 Switch interface.
static int iax2_parse_allow_disallow (struct iax2_codec_pref *pref, iax2_format *formats, const char *list, int allowing)
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 ast_sockaddr *end, int sockfd, const char *dest, const char *template, int force)
static void iax2_publish_registry (const char *username, const char *domain, const char *status, const char *cause)
static int iax2_queryoption (struct ast_channel *c, int option, void *data, int *datalen)
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 int iax2_queue_hold (int callno, const char *musicclass)
 Queue a hold frame on the ast_channel owner.
static int iax2_queue_unhold (int callno)
 Queue an unhold 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, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
static int iax2_sched_add (struct ast_sched_context *sched, int when, ast_sched_cb callback, const void *data)
static int iax2_sched_replace (int id, struct ast_sched_context *con, 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_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 void iax_debug_output (const char *data)
static void iax_error_output (const char *data)
static void iax_outputframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct ast_sockaddr *addr, int datalen)
static ast_callid iax_pvt_callid_get (int callno)
static void iax_pvt_callid_new (int callno)
static void iax_pvt_callid_set (int callno, ast_callid callid)
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 the module.
static int load_objects (void)
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 ast_sockaddr *addr, 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 (void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
static int network_change_sched_cb (const void *data)
static void network_change_stasis_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
static void network_change_stasis_subscribe (void)
static void network_change_stasis_unsubscribe (void)
static void * network_thread (void *ignore)
static struct chan_iax2_pvtnew_iax (struct ast_sockaddr *addr, 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 ast_sockaddr *addr)
static int peercnt_cmp_cb (void *obj, void *arg, int flags)
static int peercnt_hash_cb (const void *obj, const int flags)
static void peercnt_modify (unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
static void peercnt_remove (struct peercnt *peercnt)
static int peercnt_remove_by_addr (struct ast_sockaddr *addr)
static int peercnt_remove_cb (const void *obj)
static int peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root)
static void poke_all_peers (void)
static int prune_addr_range_cb (void *obj, void *arg, int flags)
static void prune_peers (void)
static void prune_users (void)
static int pvt_cmp_cb (void *obj, void *arg, int flags)
static void pvt_destructor (void *obj)
static int pvt_hash_cb (const void *obj, const int flags)
static int queue_signalling (struct chan_iax2_pvt *pvt, struct ast_frame *f)
 All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.
static int raw_hangup (struct ast_sockaddr *addr, unsigned short src, unsigned short dst, int sockfd)
static struct iax2_peerrealtime_peer (const char *peername, struct ast_sockaddr *addr)
static void realtime_update_peer (const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
static struct iax2_userrealtime_user (const char *username, struct ast_sockaddr *addr)
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 ast_sockaddr *addr, struct iax_ies *ies)
 Verify inbound registration.
static int registry_authrequest (int callno)
static int registry_rerequest (struct iax_ies *ies, int callno, struct ast_sockaddr *addr)
static char * regstate2str (int regstate)
static int reload (void)
static int reload_config (int forced_reload)
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 ast_sockaddr *addr, callno_entry 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 ast_sockaddr *addr, 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, int forced)
 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_helper (struct iax2_thread *thread)
static int socket_process_meta (int packet_len, struct ast_iax2_meta_hdr *meta, struct ast_sockaddr *addr, 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 ast_sockaddr *addr, int sockfd)
static int try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static iax2_format uncompress_subclass (unsigned char csub)
static void unlink_peer (struct iax2_peer *peer)
static int unload_module (void)
static void unwrap_timestamp (struct iax_frame *fr)
static void update_jbsched (struct chan_iax2_pvt *pvt)
static int update_packet (struct iax_frame *f)
static int update_registry (struct ast_sockaddr *addr, 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_unref (struct iax2_user *user)
static int users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root)
static void vnak_retransmit (int callno, int last)
static int wait_for_peercallno (struct chan_iax2_pvt *pvt)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", }
static char accountcode [AST_MAX_ACCOUNT_CODE]
static struct stasis_subscriptionacl_change_sub
static int adsi = 0
static int amaflags = 0
static struct ast_module_infoast_module_info = &__mod_info
static int authdebug = 0
static int autokill = 0
static struct ao2_containercallno_limits
static struct call_number_pool callno_pool
static ast_mutex_t callno_pool_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static struct call_number_pool callno_pool_trunk
static struct ao2_containercalltoken_ignores
static struct ast_cli_entry cli_iax2 []
static struct ast_sockaddr 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 iax2_format iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH
static struct ast_data_entry iax2_data_providers []
static int iax2_encryption = 0
static int(* iax2_regfunk )(const char *username, int onoff) = NULL
static struct ast_switch iax2_switch
static struct ast_channel_tech iax2_tech
static struct ast_datastore_info iax2_variable_datastore_info
static struct ao2_containeriax_peercallno_pvts
 Another container of iax2_pvt structures.
static struct ao2_containeriax_transfercallno_pvts
 Another container of iax2_pvt structures.
static int iaxactivethreadcount = 0
static int iaxcompat = 0
static int iaxdebug = 0
static int iaxdefaultdpcache = 10 * 60
static int iaxdefaulttimeout = 5
static int iaxdynamicthreadcount = 0
static int iaxdynamicthreadnum = 0
static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT
static struct ast_custom_function iaxpeer_function
static struct chan_iax2_pvtiaxs [IAX_MAX_CALLS]
 an array of iax2 pvt structures
static ast_mutex_t iaxsl [ARRAY_LEN(iaxs)]
 chan_iax2_pvt structure locks
static int iaxthreadcount = DEFAULT_THREAD_COUNT
static int iaxtrunkdebug = 0
static struct ast_custom_function iaxvar_function
static struct io_contextio
static int jittertargetextra = 40
static int lagrq_time = 10
static char language [MAX_LANGUAGE] = ""
static int last_authmethod = 0
static time_t max_calltoken_delay = 10
static int max_reg_expire
static int max_retries = 4
static int maxauthreq = 3
static int maxjitterbuffer = 1000
static int maxjitterinterps = 10
static int min_reg_expire
static char mohinterpret [MAX_MUSICCLASS]
static char mohsuggest [MAX_MUSICCLASS]
static struct ast_netsock_listnetsock
static pthread_t netthreadid = AST_PTHREADT_NULL
static int network_change_sched_id = -1
static struct stasis_subscriptionnetwork_change_sub
static struct ast_netsock_listoutsock
static char * papp = "IAX2Provision"
static struct ao2_containerpeercnts
static struct ao2_containerpeers
static struct ast_data_handler peers_data_provider
static int ping_time = 21
static struct iax2_codec_pref prefs_global
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_contextsched
static int srvlookup = 0
static const char tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)"
static int test_losspct = 0
static struct ast_timertimer
static uint16_t total_nonval_callno_used = 0
static struct ast_taskprocessortransmit_processor
static int trunk_maxmtu
static int trunk_nmaxmtu
static int trunk_timed
static int trunk_untimed
static int trunkfreq = 20
static int trunkmaxsize = MAX_TRUNKDATA
static struct ao2_containerusers
static struct ast_data_handler users_data_provider


Detailed Description

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

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

Definition in file chan_iax2.c.


Define Documentation

#define ACN_FORMAT1   "%-20.25s %4u %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 %u %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_ENTRY_GET_CALLNO ( a   )     ((a) & 0x7FFF)

Definition at line 890 of file chan_iax2.c.

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

#define CALLNO_ENTRY_IS_VALIDATED ( a   )     ((a) & 0x8000)

Definition at line 889 of file chan_iax2.c.

Referenced by make_trunk(), and replace_callno().

#define CALLNO_ENTRY_SET_VALIDATED ( a   )     ((a) |= 0x8000)

Definition at line 888 of file chan_iax2.c.

Referenced by get_unused_callno().

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

Definition at line 886 of file chan_iax2.c.

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

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

Definition at line 273 of file chan_iax2.c.

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

#define CALLTOKEN_HASH_FORMAT   "%s%u%d"

Referenced by handle_call_token().

#define CALLTOKEN_IE_FORMAT   "%u?%s"

Referenced by handle_call_token().

#define DATA_EXPORT_IAX2_PEER ( MEMBER   ) 

Definition at line 14825 of file chan_iax2.c.

#define DATA_EXPORT_IAX2_USER ( MEMBER   ) 

Definition at line 14902 of file chan_iax2.c.

#define DEBUG_SCHED_MULTITHREAD

Definition at line 265 of file chan_iax2.c.

#define DEBUG_SUPPORT

Definition at line 281 of file chan_iax2.c.

#define DEFAULT_CONTEXT   "default"

Definition at line 300 of file chan_iax2.c.

#define DEFAULT_DROP   3

Definition at line 279 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

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

Referenced by build_peer().

#define DEFAULT_MAX_THREAD_COUNT   100

Definition at line 276 of file chan_iax2.c.

#define DEFAULT_MAXMS   2000

Definition at line 374 of file chan_iax2.c.

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

#define DEFAULT_RETRY_TIME   1000

Definition at line 277 of file chan_iax2.c.

Referenced by __find_callno(), and complete_transfer().

#define DEFAULT_THREAD_COUNT   10

Definition at line 275 of file chan_iax2.c.

#define DEFAULT_TRUNKDATA   640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 650 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

#define DONT_RESCHEDULE   -2

Definition at line 398 of file chan_iax2.c.

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

#define FORMAT   "%-20.20s %-40.40s %-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   "%-45.45s %-6.6s %-10.10s %-45.45s %8d %s\n"

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

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

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

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

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

#define GAMMA   (0.01)

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

Referenced by iax2_trunk_queue().

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

Allow the FWDOWNL command?

Definition at line 463 of file chan_iax2.c.

Referenced by set_config(), and socket_process_helper().

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

Already disconnected

Definition at line 447 of file chan_iax2.c.

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

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

Definition at line 379 of file chan_iax2.c.

Referenced by acf_channel_read(), iax2_send(), and socket_process_helper().

#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF

Definition at line 353 of file chan_iax2.c.

Referenced by cache_get_callno_locked(), and set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH

Value:

Definition at line 365 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWFREE

Value:

Definition at line 370 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH

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

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

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

Force old behaviour by turning off prefs

Definition at line 453 of file chan_iax2.c.

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

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

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

Definition at line 452 of file chan_iax2.c.

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

#define IAX_DEBUGDIGEST ( msg,
key   ) 

Definition at line 382 of file chan_iax2.c.

Referenced by iax2_key_rotate(), and socket_process_helper().

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

Referenced by socket_process_helper().

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

Needs to be deleted

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

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

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

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

CallerID has been specified

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

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

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

Whether we have a key populated

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

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

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

Don't native bridge

Definition at line 442 of file chan_iax2.c.

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

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

This is a provisioning request

Definition at line 448 of file chan_iax2.c.

Referenced by iax2_provision(), and socket_process_helper().

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

Whether or not we quelch audio

Definition at line 449 of file chan_iax2.c.

Referenced by iax2_write(), and socket_process_helper().

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

Allow receiving of connected line updates

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

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

erase me on expire

Definition at line 457 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 455 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 458 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 446 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 456 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 445 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 465 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 468 of file chan_iax2.c.

Referenced by check_access(), and set_config().

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

Temporary (realtime)

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

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

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

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

Send trunk timestamps

Definition at line 459 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 658 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 647 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 933 of file chan_iax2.c.

Referenced by load_objects().

#define MAX_RETRY_TIME   10000

Definition at line 645 of file chan_iax2.c.

Referenced by __attempt_transmit(), iax2_poke_peer(), and iax2_send().

#define MAX_TIMESTAMP_SKEW   160

maximum difference between actual and predicted ts for sending

Definition at line 652 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 295 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 320 of file chan_iax2.c.

Referenced by set_config(), and set_config_destroy().

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

Definition at line 937 of file chan_iax2.c.

Referenced by load_module(), and load_objects().

#define MEMORY_SIZE   100

Definition at line 278 of file chan_iax2.c.

#define MIN_JITTER_BUFFER   10

Definition at line 648 of file chan_iax2.c.

#define MIN_RETRY_TIME   100

Definition at line 644 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME   60

Definition at line 283 of file chan_iax2.c.

Referenced by make_trunk(), and sched_delay_remove().

#define PEERS_FORMAT   "%-15.15s %-40.40s %s %-40.40s %-6s%s %s %-11s %-32.32s\n"

Definition at line 6786 of file chan_iax2.c.

Referenced by _iax2_show_peers_one().

#define PEERS_FORMAT2   "%-15.15s %-40.40s %s %-40.40s %-9s %s %-11s %-32.32s\n"

Definition at line 6785 of file chan_iax2.c.

Referenced by __iax2_show_peers(), _sip_show_peers(), and _sip_show_peers_one().

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

#define PTR_TO_CALLNO_ENTRY ( a   )     ((uint16_t)(unsigned long)(a))

Definition at line 885 of file chan_iax2.c.

Referenced by replace_callno().

#define SCHED_MULTITHREADED

Todo:
XXX The IAX2 channel driver needs its native bridge code converted to the new bridge technology scheme.
Note:
The chan_dahdi native bridge code can be used as an example. It also appears that chan_iax2 also has a native transfer check like chan_dahdi to eliminate tromboned calls.

The existing native bridge code is marked with the IAX2_NATIVE_BRIDGING conditional.

Definition at line 261 of file chan_iax2.c.

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

#define TRUNK_CALL_START   (IAX_MAX_CALLS / 2)

Definition at line 1157 of file chan_iax2.c.

Referenced by create_callno_pools(), make_trunk(), and replace_callno().

#define TS_GAP_FOR_JB_RESYNC   5000

Definition at line 655 of file chan_iax2.c.


Typedef Documentation

typedef uint16_t callno_entry

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

00984      {
00985    /*! Extension exists */
00986    CACHE_FLAG_EXISTS      = (1 << 0),
00987    /*! Extension is nonexistent */
00988    CACHE_FLAG_NONEXISTENT = (1 << 1),
00989    /*! Extension can exist */
00990    CACHE_FLAG_CANEXIST    = (1 << 2),
00991    /*! Waiting to hear back response */
00992    CACHE_FLAG_PENDING     = (1 << 3),
00993    /*! Timed out */
00994    CACHE_FLAG_TIMEOUT     = (1 << 4),
00995    /*! Request transmitted */
00996    CACHE_FLAG_TRANSMITTED = (1 << 5),
00997    /*! Timeout */
00998    CACHE_FLAG_UNKNOWN     = (1 << 6),
00999    /*! Matchmore */
01000    CACHE_FLAG_MATCHMORE   = (1 << 7),
01001 };

anonymous enum

Enumerator:
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 2255 of file chan_iax2.c.

02255      {
02256    /* do not allow a new call number, only search ones in use for match */
02257    NEW_PREVENT = 0,
02258    /* search for match first, then allow a new one to be allocated */
02259    NEW_ALLOW = 1,
02260    /* do not search for match, force a new call number */
02261    NEW_FORCE = 2,
02262    /* do not search for match, force a new call number.  Signifies call number
02263     * has been calltoken validated */
02264    NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
02265 };

Enumerator:
CALLNO_TYPE_NORMAL 
CALLNO_TYPE_TRUNK 

Definition at line 880 of file chan_iax2.c.

00880                  {
00881    CALLNO_TYPE_NORMAL,
00882    CALLNO_TYPE_TRUNK,
00883 };

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

00476                          {
00477    /*! \brief Default calltoken required unless the ip is in the ignorelist */
00478    CALLTOKEN_DEFAULT = 0,
00479    /*! \brief Require call token validation. */
00480    CALLTOKEN_YES = 1,
00481    /*! \brief Require call token validation after a successful registration
00482     *         using call token validation occurs. */
00483    CALLTOKEN_AUTO = 2,
00484    /*! \brief Do not require call token validation. */
00485    CALLTOKEN_NO = 3,
00486 };

enum iax2_state

Enumerator:
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 426 of file chan_iax2.c.

00426                 {
00427    IAX_STATE_STARTED =        (1 << 0),
00428    IAX_STATE_AUTHENTICATED =  (1 << 1),
00429    IAX_STATE_TBD =            (1 << 2),
00430 };

Enumerator:
IAX_IOSTATE_IDLE 
IAX_IOSTATE_READY 
IAX_IOSTATE_PROCESSING 
IAX_IOSTATE_SCHEDREADY 

Definition at line 1025 of file chan_iax2.c.

Enumerator:
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 1032 of file chan_iax2.c.

01032                       {
01033    IAX_THREAD_TYPE_POOL,
01034    IAX_THREAD_TYPE_DYNAMIC,
01035 };

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


Function Documentation

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

Definition at line 3500 of file chan_iax2.c.

References chan_iax2_pvt::addr, iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, ast_channel_hangupcause_set(), ast_channel_name(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_LIST_REMOVE, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_stringify_addr(), attempt_transmit(), iax_frame::callno, chan_iax2_pvt::error, f, iax_frame::final, frame_queue, ast_frame::frametype, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, ast_frame_subclass::integer, LOG_WARNING, MAX_RETRY_TIME, NULL, 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().

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

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

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

09218 {
09219    /* Called from IAX thread only, without iaxs lock */
09220    int callno = (int)(long)(nothing);
09221    struct iax_ie_data ied;
09222    ast_mutex_lock(&iaxsl[callno]);
09223    if (iaxs[callno]) {
09224       memset(&ied, 0, sizeof(ied));
09225       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
09226          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
09227          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
09228       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
09229          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
09230          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09231       }
09232       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
09233    }
09234    ast_mutex_unlock(&iaxsl[callno]);
09235 }

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

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

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

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

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

09267 {
09268    /* Called from IAX thread only, without iaxs lock */
09269    int callno = (int)(long)(nothing);
09270    struct iax_ie_data ied;
09271    ast_mutex_lock(&iaxsl[callno]);
09272    if (iaxs[callno]) {
09273       memset(&ied, 0, sizeof(ied));
09274       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09275       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09276       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09277    }
09278    ast_mutex_unlock(&iaxsl[callno]);
09279 }

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

03293 {
03294    /* Just deliver the packet by using queueing.  This is called by
03295      the IAX thread with the iaxsl lock held. */
03296    struct iax_frame *fr = data;
03297    fr->retrans = -1;
03298    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03299    if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03300       iax2_queue_frame(fr->callno, &fr->af);
03301    /* Free our iax frame */
03302    iax2_frame_free(fr);
03303    /* And don't run again */
03304    return 0;
03305 }

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

Definition at line 8833 of file chan_iax2.c.

References iax2_peer::addr, ast_db_del(), ast_debug, AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_endpoint_blob_publish(), AST_ENDPOINT_OFFLINE, ast_endpoint_set_state(), ast_endpoint_state_type(), ast_json_pack(), ast_json_unref(), ast_sockaddr_setnull(), ast_test_flag64, iax2_peer::endpoint, iax2_peer::expire, iax2_peer::expiry, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, iax2_peer::name, NULL, peer_unref(), peercnt_modify(), RAII_VAR, realtime_update_peer(), register_peer_exten(), and unlink_peer().

Referenced by expire_registry().

08834 {
08835    struct iax2_peer *peer = (struct iax2_peer *) data;
08836    RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
08837 
08838    if (!peer)
08839       return;
08840    if (peer->expire == -1) {
08841       /* Removed already (possibly through CLI), ignore */
08842       return;
08843    }
08844 
08845    peer->expire = -1;
08846 
08847    ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08848    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08849       realtime_update_peer(peer->name, &peer->addr, 0);
08850    ast_endpoint_set_state(peer->endpoint, AST_ENDPOINT_OFFLINE);
08851    blob = ast_json_pack("{s: s, s: s}",
08852       "peer_status", "Unregistered",
08853       "cause", "Expired");
08854    ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
08855    /* modify entry in peercnts table as _not_ registered */
08856    peercnt_modify((unsigned char) 0, 0, &peer->addr);
08857    /* Reset the address */
08858    ast_sockaddr_setnull(&peer->addr);
08859    /* Reset expiry value */
08860    peer->expiry = min_reg_expire;
08861    if (!ast_test_flag64(peer, IAX_TEMPONLY))
08862       ast_db_del("IAX/Registry", peer->name);
08863    register_peer_exten(peer, 0);
08864    ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
08865    if (iax2_regfunk)
08866       iax2_regfunk(peer->name, 0);
08867 
08868    if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08869       unlink_peer(peer);
08870 
08871    peer_unref(peer);
08872 }

static int __find_callno ( unsigned short  callno,
unsigned short  dcallno,
struct ast_sockaddr addr,
int  new,
int  sockfd,
int  return_locked,
int  check_dcallno 
) [static]

Definition at line 3060 of file chan_iax2.c.

References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ao2_find, ao2_ref, ast_copy_flags64, ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_string_field_set, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, CALLNO_ENTRY_GET_CALLNO, CALLNO_ENTRY_TO_PTR, CALLNO_TYPE_NORMAL, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), host, iax2_getpeername(), iax2_sched_add(), IAX_FORCE_ENCRYPT, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, chan_iax2_pvt::lagid, LOG_WARNING, match(), NEW_ALLOW, new_iax(), NULL, 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(), and chan_iax2_pvt::transfer.

Referenced by find_callno(), and find_callno_locked().

03061 {
03062    int res = 0;
03063    int x;
03064    /* this call is calltoken validated as long as it is either NEW_FORCE
03065     * or NEW_ALLOW_CALLTOKEN_VALIDATED */
03066    int validated = (new > NEW_ALLOW) ? 1 : 0;
03067    char host[80];
03068 
03069    if (new <= NEW_ALLOW) {
03070       if (callno) {
03071          struct chan_iax2_pvt *pvt;
03072          struct chan_iax2_pvt tmp_pvt = {
03073             .callno = dcallno,
03074             .peercallno = callno,
03075             .transfercallno = callno,
03076             /* hack!! */
03077             .frames_received = check_dcallno,
03078          };
03079 
03080          ast_sockaddr_copy(&tmp_pvt.addr, addr);
03081          /* this works for finding normal call numbers not involving transfering */
03082          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
03083             if (return_locked) {
03084                ast_mutex_lock(&iaxsl[pvt->callno]);
03085             }
03086             res = pvt->callno;
03087             ao2_ref(pvt, -1);
03088             pvt = NULL;
03089             return res;
03090          }
03091          /* this searches for transfer call numbers that might not get caught otherwise */
03092          memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
03093          ast_sockaddr_copy(&tmp_pvt.transfer, addr);
03094          if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
03095             if (return_locked) {
03096                ast_mutex_lock(&iaxsl[pvt->callno]);
03097             }
03098             res = pvt->callno;
03099             ao2_ref(pvt, -1);
03100             pvt = NULL;
03101             return res;
03102          }
03103       }
03104          /* This will occur on the first response to a message that we initiated,
03105        * such as a PING. */
03106       if (dcallno) {
03107          ast_mutex_lock(&iaxsl[dcallno]);
03108       }
03109       if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(addr, callno, dcallno, iaxs[dcallno], check_dcallno)) {
03110          iaxs[dcallno]->peercallno = callno;
03111          res = dcallno;
03112          store_by_peercallno(iaxs[dcallno]);
03113          if (!res || !return_locked) {
03114             ast_mutex_unlock(&iaxsl[dcallno]);
03115          }
03116          return res;
03117       }
03118       if (dcallno) {
03119          ast_mutex_unlock(&iaxsl[dcallno]);
03120       }
03121    }
03122    if (!res && (new >= NEW_ALLOW)) {
03123       callno_entry entry;
03124 
03125       /* It may seem odd that we look through the peer list for a name for
03126        * this *incoming* call.  Well, it is weird.  However, users don't
03127        * have an IP address/port number that we can match against.  So,
03128        * this is just checking for a peer that has that IP/port and
03129        * assuming that we have a user of the same name.  This isn't always
03130        * correct, but it will be changed if needed after authentication. */
03131       if (!iax2_getpeername(*addr, host, sizeof(host)))
03132          snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(addr));
03133 
03134       if (peercnt_add(addr)) {
03135          /* This address has hit its callnumber limit.  When the limit
03136           * is reached, the connection is not added to the peercnts table.*/
03137          return 0;
03138       }
03139 
03140       if (get_unused_callno(CALLNO_TYPE_NORMAL, validated, &entry)) {
03141          /* since we ran out of space, remove the peercnt
03142           * entry we added earlier */
03143          peercnt_remove_by_addr(addr);
03144          ast_log(LOG_WARNING, "No more space\n");
03145          return 0;
03146       }
03147       x = CALLNO_ENTRY_GET_CALLNO(entry);
03148       ast_mutex_lock(&iaxsl[x]);
03149 
03150       iaxs[x] = new_iax(addr, host);
03151       if (iaxs[x]) {
03152          if (iaxdebug)
03153             ast_debug(1, "Creating new call structure %d\n", x);
03154          iaxs[x]->callno_entry = entry;
03155          iaxs[x]->sockfd = sockfd;
03156          ast_sockaddr_copy(&iaxs[x]->addr, addr);
03157          iaxs[x]->peercallno = callno;
03158          iaxs[x]->callno = x;
03159          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
03160          iaxs[x]->expiry = min_reg_expire;
03161          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
03162          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
03163          iaxs[x]->amaflags = amaflags;
03164          ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
03165          ast_string_field_set(iaxs[x], accountcode, accountcode);
03166          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
03167          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
03168          ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
03169 
03170          if (iaxs[x]->peercallno) {
03171             store_by_peercallno(iaxs[x]);
03172          }
03173       } else {
03174          ast_log(LOG_WARNING, "Out of resources\n");
03175          ast_mutex_unlock(&iaxsl[x]);
03176          replace_callno(CALLNO_ENTRY_TO_PTR(entry));
03177          return 0;
03178       }
03179       if (!return_locked)
03180          ast_mutex_unlock(&iaxsl[x]);
03181       res = x;
03182    }
03183    return res;
03184 }

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

Definition at line 4077 of file chan_iax2.c.

References __do_deliver(), ast_format_compatibility_bitfield2format(), ast_format_get_default_ms(), ast_format_get_sample_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_subclass::format, 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, iax2_trunk_peer::next, NULL, 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().

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

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

Definition at line 8476 of file chan_iax2.c.

References iax2_registry::addr, AST_AF_UNSPEC, ast_dnsmgr_lookup(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, iax2_registry::dnsmgr, iax2_registry::expire, iax2_registry::hostname, iax2_do_register(), NULL, iax2_registry::port, and ast_sockaddr::ss.

Referenced by iax2_do_register_s().

08477 {
08478    struct iax2_registry *reg = (struct iax2_registry *)data;
08479 
08480    if (ast_sockaddr_isnull(&reg->addr)) {
08481       reg->addr.ss.ss_family = AST_AF_UNSPEC;
08482       ast_dnsmgr_lookup(reg->hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL);
08483       if (!ast_sockaddr_port(&reg->addr)) {
08484          ast_sockaddr_set_port(&reg->addr, reg->port);
08485       } else {
08486          reg->port = ast_sockaddr_port(&reg->addr);
08487       }
08488    }
08489 
08490    reg->expire = -1;
08491    iax2_do_register(reg);
08492 }

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

Definition at line 12252 of file chan_iax2.c.

References AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_endpoint_blob_publish(), AST_ENDPOINT_OFFLINE, ast_endpoint_set_state(), ast_endpoint_state_type(), ast_json_pack(), ast_json_unref(), ast_log, ast_mutex_lock, ast_mutex_unlock, iax2_peer::callno, iax2_peer::endpoint, iax2_destroy(), iax2_poke_peer_s(), iax2_sched_add(), iax2_peer::lastms, LOG_NOTICE, iax2_peer::name, NULL, peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, and RAII_VAR.

Referenced by iax2_poke_noanswer().

12253 {
12254    struct iax2_peer *peer = (struct iax2_peer *)data;
12255    int callno;
12256 
12257    if (peer->lastms > -1) {
12258       RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
12259 
12260       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
12261       ast_endpoint_set_state(peer->endpoint, AST_ENDPOINT_OFFLINE);
12262       blob = ast_json_pack("{s: s, s: i}",
12263          "peer_status", "Unreachable",
12264          "time", peer->lastms);
12265       ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
12266       ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
12267    }
12268    if ((callno = peer->callno) > 0) {
12269       ast_mutex_lock(&iaxsl[callno]);
12270       iax2_destroy(callno);
12271       ast_mutex_unlock(&iaxsl[callno]);
12272    }
12273    peer->callno = 0;
12274    peer->lastms = -1;
12275    /* Try again quickly */
12276    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
12277    if (peer->pokeexpire == -1)
12278       peer_unref(peer);
12279 }

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

Definition at line 9326 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

09327 {
09328    struct iax2_peer *peer = (struct iax2_peer *)data;
09329    iax2_poke_peer(peer, 0);
09330    peer_unref(peer);
09331 }

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

Definition at line 6889 of file chan_iax2.c.

References _iax2_show_peers_one(), iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli(), ast_sockaddr_isnull(), show_peers_context::havepattern, iax2_peer::name, NULL, show_peers_context::offline_peers, show_peers_context::online_peers, peer_unref(), PEERS_FORMAT2, show_peers_context::regexbuf, show_peers_context::registeredonly, RESULT_SHOWUSAGE, RESULT_SUCCESS, show_peers_context::total_peers, and show_peers_context::unmonitored_peers.

Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().

06890 {
06891    struct show_peers_context cont = {
06892       .havepattern = 0,
06893       .idtext = "",
06894       .registeredonly = 0,
06895 
06896       .peerlist = 0,
06897 
06898       .total_peers = 0,
06899       .online_peers = 0,
06900       .offline_peers = 0,
06901       .unmonitored_peers = 0,
06902    };
06903 
06904    struct ao2_iterator i;
06905 
06906    struct iax2_peer *peer = NULL;
06907 
06908    switch (argc) {
06909    case 6:
06910       if (!strcasecmp(argv[3], "registered"))
06911          cont.registeredonly = 1;
06912       else
06913          return RESULT_SHOWUSAGE;
06914       if (!strcasecmp(argv[4], "like")) {
06915          if (regcomp(&cont.regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06916             return RESULT_SHOWUSAGE;
06917          cont.havepattern = 1;
06918       } else
06919          return RESULT_SHOWUSAGE;
06920       break;
06921    case 5:
06922       if (!strcasecmp(argv[3], "like")) {
06923          if (regcomp(&cont.regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06924             return RESULT_SHOWUSAGE;
06925          cont.havepattern = 1;
06926       } else
06927          return RESULT_SHOWUSAGE;
06928       break;
06929    case 4:
06930       if (!strcasecmp(argv[3], "registered")) {
06931          cont.registeredonly = 1;
06932       } else {
06933          return RESULT_SHOWUSAGE;
06934       }
06935       break;
06936    case 3:
06937       break;
06938    default:
06939       return RESULT_SHOWUSAGE;
06940    }
06941 
06942 
06943    if (!s) {
06944       ast_cli(fd, PEERS_FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", "Description");
06945    }
06946 
06947    i = ao2_iterator_init(peers, 0);
06948    for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
06949 
06950       if (cont.registeredonly && ast_sockaddr_isnull(&peer->addr)) {
06951          continue;
06952       }
06953       if (cont.havepattern && regexec(&cont.regexbuf, peer->name, 0, NULL, 0)) {
06954          continue;
06955       }
06956 
06957       _iax2_show_peers_one(fd, s, &cont, peer);
06958 
06959    }
06960    ao2_iterator_destroy(&i);
06961 
06962    if (!s) {
06963       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06964          cont.total_peers, cont.online_peers, cont.offline_peers, cont.unmonitored_peers);
06965    }
06966 
06967    if (cont.havepattern) {
06968       regfree(&cont.regexbuf);
06969    }
06970 
06971    if (total) {
06972       *total = cont.total_peers;
06973    }
06974 
06975    return RESULT_SUCCESS;
06976 
06977 }

static void __reg_module ( void   )  [static]

Definition at line 15158 of file chan_iax2.c.

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

Definition at line 1634 of file chan_iax2.c.

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

01635 {
01636    struct iax2_thread *thread;
01637    static time_t lasterror;
01638    time_t t;
01639 
01640    thread = find_idle_thread();
01641    if (thread != NULL) {
01642       thread->schedfunc = func;
01643       thread->scheddata = data;
01644       thread->iostate = IAX_IOSTATE_SCHEDREADY;
01645 #ifdef DEBUG_SCHED_MULTITHREAD
01646       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01647 #endif
01648       signal_condition(&thread->lock, &thread->cond);
01649       return 0;
01650    }
01651    time(&t);
01652    if (t != lasterror) {
01653       lasterror = t;
01654       ast_debug(1, "Out of idle IAX2 threads for scheduling! (%s)\n", funcname);
01655    }
01656 
01657    return -1;
01658 }

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

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

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

07657 {
07658    struct ast_frame f = { 0, };
07659    int res = 0;
07660 
07661    f.frametype = type;
07662    f.subclass.integer = command;
07663    f.datalen = datalen;
07664    f.src = __FUNCTION__;
07665    f.data.ptr = (void *) data;
07666 
07667    if ((res = queue_signalling(i, &f)) <= 0) {
07668       return res;
07669    }
07670 
07671    return iax2_send(i, &f, ts, seqno, now, transfer, final);
07672 }

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

Definition at line 1743 of file chan_iax2.c.

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

Referenced by send_lagrq().

01744 {
01745    int callno = (long) data;
01746 
01747    ast_mutex_lock(&iaxsl[callno]);
01748 
01749    if (iaxs[callno]) {
01750       if (iaxs[callno]->peercallno) {
01751          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01752          if (iaxs[callno]->lagid != DONT_RESCHEDULE) {
01753             iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01754          }
01755       }
01756    } else {
01757       ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01758    }
01759 
01760    ast_mutex_unlock(&iaxsl[callno]);
01761 }

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

Definition at line 1676 of file chan_iax2.c.

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

Referenced by send_ping().

01677 {
01678    int callno = (long) data;
01679 
01680    ast_mutex_lock(&iaxsl[callno]);
01681 
01682    if (iaxs[callno]) {
01683       if (iaxs[callno]->peercallno) {
01684          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01685          if (iaxs[callno]->pingid != DONT_RESCHEDULE) {
01686             iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01687          }
01688       }
01689    } else {
01690       ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01691    }
01692 
01693    ast_mutex_unlock(&iaxsl[callno]);
01694 }

static int __unload_module ( void   )  [static]

Definition at line 14630 of file chan_iax2.c.

References acl_change_stasis_unsubscribe(), ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), ast_data_unregister, ast_manager_unregister(), ast_mutex_destroy, ast_netsock_release(), AST_PTHREADT_NULL, ast_sched_clean_by_callback(), ast_sched_context_destroy(), ast_taskprocessor_unreference(), AST_TEST_UNREGISTER, ast_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), ast_channel_tech::capabilities, cleanup_thread_list(), delete_users(), iax2_destroy(), iax_firmware_unload(), iax_provision_unload(), network_change_stasis_unsubscribe(), NULL, and peercnt_remove_cb().

14631 {
14632    struct ast_context *con;
14633    int x;
14634 
14635    network_change_stasis_unsubscribe();
14636    acl_change_stasis_unsubscribe();
14637 
14638    ast_manager_unregister("IAXpeers");
14639    ast_manager_unregister("IAXpeerlist");
14640    ast_manager_unregister("IAXnetstats");
14641    ast_manager_unregister("IAXregistry");
14642    ast_unregister_application(papp);
14643    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14644    ast_unregister_switch(&iax2_switch);
14645    ast_channel_unregister(&iax2_tech);
14646 
14647    if (netthreadid != AST_PTHREADT_NULL) {
14648       pthread_cancel(netthreadid);
14649       pthread_kill(netthreadid, SIGURG);
14650       pthread_join(netthreadid, NULL);
14651    }
14652 
14653    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14654       if (iaxs[x]) {
14655          iax2_destroy(x);
14656       }
14657    }
14658 
14659    /* Call for all threads to halt */
14660    cleanup_thread_list(&active_list);
14661    cleanup_thread_list(&dynamic_list);
14662    cleanup_thread_list(&idle_list);
14663 
14664    ast_netsock_release(netsock);
14665    ast_netsock_release(outsock);
14666    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14667       if (iaxs[x]) {
14668          iax2_destroy(x);
14669       }
14670    }
14671    ast_manager_unregister( "IAXpeers" );
14672    ast_manager_unregister( "IAXpeerlist" );
14673    ast_manager_unregister( "IAXnetstats" );
14674    ast_manager_unregister( "IAXregistry" );
14675    ast_unregister_application(papp);
14676 #ifdef TEST_FRAMEWORK
14677    AST_TEST_UNREGISTER(test_iax2_peers_get);
14678    AST_TEST_UNREGISTER(test_iax2_users_get);
14679 #endif
14680    ast_data_unregister(NULL);
14681    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14682    ast_unregister_switch(&iax2_switch);
14683    ast_channel_unregister(&iax2_tech);
14684    delete_users();
14685    iax_provision_unload();
14686    iax_firmware_unload();
14687 
14688    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14689       ast_mutex_destroy(&iaxsl[x]);
14690    }
14691 
14692    ao2_ref(peers, -1);
14693    ao2_ref(users, -1);
14694    ao2_ref(iax_peercallno_pvts, -1);
14695    ao2_ref(iax_transfercallno_pvts, -1);
14696    ao2_ref(callno_limits, -1);
14697    ao2_ref(calltoken_ignores, -1);
14698    if (timer) {
14699       ast_timer_close(timer);
14700       timer = NULL;
14701    }
14702    transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14703 
14704    ast_sched_clean_by_callback(sched, peercnt_remove_cb, peercnt_remove_cb);
14705    ast_sched_context_destroy(sched);
14706    sched = NULL;
14707    ao2_ref(peercnts, -1);
14708 
14709    con = ast_context_find(regcontext);
14710    if (con)
14711       ast_context_destroy(con, "IAX2");
14712    ast_unload_realtime("iaxpeers");
14713 
14714    ao2_ref(iax2_tech.capabilities, -1);
14715    iax2_tech.capabilities = NULL;
14716    return 0;
14717 }

static void __unreg_module ( void   )  [static]

Definition at line 15158 of file chan_iax2.c.

static void _iax2_show_peers_one ( int  fd,
struct mansession s,
struct show_peers_context cont,
struct iax2_peer peer 
) [static]

Definition at line 6788 of file chan_iax2.c.

References iax2_peer::addr, ast_cli(), ast_copy_string(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_str_alloca, ast_str_buffer(), ast_strdupa, ast_strlen_zero, ast_test_flag64, astman_append(), iax2_peer::description, iax2_peer::encmethods, encmethods_to_str(), IAX_DYNAMIC, IAX_TRUNK, show_peers_context::idtext, iax2_peer::mask, iax2_peer::name, name, show_peers_context::offline_peers, show_peers_context::online_peers, peer_status(), show_peers_context::peerlist, PEERS_FORMAT, status, show_peers_context::total_peers, show_peers_context::unmonitored_peers, and iax2_peer::username.

Referenced by __iax2_show_peers(), and manager_iax2_show_peer_list().

06789 {
06790    char name[256] = "";
06791    char status[20];
06792    int retstatus;
06793    struct ast_str *encmethods = ast_str_alloca(256);
06794 
06795    char *tmp_host, *tmp_mask, *tmp_port;
06796 
06797    tmp_host = ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr));
06798    tmp_mask = ast_strdupa(ast_sockaddr_stringify_addr(&peer->mask));
06799    tmp_port = ast_strdupa(ast_sockaddr_stringify_port(&peer->addr));
06800 
06801    if (!ast_strlen_zero(peer->username)) {
06802       snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06803    } else {
06804       ast_copy_string(name, peer->name, sizeof(name));
06805    }
06806 
06807    encmethods_to_str(peer->encmethods, &encmethods);
06808    retstatus = peer_status(peer, status, sizeof(status));
06809    if (retstatus > 0) {
06810       cont->online_peers++;
06811    } else if (!retstatus) {
06812       cont->offline_peers++;
06813    } else {
06814       cont->unmonitored_peers++;
06815    }
06816 
06817    if (s) {
06818       if (cont->peerlist) { /* IAXpeerlist */
06819          astman_append(s,
06820             "Event: PeerEntry\r\n%s"
06821             "Channeltype: IAX\r\n",
06822             cont->idtext);
06823          if (!ast_strlen_zero(peer->username)) {
06824             astman_append(s,
06825                "ObjectName: %s\r\n"
06826                "ObjectUsername: %s\r\n",
06827                peer->name,
06828                peer->username);
06829          } else {
06830             astman_append(s,
06831                "ObjectName: %s\r\n",
06832                name);
06833          }
06834       } else { /* IAXpeers */
06835          astman_append(s,
06836             "Event: PeerEntry\r\n%s"
06837             "Channeltype: IAX2\r\n"
06838             "ObjectName: %s\r\n",
06839             cont->idtext,
06840             name);
06841       }
06842       astman_append(s,
06843          "ChanObjectType: peer\r\n"
06844          "IPaddress: %s\r\n",
06845          tmp_host);
06846       if (cont->peerlist) { /* IAXpeerlist */
06847          astman_append(s,
06848             "Mask: %s\r\n"
06849             "Port: %s\r\n",
06850             tmp_mask,
06851             tmp_port);
06852       } else { /* IAXpeers */
06853          astman_append(s,
06854             "IPport: %s\r\n",
06855             tmp_port);
06856       }
06857       astman_append(s,
06858          "Dynamic: %s\r\n"
06859          "Trunk: %s\r\n"
06860          "Encryption: %s\r\n"
06861          "Status: %s\r\n",
06862          ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06863          ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06864          peer->encmethods ? ast_str_buffer(encmethods) : "no",
06865          status);
06866       if (cont->peerlist) { /* IAXpeerlist */
06867          astman_append(s, "\r\n");
06868       } else { /* IAXpeers */
06869          astman_append(s,
06870             "Description: %s\r\n\r\n",
06871             peer->description);
06872       }
06873    } else {
06874       ast_cli(fd, PEERS_FORMAT,
06875          name,
06876          tmp_host,
06877          ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06878          tmp_mask,
06879          tmp_port,
06880          ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : "   ",
06881          peer->encmethods ? "(E)" : "   ",
06882          status,
06883          peer->description);
06884    }
06885 
06886    cont->total_peers++;
06887 }

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

Definition at line 14373 of file chan_iax2.c.

References chan_iax2_pvt::addr, ast_channel_tech(), ast_channel_tech_pvt(), ast_copy_string(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_isnull(), ast_sockaddr_stringify_addr(), chan_iax2_pvt::callno, IAX_CALLENCRYPTED, LOG_ERROR, chan_iax2_pvt::osptoken, PTR_TO_CALLNO, and chan_iax2_pvt::username.

14374 {
14375    struct chan_iax2_pvt *pvt;
14376    unsigned int callno;
14377    int res = 0;
14378 
14379    if (!chan || ast_channel_tech(chan) != &iax2_tech) {
14380       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
14381       return -1;
14382    }
14383 
14384    callno = PTR_TO_CALLNO(ast_channel_tech_pvt(chan));
14385    ast_mutex_lock(&iaxsl[callno]);
14386    if (!(pvt = iaxs[callno])) {
14387       ast_mutex_unlock(&iaxsl[callno]);
14388       return -1;
14389    }
14390 
14391    if (!strcasecmp(args, "osptoken")) {
14392       ast_copy_string(buf, pvt->osptoken, buflen);
14393    } else if (!strcasecmp(args, "peerip")) {
14394       ast_copy_string(buf, !ast_sockaddr_isnull(&pvt->addr) ? ast_sockaddr_stringify_addr(&pvt->addr) : "", buflen);
14395    } else if (!strcasecmp(args, "peername")) {
14396       ast_copy_string(buf, pvt->username, buflen);
14397    } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
14398       snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
14399    } else {
14400       res = -1;
14401    }
14402 
14403    ast_mutex_unlock(&iaxsl[callno]);
14404 
14405    return res;
14406 }

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

Definition at line 9912 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_log, ast_datastore::data, ast_var_t::entries, LOG_WARNING, ast_var_t::name, NULL, ast_var_t::value, and var.

09913 {
09914    struct ast_datastore *variablestore;
09915    AST_LIST_HEAD(, ast_var_t) *varlist;
09916    struct ast_var_t *var;
09917 
09918    if (!chan) {
09919       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
09920       return -1;
09921    }
09922 
09923    variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09924    if (!variablestore) {
09925       *buf = '\0';
09926       return 0;
09927    }
09928    varlist = variablestore->data;
09929 
09930    AST_LIST_LOCK(varlist);
09931    AST_LIST_TRAVERSE(varlist, var, entries) {
09932       if (strcmp(var->name, data) == 0) {
09933          ast_copy_string(buf, var->value, len);
09934          break;
09935       }
09936    }
09937    AST_LIST_UNLOCK(varlist);
09938    return 0;
09939 }

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

Definition at line 9941 of file chan_iax2.c.

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

09942 {
09943    struct ast_datastore *variablestore;
09944    AST_LIST_HEAD(, ast_var_t) *varlist;
09945    struct ast_var_t *var;
09946 
09947    if (!chan) {
09948       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
09949       return -1;
09950    }
09951 
09952    variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09953    if (!variablestore) {
09954       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09955       if (!variablestore) {
09956          ast_log(LOG_ERROR, "Memory allocation error\n");
09957          return -1;
09958       }
09959       varlist = ast_calloc(1, sizeof(*varlist));
09960       if (!varlist) {
09961          ast_datastore_free(variablestore);
09962          ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09963          return -1;
09964       }
09965 
09966       AST_LIST_HEAD_INIT(varlist);
09967       variablestore->data = varlist;
09968       variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09969       ast_channel_datastore_add(chan, variablestore);
09970    } else
09971       varlist = variablestore->data;
09972 
09973    AST_LIST_LOCK(varlist);
09974    AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09975       if (strcmp(var->name, data) == 0) {
09976          AST_LIST_REMOVE_CURRENT(entries);
09977          ast_var_delete(var);
09978          break;
09979       }
09980    }
09981    AST_LIST_TRAVERSE_SAFE_END;
09982    var = ast_var_assign(data, value);
09983    if (var)
09984       AST_LIST_INSERT_TAIL(varlist, var, entries);
09985    else
09986       ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09987    AST_LIST_UNLOCK(varlist);
09988    return 0;
09989 }

static void acl_change_stasis_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
) [static]

Definition at line 1493 of file chan_iax2.c.

References ast_log, ast_named_acl_change_type(), LOG_NOTICE, reload_config(), and stasis_message_type().

Referenced by acl_change_stasis_subscribe().

01495 {
01496    if (stasis_message_type(message) != ast_named_acl_change_type()) {
01497       return;
01498    }
01499 
01500    ast_log(LOG_NOTICE, "Reloading chan_iax2 in response to ACL change event.\n");
01501    reload_config(1);
01502 }

static void acl_change_stasis_subscribe ( void   )  [static]

static void acl_change_stasis_unsubscribe ( void   )  [static]

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

Definition at line 2747 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, error(), addr_range::ha, LOG_WARNING, NULL, and OBJ_POINTER.

Referenced by set_config().

02748 {
02749    struct addr_range tmp;
02750    struct addr_range *addr_range = NULL;
02751    struct ast_ha *ha = NULL;
02752    int error = 0;
02753 
02754    if (ast_strlen_zero(addr)) {
02755       ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02756       return -1;
02757    }
02758 
02759    ha = ast_append_ha("permit", addr, NULL, &error);
02760 
02761    /* check for valid config information */
02762    if (error) {
02763       ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02764       return -1;
02765    }
02766 
02767    ast_copy_ha(ha, &tmp.ha);
02768    /* find or create the addr_range */
02769    if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02770       ao2_lock(addr_range);
02771       addr_range->delme = 0;
02772       ao2_unlock(addr_range);
02773    } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02774       /* copy over config data into addr_range object */
02775       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
02776       ao2_link(calltoken_ignores, addr_range);
02777    } else {
02778       ast_free_ha(ha);
02779       return -1;
02780    }
02781 
02782    ast_free_ha(ha);
02783    ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02784 
02785    return 0;
02786 }

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

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

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

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

Definition at line 2403 of file chan_iax2.c.

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

Referenced by load_objects().

02404 {
02405    struct addr_range *lim1 = obj, *lim2 = arg;
02406    return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
02407          !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
02408          CMP_MATCH | CMP_STOP : 0;
02409 }

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

Definition at line 2390 of file chan_iax2.c.

References addr_range::delme.

Referenced by set_config_destroy().

02391 {
02392    struct addr_range *lim = obj;
02393    lim->delme = 1;
02394    return 0;
02395 }

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

Definition at line 2397 of file chan_iax2.c.

References abs, ast_ha::addr, ast_sockaddr_hash(), and addr_range::ha.

Referenced by load_objects().

02398 {
02399    const struct addr_range *lim = obj;
02400    return abs(ast_sockaddr_hash(&lim->ha.addr));
02401 }

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

Definition at line 2427 of file chan_iax2.c.

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

Referenced by calltoken_required(), and set_peercnt_limit().

02428 {
02429    struct addr_range *addr_range = obj;
02430    struct ast_sockaddr *addr = arg;
02431    struct ast_sockaddr tmp_addr;
02432 
02433    ast_sockaddr_apply_netmask(addr, &addr_range->ha.netmask, &tmp_addr);
02434 
02435    if (!ast_sockaddr_cmp_addr(&tmp_addr, &addr_range->ha.addr)) {
02436       return CMP_MATCH | CMP_STOP;
02437    }
02438    return 0;
02439 }

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

Definition at line 7719 of file chan_iax2.c.

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

Referenced by check_access().

07720 {
07721    while(con) {
07722       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07723          return -1;
07724       con = con->next;
07725    }
07726    return 0;
07727 }

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

Definition at line 7420 of file chan_iax2.c.

References ACN_FORMAT1, ACN_FORMAT2, ARRAY_LEN, ast_channel_name(), 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, 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, and chan_iax2_pvt::remote_rr.

Referenced by handle_cli_iax2_show_netstats(), and manager_iax2_show_netstats().

07421 {
07422    int x;
07423    int numchans = 0;
07424    char first_message[10] = { 0, };
07425    char last_message[10] = { 0, };
07426 #define ACN_FORMAT1 "%-20.25s %4u %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
07427 #define ACN_FORMAT2 "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07428    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07429       ast_mutex_lock(&iaxsl[x]);
07430       if (iaxs[x]) {
07431          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07432          jb_info jbinfo;
07433          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07434          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07435 
07436          if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07437             jb_getinfo(iaxs[x]->jb, &jbinfo);
07438             localjitter = jbinfo.jitter;
07439             localdelay = jbinfo.current - jbinfo.min;
07440             locallost = jbinfo.frames_lost;
07441             locallosspct = jbinfo.losspct/1000;
07442             localdropped = jbinfo.frames_dropped;
07443             localooo = jbinfo.frames_ooo;
07444          } else {
07445             localjitter = -1;
07446             localdelay = 0;
07447             locallost = -1;
07448             locallosspct = -1;
07449             localdropped = 0;
07450             localooo = -1;
07451          }
07452          if (s)
07453             astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07454                iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
07455                iaxs[x]->pingtime,
07456                localjitter,
07457                localdelay,
07458                locallost,
07459                locallosspct,
07460                localdropped,
07461                localooo,
07462                iaxs[x]->frames_received/1000,
07463                iaxs[x]->remote_rr.jitter,
07464                iaxs[x]->remote_rr.delay,
07465                iaxs[x]->remote_rr.losscnt,
07466                iaxs[x]->remote_rr.losspct,
07467                iaxs[x]->remote_rr.dropped,
07468                iaxs[x]->remote_rr.ooo,
07469                iaxs[x]->remote_rr.packets/1000,
07470                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07471                first_message,
07472                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07473                last_message);
07474          else
07475             ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07476                iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
07477                iaxs[x]->pingtime,
07478                localjitter,
07479                localdelay,
07480                locallost,
07481                locallosspct,
07482                localdropped,
07483                localooo,
07484                iaxs[x]->frames_received/1000,
07485                iaxs[x]->remote_rr.jitter,
07486                iaxs[x]->remote_rr.delay,
07487                iaxs[x]->remote_rr.losscnt,
07488                iaxs[x]->remote_rr.losspct,
07489                iaxs[x]->remote_rr.dropped,
07490                iaxs[x]->remote_rr.ooo,
07491                iaxs[x]->remote_rr.packets/1000,
07492                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07493                first_message,
07494                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07495                last_message);
07496          numchans++;
07497       }
07498       ast_mutex_unlock(&iaxsl[x]);
07499    }
07500 
07501    return numchans;
07502 }

AST_DATA_STRUCTURE ( iax2_user  ,
DATA_EXPORT_IAX2_USER   
)

AST_DATA_STRUCTURE ( iax2_peer  ,
DATA_EXPORT_IAX2_PEER   
)

static struct ast_channel* ast_iax2_new ( int  callno,
int  state,
iax2_format  capability,
struct iax2_codec_pref prefs,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
unsigned int  cachable 
) [static, read]

Create new call, interface with the PBX core.

Definition at line 5772 of file chan_iax2.c.

References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, chan_iax2_pvt::amaflags, ast_party_caller::ani, chan_iax2_pvt::ani, ao2_cleanup, ao2_ref, AST_ADSI_UNAVAILABLE, ast_calloc, ast_channel_adsicpe_set(), ast_channel_alloc, ast_channel_alloc_with_endpoint, ast_channel_amaflags_set(), ast_channel_caller(), ast_channel_callid_set(), ast_channel_context_set(), ast_channel_datastore_add(), ast_channel_dialed(), ast_channel_exten_set(), ast_channel_flags(), ast_channel_name(), ast_channel_nativeformats_set(), ast_channel_redirecting(), ast_channel_release(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_tech_pvt_set(), ast_channel_tech_set(), ast_channel_unlock, ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_FLAG_DISABLE_DEVSTATE_CACHE, ast_format_cap_alloc, ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_format(), 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_set_flag, AST_STATE_DOWN, ast_strdup, ast_strdupa, 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, chan_iax2_pvt::cid_name, chan_iax2_pvt::cid_num, chan_iax2_pvt::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, chan_iax2_pvt::dnid, iax2_peer::endpoint, ast_var_t::entries, chan_iax2_pvt::exten, find_peer(), ast_party_redirecting::from, chan_iax2_pvt::host, iax2_codec_pref_best_bitfield2cap(), chan_iax2_pvt::iaxvars, ast_party_caller::id, ast_datastore::inheritance, chan_iax2_pvt::language, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_party_id::name, ast_variable::next, NULL, ast_party_dialed::number, ast_party_id::number, chan_iax2_pvt::owner, chan_iax2_pvt::parkinglot, pbx_builtin_setvar_helper(), chan_iax2_pvt::peer, chan_iax2_pvt::peeradsicpe, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, chan_iax2_pvt::rdnis, ast_party_dialed::str, ast_party_number::str, tmp(), ast_party_dialed::transit_network_select, ast_party_number::valid, ast_variable::value, var, and chan_iax2_pvt::vars.

Referenced by iax2_request(), and socket_process_helper().

05775 {
05776    struct ast_channel *tmp = NULL;
05777    struct chan_iax2_pvt *i;
05778    struct iax2_peer *peer;
05779    struct ast_variable *v = NULL;
05780    struct ast_format_cap *native;
05781    struct ast_format *tmpfmt;
05782    ast_callid callid;
05783    char *peer_name = NULL;
05784 
05785    if (!(i = iaxs[callno])) {
05786       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05787       return NULL;
05788    }
05789 
05790    if (!capability) {
05791       ast_log(LOG_WARNING, "No formats specified for call to: IAX2/%s-%d\n",
05792          i->host, i->callno);
05793       return NULL;
05794    }
05795    native = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
05796    if (!native) {
05797       return NULL;
05798    }
05799    if (iax2_codec_pref_best_bitfield2cap(capability, prefs, native)
05800       || !ast_format_cap_count(native)) {
05801       ast_log(LOG_WARNING, "No requested formats available for call to: IAX2/%s-%d\n",
05802          i->host, i->callno);
05803       ao2_ref(native, -1);
05804       return NULL;
05805    }
05806 
05807    if (!ast_strlen_zero(i->peer)) {
05808       peer_name = ast_strdupa(i->peer);
05809    } else if (!ast_strlen_zero(i->host)) {
05810       peer_name = ast_strdupa(i->host);
05811    }
05812 
05813    /* Don't hold call lock while making a channel or looking up a peer */
05814    ast_mutex_unlock(&iaxsl[callno]);
05815 
05816    if (!ast_strlen_zero(peer_name)) {
05817       peer = find_peer(peer_name, 1);
05818       if (peer && peer->endpoint) {
05819          tmp = ast_channel_alloc_with_endpoint(1, state, i->cid_num, i->cid_name,
05820             i->accountcode, i->exten, i->context, assignedids, requestor,
05821             i->amaflags, peer->endpoint, "IAX2/%s-%d", i->host, i->callno);
05822       }
05823       ao2_cleanup(peer);
05824    }
05825 
05826    if (!tmp) {
05827       tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode,
05828          i->exten, i->context, assignedids, requestor, i->amaflags, "IAX2/%s-%d",
05829          i->host, i->callno);
05830    }
05831 
05832    ast_mutex_lock(&iaxsl[callno]);
05833    if (i != iaxs[callno]) {
05834       if (tmp) {
05835          /* unlock and relock iaxsl[callno] to preserve locking order */
05836          ast_mutex_unlock(&iaxsl[callno]);
05837          ast_channel_unlock(tmp);
05838          tmp = ast_channel_release(tmp);
05839          ast_mutex_lock(&iaxsl[callno]);
05840       }
05841       ao2_ref(native, -1);
05842       return NULL;
05843    }
05844    if (!tmp) {
05845       ao2_ref(native, -1);
05846       return NULL;
05847    }
05848 
05849    ast_channel_stage_snapshot(tmp);
05850 
05851    if ((callid = iaxs[callno]->callid)) {
05852       ast_channel_callid_set(tmp, callid);
05853    }
05854 
05855    ast_channel_tech_set(tmp, &iax2_tech);
05856 
05857    /* We can support any format by default, until we get restricted */
05858    ast_channel_nativeformats_set(tmp, native);
05859    tmpfmt = ast_format_cap_get_format(native, 0);
05860 
05861    ast_channel_set_readformat(tmp, tmpfmt);
05862    ast_channel_set_rawreadformat(tmp, tmpfmt);
05863    ast_channel_set_writeformat(tmp, tmpfmt);
05864    ast_channel_set_rawwriteformat(tmp, tmpfmt);
05865 
05866    ao2_ref(tmpfmt, -1);
05867    ao2_ref(native, -1);
05868 
05869    ast_channel_tech_pvt_set(tmp, CALLNO_TO_PTR(i->callno));
05870 
05871    if (!ast_strlen_zero(i->parkinglot))
05872       ast_channel_parkinglot_set(tmp, i->parkinglot);
05873    /* Don't use ast_set_callerid() here because it will
05874     * generate a NewCallerID event before the NewChannel event */
05875    if (!ast_strlen_zero(i->ani)) {
05876       ast_channel_caller(tmp)->ani.number.valid = 1;
05877       ast_channel_caller(tmp)->ani.number.str = ast_strdup(i->ani);
05878    } else if (!ast_strlen_zero(i->cid_num)) {
05879       ast_channel_caller(tmp)->ani.number.valid = 1;
05880       ast_channel_caller(tmp)->ani.number.str = ast_strdup(i->cid_num);
05881    }
05882    ast_channel_dialed(tmp)->number.str = ast_strdup(i->dnid);
05883    if (!ast_strlen_zero(i->rdnis)) {
05884       ast_channel_redirecting(tmp)->from.number.valid = 1;
05885       ast_channel_redirecting(tmp)->from.number.str = ast_strdup(i->rdnis);
05886    }
05887    ast_channel_caller(tmp)->id.name.presentation = i->calling_pres;
05888    ast_channel_caller(tmp)->id.number.presentation = i->calling_pres;
05889    ast_channel_caller(tmp)->id.number.plan = i->calling_ton;
05890    ast_channel_dialed(tmp)->transit_network_select = i->calling_tns;
05891    if (!ast_strlen_zero(i->language))
05892       ast_channel_language_set(tmp, i->language);
05893    if (!ast_strlen_zero(i->accountcode))
05894       ast_channel_accountcode_set(tmp, i->accountcode);
05895    if (i->amaflags)
05896       ast_channel_amaflags_set(tmp, i->amaflags);
05897    ast_channel_context_set(tmp, i->context);
05898    ast_channel_exten_set(tmp, i->exten);
05899    if (i->adsi)
05900       ast_channel_adsicpe_set(tmp, i->peeradsicpe);
05901    else
05902       ast_channel_adsicpe_set(tmp, AST_ADSI_UNAVAILABLE);
05903    i->owner = tmp;
05904    i->capability = capability;
05905 
05906    if (!cachable) {
05907       ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
05908    }
05909 
05910    /* Set inherited variables */
05911    if (i->vars) {
05912       for (v = i->vars ; v ; v = v->next)
05913          pbx_builtin_setvar_helper(tmp, v->name, v->value);
05914    }
05915    if (i->iaxvars) {
05916       struct ast_datastore *variablestore;
05917       struct ast_variable *var, *prev = NULL;
05918       AST_LIST_HEAD(, ast_var_t) *varlist;
05919       ast_debug(1, "Loading up the channel with IAXVARs\n");
05920       varlist = ast_calloc(1, sizeof(*varlist));
05921       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05922       if (variablestore && varlist) {
05923          variablestore->data = varlist;
05924          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05925          AST_LIST_HEAD_INIT(varlist);
05926          for (var = i->iaxvars; var; var = var->next) {
05927             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05928             if (prev)
05929                ast_free(prev);
05930             prev = var;
05931             if (!newvar) {
05932                /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
05933                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05934             } else {
05935                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05936             }
05937          }
05938          if (prev)
05939             ast_free(prev);
05940          i->iaxvars = NULL;
05941          ast_channel_datastore_add(i->owner, variablestore);
05942       } else {
05943          if (variablestore) {
05944             ast_datastore_free(variablestore);
05945          }
05946          if (varlist) {
05947             ast_free(varlist);
05948          }
05949       }
05950    }
05951 
05952    ast_channel_stage_snapshot_done(tmp);
05953    ast_channel_unlock(tmp);
05954 
05955    if (state != AST_STATE_DOWN) {
05956       if (ast_pbx_start(tmp)) {
05957          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
05958          /* unlock and relock iaxsl[callno] to preserve locking order */
05959          ast_mutex_unlock(&iaxsl[callno]);
05960          ast_hangup(tmp);
05961          ast_mutex_lock(&iaxsl[callno]);
05962          return NULL;
05963       }
05964    }
05965 
05966    ast_module_ref(ast_module_info->self);
05967    return tmp;
05968 }

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

Definition at line 3583 of file chan_iax2.c.

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and transmit_frame().

03584 {
03585 #ifdef SCHED_MULTITHREADED
03586    if (schedule_action(__attempt_transmit, data))
03587 #endif
03588       __attempt_transmit(data);
03589    return 0;
03590 }

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

Definition at line 9251 of file chan_iax2.c.

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

Referenced by socket_process_helper().

09252 {
09253    /* Schedule sending the authentication failure in one second, to prevent
09254       guessing */
09255    if (iaxs[callno]) {
09256       iaxs[callno]->authfail = failcode;
09257       if (delayreject) {
09258          iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
09259             sched, 1000, auth_reject, (void *)(long)callno);
09260       } else
09261          auth_reject((void *)(long)callno);
09262    }
09263    return 0;
09264 }

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

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

09238 {
09239    int callno = (int)(long)(data);
09240    ast_mutex_lock(&iaxsl[callno]);
09241    if (iaxs[callno])
09242       iaxs[callno]->authid = -1;
09243    ast_mutex_unlock(&iaxsl[callno]);
09244 #ifdef SCHED_MULTITHREADED
09245    if (schedule_action(__auth_reject, data))
09246 #endif
09247       __auth_reject(data);
09248    return 0;
09249 }

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

Definition at line 8292 of file chan_iax2.c.

References ast_key_get(), AST_KEY_PRIVATE, ast_log, ast_sign(), ast_sockaddr_stringify_addr(), 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(), MD5Update(), and sig().

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

08293 {
08294    int res = -1;
08295    int x;
08296    if (!ast_strlen_zero(keyn)) {
08297       if (!(authmethods & IAX_AUTH_RSA)) {
08298          if (ast_strlen_zero(secret)) {
08299             ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_sockaddr_stringify_addr(addr));
08300          }
08301       } else if (ast_strlen_zero(challenge)) {
08302          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_sockaddr_stringify_addr(addr));
08303       } else {
08304          char sig[256];
08305          struct ast_key *key;
08306          key = ast_key_get(keyn, AST_KEY_PRIVATE);
08307          if (!key) {
08308             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08309          } else {
08310             if (ast_sign(key, (char*)challenge, sig)) {
08311                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08312                res = -1;
08313             } else {
08314                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08315                res = 0;
08316             }
08317          }
08318       }
08319    }
08320    /* Fall back */
08321    if (res && !ast_strlen_zero(secret)) {
08322       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08323          struct MD5Context md5;
08324          unsigned char digest[16];
08325          char digres[128];
08326          MD5Init(&md5);
08327          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08328          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08329          MD5Final(digest, &md5);
08330          /* If they support md5, authenticate with it.  */
08331          for (x=0;x<16;x++)
08332             sprintf(digres + (x << 1),  "%02hhx", digest[x]); /* safe */
08333          if (pvt) {
08334             build_encryption_keys(digest, pvt);
08335          }
08336          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08337          res = 0;
08338       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08339          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08340          res = 0;
08341       } else
08342          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_sockaddr_stringify_addr(addr), authmethods);
08343    }
08344    return res;
08345 }

static int authenticate_reply ( struct chan_iax2_pvt p,
struct ast_sockaddr addr,
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 8351 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_calloc, ast_channel_datastore_add(), ast_datastore_alloc, ast_datastore_free(), AST_FRAME_IAX, ast_free, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_sockaddr_apply_netmask(), ast_sockaddr_cmp_addr(), ast_sockaddr_copy(), ast_sockaddr_isnull(), 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, 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, NULL, 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_helper().

08352 {
08353    struct iax2_peer *peer = NULL;
08354    /* Start pessimistic */
08355    int res = -1;
08356    int authmethods = 0;
08357    struct iax_ie_data ied;
08358    uint16_t callno = p->callno;
08359 
08360    memset(&ied, 0, sizeof(ied));
08361 
08362    if (ies->username)
08363       ast_string_field_set(p, username, ies->username);
08364    if (ies->challenge)
08365       ast_string_field_set(p, challenge, ies->challenge);
08366    if (ies->authmethods)
08367       authmethods = ies->authmethods;
08368    if (authmethods & IAX_AUTH_MD5)
08369       merge_encryption(p, ies->encmethods);
08370    else
08371       p->encmethods = 0;
08372 
08373    /* Check for override RSA authentication first */
08374    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08375       /* Normal password authentication */
08376       res = authenticate(p->challenge, override, okey, authmethods, &ied, addr, p);
08377    } else {
08378       struct ao2_iterator i = ao2_iterator_init(peers, 0);
08379       while ((peer = ao2_iterator_next(&i))) {
08380          struct ast_sockaddr peer_addr;
08381          struct ast_sockaddr tmp_sockaddr1;
08382          struct ast_sockaddr tmp_sockaddr2;
08383 
08384          ast_sockaddr_copy(&peer_addr, &peer->addr);
08385 
08386          ast_sockaddr_apply_netmask(addr, &peer->mask, &tmp_sockaddr1);
08387          ast_sockaddr_apply_netmask(&peer_addr, &peer->mask, &tmp_sockaddr2);
08388 
08389          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
08390             /* No peer specified at our end, or this is the peer */
08391              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08392              /* No username specified in peer rule, or this is the right username */
08393              && (ast_sockaddr_isnull(&peer_addr) || !(ast_sockaddr_cmp_addr(&tmp_sockaddr1, &tmp_sockaddr2)))
08394              /* No specified host, or this is our host */
08395             ) {
08396             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, addr, p);
08397             if (!res) {
08398                peer_unref(peer);
08399                break;
08400             }
08401          }
08402          peer_unref(peer);
08403       }
08404       ao2_iterator_destroy(&i);
08405       if (!peer) {
08406          /* We checked our list and didn't find one.  It's unlikely, but possible,
08407             that we're trying to authenticate *to* a realtime peer */
08408          const char *peer_name = ast_strdupa(p->peer);
08409          ast_mutex_unlock(&iaxsl[callno]);
08410          if ((peer = realtime_peer(peer_name, NULL))) {
08411             ast_mutex_lock(&iaxsl[callno]);
08412             if (!(p = iaxs[callno])) {
08413                peer_unref(peer);
08414                return -1;
08415             }
08416             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, addr, p);
08417             peer_unref(peer);
08418          }
08419          if (!peer) {
08420             ast_mutex_lock(&iaxsl[callno]);
08421             if (!(p = iaxs[callno]))
08422                return -1;
08423          }
08424       }
08425    }
08426 
08427    if (ies->encmethods) {
08428       ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08429    } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08430       ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n");
08431       return -1;             /* if force encryption is yes, and no encryption methods, then return -1 to hangup */
08432    }
08433    if (!res) {
08434       struct ast_datastore *variablestore;
08435       struct ast_variable *var, *prev = NULL;
08436       AST_LIST_HEAD(, ast_var_t) *varlist;
08437       varlist = ast_calloc(1, sizeof(*varlist));
08438       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08439       if (variablestore && varlist && p->owner) {
08440          variablestore->data = varlist;
08441          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08442          AST_LIST_HEAD_INIT(varlist);
08443          for (var = ies->vars; var; var = var->next) {
08444             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08445             if (prev)
08446                ast_free(prev);
08447             prev = var;
08448             if (!newvar) {
08449                /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */
08450                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08451             } else {
08452                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08453             }
08454          }
08455          if (prev)
08456             ast_free(prev);
08457          ies->vars = NULL;
08458          ast_channel_datastore_add(p->owner, variablestore);
08459       } else {
08460          if (p->owner)
08461             ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08462          if (variablestore)
08463             ast_datastore_free(variablestore);
08464          if (varlist)
08465             ast_free(varlist);
08466       }
08467    }
08468 
08469    if (!res)
08470       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08471    return res;
08472 }

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 7996 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, 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_KEY, iax_ie_data::pos, send_command(), send_command_final(), user_unref(), and chan_iax2_pvt::username.

Referenced by socket_process_helper().

07997 {
07998    struct iax_ie_data ied;
07999    int res = -1, authreq_restrict = 0;
08000    char challenge[10];
08001    struct chan_iax2_pvt *p = iaxs[call_num];
08002 
08003    memset(&ied, 0, sizeof(ied));
08004 
08005    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
08006    if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
08007       struct iax2_user *user;
08008 
08009       user = ao2_find(users, p->username, OBJ_KEY);
08010       if (user) {
08011          if (user->curauthreq == user->maxauthreq)
08012             authreq_restrict = 1;
08013          else
08014             user->curauthreq++;
08015          user = user_unref(user);
08016       }
08017    }
08018 
08019    /* If the AUTHREQ limit test failed, send back an error */
08020    if (authreq_restrict) {
08021       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
08022       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
08023       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
08024       return 0;
08025    }
08026 
08027    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
08028    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
08029       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08030       ast_string_field_set(p, challenge, challenge);
08031       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
08032       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
08033    }
08034    if (p->encmethods)
08035       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
08036 
08037    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
08038 
08039    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
08040 
08041    if (p->encmethods)
08042       ast_set_flag64(p, IAX_ENCRYPTED);
08043 
08044    return res;
08045 }

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

Definition at line 8047 of file chan_iax2.c.

References ao2_find, ast_atomic_fetchadd_int(), ast_check_signature(), ast_clear_flag64, ast_copy_string(), ast_free, ast_key_get(), AST_KEY_PUBLIC, ast_log, ast_strdup, 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, host, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_FORCE_ENCRYPT, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, LOG_ERROR, LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_user::name, NULL, OBJ_KEY, iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, iax2_user::secret, chan_iax2_pvt::state, strsep(), user_unref(), and chan_iax2_pvt::username.

Referenced by socket_process_helper().

08048 {
08049    char requeststr[256];
08050    char md5secret[256] = "";
08051    char secret[256] = "";
08052    char rsasecret[256] = "";
08053    int res = -1;
08054    int x;
08055    struct iax2_user *user;
08056 
08057    if (p->authrej) {
08058       return res;
08059    }
08060 
08061    user = ao2_find(users, p->username, OBJ_KEY);
08062    if (user) {
08063       if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
08064          ast_atomic_fetchadd_int(&user->curauthreq, -1);
08065          ast_clear_flag64(p, IAX_MAXAUTHREQ);
08066       }
08067       ast_string_field_set(p, host, user->name);
08068       user = user_unref(user);
08069    }
08070    if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
08071       ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.\n");
08072       return res;
08073    }
08074    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
08075       return res;
08076    if (ies->password)
08077       ast_copy_string(secret, ies->password, sizeof(secret));
08078    if (ies->md5_result)
08079       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
08080    if (ies->rsa_result)
08081       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
08082    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
08083       struct ast_key *key;
08084       char *keyn;
08085       char *tmpkey;
08086       char *stringp=NULL;
08087       if (!(tmpkey = ast_strdup(p->inkeys))) {
08088          ast_log(LOG_ERROR, "Unable to create a temporary string for parsing stored 'inkeys'\n");
08089          return res;
08090       }
08091       stringp = tmpkey;
08092       keyn = strsep(&stringp, ":");
08093       while(keyn) {
08094          key = ast_key_get(keyn, AST_KEY_PUBLIC);
08095          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
08096             res = 0;
08097             break;
08098          } else if (!key)
08099             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
08100          keyn = strsep(&stringp, ":");
08101       }
08102       ast_free(tmpkey);
08103    } else if (p->authmethods & IAX_AUTH_MD5) {
08104       struct MD5Context md5;
08105       unsigned char digest[16];
08106       char *tmppw, *stringp;
08107       tmppw = ast_strdupa(p->secret);
08108       stringp = tmppw;
08109       while((tmppw = strsep(&stringp, ";"))) {
08110          MD5Init(&md5);
08111          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
08112          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08113          MD5Final(digest, &md5);
08114          /* If they support md5, authenticate with it.  */
08115          for (x=0;x<16;x++)
08116             sprintf(requeststr + (x << 1), "%02hhx", digest[x]); /* safe */
08117          if (!strcasecmp(requeststr, md5secret)) {
08118             res = 0;
08119             break;
08120          }
08121       }
08122    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
08123       if (!strcmp(secret, p->secret))
08124          res = 0;
08125    }
08126    return res;
08127 }

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

Definition at line 4687 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

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

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

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

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

09282 {
09283    int callno = (int)(long)(data);
09284    ast_mutex_lock(&iaxsl[callno]);
09285    if (iaxs[callno]) {
09286       iaxs[callno]->autoid = -1;
09287    }
09288    ast_mutex_unlock(&iaxsl[callno]);
09289 #ifdef SCHED_MULTITHREADED
09290    if (schedule_action(__auto_hangup, data))
09291 #endif
09292       __auto_hangup(data);
09293    return 0;
09294 }

static void build_callno_limits ( struct ast_variable v  )  [static]

Definition at line 2692 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, error(), addr_range::ha, addr_range::limit, LOG_ERROR, ast_variable::name, ast_variable::next, NULL, OBJ_POINTER, and ast_variable::value.

Referenced by set_config().

02693 {
02694    struct addr_range *addr_range = NULL;
02695    struct addr_range tmp;
02696    struct ast_ha *ha;
02697    int limit;
02698    int error;
02699    int found;
02700 
02701    for (; v; v = v->next) {
02702       limit = -1;
02703       error = 0;
02704       found = 0;
02705       ha = ast_append_ha("permit", v->name, NULL, &error);
02706 
02707       /* check for valid config information */
02708       if (error) {
02709          ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02710          continue;
02711       } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02712          ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02713          ast_free_ha(ha);
02714          continue;
02715       }
02716 
02717       ast_copy_ha(ha, &tmp.ha);
02718       /* find or create the addr_range */
02719       if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02720          ao2_lock(addr_range);
02721          found = 1;
02722       } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02723          ast_free_ha(ha);
02724          return; /* out of memory */
02725       }
02726 
02727       /* copy over config data into addr_range object */
02728       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
02729       ast_free_ha(ha); /* cleanup the tmp ha */
02730       addr_range->limit = limit;
02731       addr_range->delme = 0;
02732 
02733       /* cleanup */
02734       if (found) {
02735          ao2_unlock(addr_range);
02736       } else {
02737          ao2_link(callno_limits, addr_range);
02738       }
02739       ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02740    }
02741 }

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

Definition at line 12576 of file chan_iax2.c.

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

Referenced by build_user().

12577 {
12578    struct iax2_context *con;
12579 
12580    if ((con = ast_calloc(1, sizeof(*con))))
12581       ast_copy_string(con->context, context, sizeof(con->context));
12582 
12583    return con;
12584 }

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

Definition at line 6314 of file chan_iax2.c.

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

Referenced by build_encryption_keys(), and iax2_key_rotate().

06315 {
06316    /* it is required to hold the corresponding decrypt key to our encrypt key
06317     * in the pvt struct because queued frames occasionally need to be decrypted and
06318     * re-encrypted when updated for a retransmission */
06319    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06320    ast_aes_set_encrypt_key(digest, &pvt->ecx);
06321    ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06322 }

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

Definition at line 6308 of file chan_iax2.c.

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

Referenced by authenticate(), and decrypt_frame().

06309 {
06310    build_ecx_key(digest, pvt);
06311    ast_aes_set_decrypt_key(digest, &pvt->dcx);
06312 }

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

References iax2_peer::acl, acl_change_stasis_subscribe(), iax2_peer::addr, iax2_peer::adsi, ao2_alloc, ao2_find, AST_AF_UNSPEC, ast_append_acl(), ast_callerid_split(), ast_clear_flag64, ast_copy_flags64, ast_dnsmgr_lookup(), ast_endpoint_create(), ast_false(), ast_free_acl_list(), ast_get_ip(), ast_log, ast_mwi_topic(), ast_parse_arg(), AST_SCHED_DEL, ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_sockaddr_copy(), ast_sockaddr_is_ipv4_mapped(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_string_field_build, ast_string_field_init, ast_string_field_set, ast_strlen_zero, ast_test_flag64, ast_true(), iax2_peer::authmethods, CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, cid_name, cid_num, context, iax2_peer::defaddr, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::endpoint, iax2_peer::expire, iax2_peer::expiry, get_auth_methods(), get_encrypt_methods(), iax2_parse_allow_disallow(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, 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, iax2_peer::name, ast_variable::name, ast_variable::next, NULL, OBJ_KEY, PARSE_IN_RANGE, PARSE_UINT32, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, prefs_global, S_OR, iax2_peer::smoothing, iax2_peer::sockfd, ast_sockaddr::ss, stasis_subscribe_pool(), unlink_peer(), ast_variable::value, and zonetag.

12722 {
12723    struct iax2_peer *peer = NULL;
12724    struct ast_acl_list *oldacl = NULL;
12725    int maskfound = 0;
12726    int found = 0;
12727    int firstpass = 1;
12728    int subscribe_acl_change = 0;
12729 
12730    if (!temponly) {
12731       peer = ao2_find(peers, name, OBJ_KEY);
12732       if (peer && !ast_test_flag64(peer, IAX_DELME))
12733          firstpass = 0;
12734    }
12735 
12736    if (peer) {
12737       found++;
12738       if (firstpass) {
12739          oldacl = peer->acl;
12740          peer->acl = NULL;
12741       }
12742       unlink_peer(peer);
12743    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12744       peer->expire = -1;
12745       peer->pokeexpire = -1;
12746       peer->sockfd = defaultsockfd;
12747       if (ast_string_field_init(peer, 32))
12748          peer = peer_unref(peer);
12749       if (!(peer->endpoint = ast_endpoint_create("IAX2", name))) {
12750          peer = peer_unref(peer);
12751       }
12752    }
12753 
12754    if (peer) {
12755       if (firstpass) {
12756          ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12757          peer->encmethods = iax2_encryption;
12758          peer->adsi = adsi;
12759          ast_string_field_set(peer, secret, "");
12760          if (!found) {
12761             ast_string_field_set(peer, name, name);
12762             ast_sockaddr_parse(&peer->addr, "0.0.0.0", 0);
12763             ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12764             peer->expiry = min_reg_expire;
12765          }
12766          peer->prefs = prefs_global;
12767          peer->capability = iax2_capability;
12768          peer->smoothing = 0;
12769          peer->pokefreqok = DEFAULT_FREQ_OK;
12770          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12771          peer->maxcallno = 0;
12772          peercnt_modify((unsigned char) 0, 0, &peer->addr);
12773          peer->calltoken_required = CALLTOKEN_DEFAULT;
12774          ast_string_field_set(peer,context,"");
12775          ast_string_field_set(peer,peercontext,"");
12776          ast_clear_flag64(peer, IAX_HASCALLERID);
12777          ast_string_field_set(peer, cid_name, "");
12778          ast_string_field_set(peer, cid_num, "");
12779          ast_string_field_set(peer, mohinterpret, mohinterpret);
12780          ast_string_field_set(peer, mohsuggest, mohsuggest);
12781       }
12782 
12783       if (!v) {
12784          v = alt;
12785          alt = NULL;
12786       }
12787       while(v) {
12788          if (!strcasecmp(v->name, "secret")) {
12789             ast_string_field_set(peer, secret, v->value);
12790          } else if (!strcasecmp(v->name, "mailbox")) {
12791             ast_string_field_set(peer, mailbox, v->value);
12792          } else if (!strcasecmp(v->name, "hasvoicemail")) {
12793             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12794                /*
12795                 * hasvoicemail is a users.conf legacy voicemail enable method.
12796                 * hasvoicemail is only going to work for app_voicemail mailboxes.
12797                 */
12798                if (strchr(name, '@')) {
12799                   ast_string_field_set(peer, mailbox, name);
12800                } else {
12801                   ast_string_field_build(peer, mailbox, "%s@default", name);
12802                }
12803             }
12804          } else if (!strcasecmp(v->name, "mohinterpret")) {
12805             ast_string_field_set(peer, mohinterpret, v->value);
12806          } else if (!strcasecmp(v->name, "mohsuggest")) {
12807             ast_string_field_set(peer, mohsuggest, v->value);
12808          } else if (!strcasecmp(v->name, "dbsecret")) {
12809             ast_string_field_set(peer, dbsecret, v->value);
12810          } else if (!strcasecmp(v->name, "description")) {
12811             ast_string_field_set(peer, description, v->value);
12812          } else if (!strcasecmp(v->name, "trunk")) {
12813             ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK);
12814             if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12815                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12816                ast_clear_flag64(peer, IAX_TRUNK);
12817             }
12818          } else if (!strcasecmp(v->name, "auth")) {
12819             peer->authmethods = get_auth_methods(v->value);
12820          } else if (!strcasecmp(v->name, "encryption")) {
12821             peer->encmethods |= get_encrypt_methods(v->value);
12822             if (!peer->encmethods) {
12823                ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12824             }
12825          } else if (!strcasecmp(v->name, "forceencryption")) {
12826             if (ast_false(v->value)) {
12827                ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12828             } else {
12829                peer->encmethods |= get_encrypt_methods(v->value);
12830                if (peer->encmethods) {
12831                   ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12832                }
12833             }
12834          } else if (!strcasecmp(v->name, "transfer")) {
12835             if (!strcasecmp(v->value, "mediaonly")) {
12836                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12837             } else if (ast_true(v->value)) {
12838                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12839             } else
12840                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12841          } else if (!strcasecmp(v->name, "jitterbuffer")) {
12842             ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12843          } else if (!strcasecmp(v->name, "host")) {
12844             if (!strcasecmp(v->value, "dynamic")) {
12845                /* They'll register with us */
12846                ast_set_flag64(peer, IAX_DYNAMIC);
12847                if (!found) {
12848                   int peer_port = ast_sockaddr_port(&peer->addr);
12849                   if (peer_port) {
12850                      ast_sockaddr_set_port(&peer->defaddr, peer_port);
12851                   }
12852                   ast_sockaddr_setnull(&peer->addr);
12853                }
12854             } else {
12855                /* Non-dynamic.  Make sure we become that way if we're not */
12856                AST_SCHED_DEL(sched, peer->expire);
12857                ast_clear_flag64(peer, IAX_DYNAMIC);
12858                peer->addr.ss.ss_family = AST_AF_UNSPEC;
12859                if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) {
12860                   return peer_unref(peer);
12861                }
12862                if (!ast_sockaddr_port(&peer->addr)) {
12863                   ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12864                }
12865             }
12866          } else if (!strcasecmp(v->name, "defaultip")) {
12867             struct ast_sockaddr peer_defaddr_tmp;
12868             peer_defaddr_tmp.ss.ss_family = AF_UNSPEC;
12869             if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12870                return peer_unref(peer);
12871             }
12872             ast_sockaddr_set_port(&peer_defaddr_tmp, ast_sockaddr_port(&peer->defaddr));
12873             ast_sockaddr_copy(&peer->defaddr, &peer_defaddr_tmp);
12874          } else if (!strcasecmp(v->name, "sourceaddress")) {
12875             peer_set_srcaddr(peer, v->value);
12876          } else if (!strcasecmp(v->name, "permit") ||
12877                   !strcasecmp(v->name, "deny") ||
12878                   !strcasecmp(v->name, "acl")) {
12879             ast_append_acl(v->name, v->value, &peer->acl, NULL, &subscribe_acl_change);
12880          } else if (!strcasecmp(v->name, "mask")) {
12881             maskfound++;
12882             ast_sockaddr_parse(&peer->mask, v->value, 0);
12883          } else if (!strcasecmp(v->name, "context")) {
12884             ast_string_field_set(peer, context, v->value);
12885          } else if (!strcasecmp(v->name, "regexten")) {
12886             ast_string_field_set(peer, regexten, v->value);
12887          } else if (!strcasecmp(v->name, "peercontext")) {
12888             ast_string_field_set(peer, peercontext, v->value);
12889          } else if (!strcasecmp(v->name, "port")) {
12890             int bindport;
12891             if (ast_parse_arg(v->value, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535)) {
12892                bindport = IAX_DEFAULT_PORTNO;
12893             }
12894             if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12895                ast_sockaddr_set_port(&peer->defaddr, bindport);
12896             } else {
12897                ast_sockaddr_set_port(&peer->addr, bindport);
12898             }
12899          } else if (!strcasecmp(v->name, "username")) {
12900             ast_string_field_set(peer, username, v->value);
12901          } else if (!strcasecmp(v->name, "allow")) {
12902             iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12903          } else if (!strcasecmp(v->name, "disallow")) {
12904             iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12905          } else if (!strcasecmp(v->name, "callerid")) {
12906             if (!ast_strlen_zero(v->value)) {
12907                char name2[80];
12908                char num2[80];
12909                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12910                ast_string_field_set(peer, cid_name, name2);
12911                ast_string_field_set(peer, cid_num, num2);
12912             } else {
12913                ast_string_field_set(peer, cid_name, "");
12914                ast_string_field_set(peer, cid_num, "");
12915             }
12916             ast_set_flag64(peer, IAX_HASCALLERID);
12917          } else if (!strcasecmp(v->name, "fullname")) {
12918             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12919             ast_set_flag64(peer, IAX_HASCALLERID);
12920          } else if (!strcasecmp(v->name, "cid_number")) {
12921             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12922             ast_set_flag64(peer, IAX_HASCALLERID);
12923          } else if (!strcasecmp(v->name, "sendani")) {
12924             ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12925          } else if (!strcasecmp(v->name, "inkeys")) {
12926             ast_string_field_set(peer, inkeys, v->value);
12927          } else if (!strcasecmp(v->name, "outkey")) {
12928             ast_string_field_set(peer, outkey, v->value);
12929          } else if (!strcasecmp(v->name, "qualify")) {
12930             if (!strcasecmp(v->value, "no")) {
12931                peer->maxms = 0;
12932             } else if (!strcasecmp(v->value, "yes")) {
12933                peer->maxms = DEFAULT_MAXMS;
12934             } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12935                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);
12936                peer->maxms = 0;
12937             }
12938          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12939             peer->smoothing = ast_true(v->value);
12940          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12941             if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12942                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);
12943             }
12944          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12945             if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12946                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);
12947             }
12948          } else if (!strcasecmp(v->name, "timezone")) {
12949             ast_string_field_set(peer, zonetag, v->value);
12950          } else if (!strcasecmp(v->name, "adsi")) {
12951             peer->adsi = ast_true(v->value);
12952          } else if (!strcasecmp(v->name, "connectedline")) {
12953             if (ast_true(v->value)) {
12954                ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12955             } else if (!strcasecmp(v->value, "send")) {
12956                ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12957                ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12958             } else if (!strcasecmp(v->value, "receive")) {
12959                ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12960                ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12961             } else {
12962                ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12963             }
12964          } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12965             if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12966                ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12967             } else {
12968                peercnt_modify((unsigned char) 1, peer->maxcallno, &peer->addr);
12969             }
12970          } else if (!strcasecmp(v->name, "requirecalltoken")) {
12971             /* default is required unless in optional ip list */
12972             if (ast_false(v->value)) {
12973                peer->calltoken_required = CALLTOKEN_NO;
12974             } else if (!strcasecmp(v->value, "auto")) {
12975                peer->calltoken_required = CALLTOKEN_AUTO;
12976             } else if (ast_true(v->value)) {
12977                peer->calltoken_required = CALLTOKEN_YES;
12978             } else {
12979                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12980             }
12981          } /* else if (strcasecmp(v->name,"type")) */
12982          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
12983          v = v->next;
12984          if (!v) {
12985             v = alt;
12986             alt = NULL;
12987          }
12988       }
12989       if (!peer->authmethods)
12990          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12991       ast_clear_flag64(peer, IAX_DELME);
12992    }
12993 
12994    if (!maskfound && !ast_sockaddr_isnull(&peer->addr)) {
12995       if (ast_sockaddr_is_ipv4_mapped(&peer->addr)) {
12996          ast_sockaddr_parse(&peer->mask, "::ffff:ffff:ffff", 0);
12997       } else if (ast_sockaddr_is_ipv6(&peer->addr)) {
12998          ast_sockaddr_parse(&peer->mask, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0);
12999       } else {
13000          ast_sockaddr_parse(&peer->mask, "255.255.255.255", 0);
13001       }
13002    }
13003 
13004    if (oldacl) {
13005       ast_free_acl_list(oldacl);
13006    }
13007 
13008    if (!ast_strlen_zero(peer->mailbox)) {
13009       struct stasis_topic *mailbox_specific_topic;
13010 
13011       mailbox_specific_topic = ast_mwi_topic(peer->mailbox);
13012       if (mailbox_specific_topic) {
13013          peer->mwi_event_sub = stasis_subscribe_pool(mailbox_specific_topic, mwi_event_cb, NULL);
13014       }
13015    }
13016 
13017    if (subscribe_acl_change) {
13018       acl_change_stasis_subscribe();
13019    }
13020 
13021    return peer;
13022 }

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

Definition at line 6298 of file chan_iax2.c.

References ast_random(), and tmp().

Referenced by build_ecx_key(), and update_packet().

06299 {
06300    long tmp;
06301    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06302       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06303       buf += sizeof(tmp);
06304       len -= sizeof(tmp);
06305    }
06306 }

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

References iax2_user::acl, acl_change_stasis_subscribe(), iax2_user::adsi, iax2_user::amaflags, ao2_alloc, ao2_find, ao2_unlink, ast_append_acl(), ast_callerid_split(), ast_channel_string2amaflag(), ast_clear_flag64, ast_copy_flags64, ast_false(), ast_free_acl_list(), ast_log, 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::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), iax2_parse_allow_disallow(), 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_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, iax2_user::name, ast_variable::name, ast_variable::next, iax2_context::next, NULL, OBJ_KEY, parkinglot, iax2_user::prefs, prefs_global, iax2_user::secret, user_destructor(), user_unref(), ast_variable::value, and iax2_user::vars.

13039 {
13040    struct iax2_user *user = NULL;
13041    struct iax2_context *con, *conl = NULL;
13042    struct ast_acl_list *oldacl = NULL;
13043    struct iax2_context *oldcon = NULL;
13044    int format;
13045    int firstpass=1;
13046    int oldcurauthreq = 0;
13047    int subscribe_acl_change = 0;
13048    char *varname = NULL, *varval = NULL;
13049    struct ast_variable *tmpvar = NULL;
13050 
13051    if (!temponly) {
13052       user = ao2_find(users, name, OBJ_KEY);
13053       if (user && !ast_test_flag64(user, IAX_DELME))
13054          firstpass = 0;
13055    }
13056 
13057    if (user) {
13058       if (firstpass) {
13059          oldcurauthreq = user->curauthreq;
13060          oldacl = user->acl;
13061          oldcon = user->contexts;
13062          user->acl = NULL;
13063          user->contexts = NULL;
13064       }
13065       /* Already in the list, remove it and it will be added back (or FREE'd) */
13066       ao2_unlink(users, user);
13067    } else {
13068       user = ao2_alloc(sizeof(*user), user_destructor);
13069    }
13070 
13071    if (user) {
13072       if (firstpass) {
13073          ast_string_field_free_memory(user);
13074          memset(user, 0, sizeof(struct iax2_user));
13075          if (ast_string_field_init(user, 32)) {
13076             user = user_unref(user);
13077             goto cleanup;
13078          }
13079          user->maxauthreq = maxauthreq;
13080          user->curauthreq = oldcurauthreq;
13081          user->prefs = prefs_global;
13082          user->capability = iax2_capability;
13083          user->encmethods = iax2_encryption;
13084          user->adsi = adsi;
13085          user->calltoken_required = CALLTOKEN_DEFAULT;
13086          ast_string_field_set(user, name, name);
13087          ast_string_field_set(user, language, language);
13088          ast_copy_flags64(user, &globalflags, IAX_USEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
13089          ast_clear_flag64(user, IAX_HASCALLERID);
13090          ast_string_field_set(user, cid_name, "");
13091          ast_string_field_set(user, cid_num, "");
13092          ast_string_field_set(user, accountcode, accountcode);
13093          ast_string_field_set(user, mohinterpret, mohinterpret);
13094          ast_string_field_set(user, mohsuggest, mohsuggest);
13095       }
13096       if (!v) {
13097          v = alt;
13098          alt = NULL;
13099       }
13100       while(v) {
13101          if (!strcasecmp(v->name, "context")) {
13102             con = build_context(v->value);
13103             if (con) {
13104                if (conl)
13105                   conl->next = con;
13106                else
13107                   user->contexts = con;
13108                conl = con;
13109             }
13110          } else if (!strcasecmp(v->name, "permit") ||
13111                   !strcasecmp(v->name, "deny") ||
13112                   !strcasecmp(v->name, "acl")) {
13113             ast_append_acl(v->name, v->value, &user->acl, NULL, &subscribe_acl_change);
13114          } else if (!strcasecmp(v->name, "setvar")) {
13115             varname = ast_strdupa(v->value);
13116             if ((varval = strchr(varname, '='))) {
13117                *varval = '\0';
13118                varval++;
13119                if((tmpvar = ast_variable_new(varname, varval, ""))) {
13120                   tmpvar->next = user->vars;
13121                   user->vars = tmpvar;
13122                }
13123             }
13124          } else if (!strcasecmp(v->name, "allow")) {
13125             iax2_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
13126          } else if (!strcasecmp(v->name, "disallow")) {
13127             iax2_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
13128          } else if (!strcasecmp(v->name, "trunk")) {
13129             ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);
13130             if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
13131                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
13132                ast_clear_flag64(user, IAX_TRUNK);
13133             }
13134          } else if (!strcasecmp(v->name, "auth")) {
13135             user->authmethods = get_auth_methods(v->value);
13136          } else if (!strcasecmp(v->name, "encryption")) {
13137             user->encmethods |= get_encrypt_methods(v->value);
13138             if (!user->encmethods) {
13139                ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
13140             }
13141          } else if (!strcasecmp(v->name, "forceencryption")) {
13142             if (ast_false(v->value)) {
13143                ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
13144             } else {
13145                user->encmethods |= get_encrypt_methods(v->value);
13146                if (user->encmethods) {
13147                   ast_set_flag64(user, IAX_FORCE_ENCRYPT);
13148                }
13149             }
13150          } else if (!strcasecmp(v->name, "transfer")) {
13151             if (!strcasecmp(v->value, "mediaonly")) {
13152                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13153             } else if (ast_true(v->value)) {
13154                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13155             } else
13156                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13157          } else if (!strcasecmp(v->name, "codecpriority")) {
13158             if(!strcasecmp(v->value, "caller"))
13159                ast_set_flag64(user, IAX_CODEC_USER_FIRST);
13160             else if(!strcasecmp(v->value, "disabled"))
13161                ast_set_flag64(user, IAX_CODEC_NOPREFS);
13162             else if(!strcasecmp(v->value, "reqonly")) {
13163                ast_set_flag64(user, IAX_CODEC_NOCAP);
13164                ast_set_flag64(user, IAX_CODEC_NOPREFS);
13165             }
13166          } else if (!strcasecmp(v->name, "immediate")) {
13167             ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
13168          } else if (!strcasecmp(v->name, "jitterbuffer")) {
13169             ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
13170          } else if (!strcasecmp(v->name, "dbsecret")) {
13171             ast_string_field_set(user, dbsecret, v->value);
13172          } else if (!strcasecmp(v->name, "secret")) {
13173             if (!ast_strlen_zero(user->secret)) {
13174                char *old = ast_strdupa(user->secret);
13175 
13176                ast_string_field_build(user, secret, "%s;%s", old, v->value);
13177             } else
13178                ast_string_field_set(user, secret, v->value);
13179          } else if (!strcasecmp(v->name, "callerid")) {
13180             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
13181                char name2[80];
13182                char num2[80];
13183                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
13184                ast_string_field_set(user, cid_name, name2);
13185                ast_string_field_set(user, cid_num, num2);
13186                ast_set_flag64(user, IAX_HASCALLERID);
13187             } else {
13188                ast_clear_flag64(user, IAX_HASCALLERID);
13189                ast_string_field_set(user, cid_name, "");
13190                ast_string_field_set(user, cid_num, "");
13191             }
13192          } else if (!strcasecmp(v->name, "fullname")) {
13193             if (!ast_strlen_zero(v->value)) {
13194                ast_string_field_set(user, cid_name, v->value);
13195                ast_set_flag64(user, IAX_HASCALLERID);
13196             } else {
13197                ast_string_field_set(user, cid_name, "");
13198                if (ast_strlen_zero(user->cid_num))
13199                   ast_clear_flag64(user, IAX_HASCALLERID);
13200             }
13201          } else if (!strcasecmp(v->name, "cid_number")) {
13202             if (!ast_strlen_zero(v->value)) {
13203                ast_string_field_set(user, cid_num, v->value);
13204                ast_set_flag64(user, IAX_HASCALLERID);
13205             } else {
13206                ast_string_field_set(user, cid_num, "");
13207                if (ast_strlen_zero(user->cid_name))
13208                   ast_clear_flag64(user, IAX_HASCALLERID);
13209             }
13210          } else if (!strcasecmp(v->name, "accountcode")) {
13211             ast_string_field_set(user, accountcode, v->value);
13212          } else if (!strcasecmp(v->name, "mohinterpret")) {
13213             ast_string_field_set(user, mohinterpret, v->value);
13214          } else if (!strcasecmp(v->name, "mohsuggest")) {
13215             ast_string_field_set(user, mohsuggest, v->value);
13216          } else if (!strcasecmp(v->name, "parkinglot")) {
13217             ast_string_field_set(user, parkinglot, v->value);
13218          } else if (!strcasecmp(v->name, "language")) {
13219             ast_string_field_set(user, language, v->value);
13220          } else if (!strcasecmp(v->name, "amaflags")) {
13221             format = ast_channel_string2amaflag(v->value);
13222             if (format < 0) {
13223                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13224             } else {
13225                user->amaflags = format;
13226             }
13227          } else if (!strcasecmp(v->name, "inkeys")) {
13228             ast_string_field_set(user, inkeys, v->value);
13229          } else if (!strcasecmp(v->name, "maxauthreq")) {
13230             user->maxauthreq = atoi(v->value);
13231             if (user->maxauthreq < 0)
13232                user->maxauthreq = 0;
13233          } else if (!strcasecmp(v->name, "adsi")) {
13234             user->adsi = ast_true(v->value);
13235          } else if (!strcasecmp(v->name, "connectedline")) {
13236             if (ast_true(v->value)) {
13237                ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13238             } else if (!strcasecmp(v->value, "send")) {
13239                ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
13240                ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
13241             } else if (!strcasecmp(v->value, "receive")) {
13242                ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
13243                ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
13244             } else {
13245                ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13246             }
13247          } else if (!strcasecmp(v->name, "requirecalltoken")) {
13248             /* default is required unless in optional ip list */
13249             if (ast_false(v->value)) {
13250                user->calltoken_required = CALLTOKEN_NO;
13251             } else if (!strcasecmp(v->value, "auto")) {
13252                user->calltoken_required = CALLTOKEN_AUTO;
13253             } else if (ast_true(v->value)) {
13254                user->calltoken_required = CALLTOKEN_YES;
13255             } else {
13256                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13257             }
13258          } /* else if (strcasecmp(v->name,"type")) */
13259          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13260          v = v->next;
13261          if (!v) {
13262             v = alt;
13263             alt = NULL;
13264          }
13265       }
13266       if (!user->authmethods) {
13267          if (!ast_strlen_zero(user->secret)) {
13268             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
13269             if (!ast_strlen_zero(user->inkeys))
13270                user->authmethods |= IAX_AUTH_RSA;
13271          } else if (!ast_strlen_zero(user->inkeys)) {
13272             user->authmethods = IAX_AUTH_RSA;
13273          } else {
13274             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
13275          }
13276       }
13277       ast_clear_flag64(user, IAX_DELME);
13278    }
13279 cleanup:
13280    if (oldacl) {
13281       ast_free_acl_list(oldacl);
13282    }
13283    if (oldcon) {
13284       free_context(oldcon);
13285    }
13286 
13287    if (subscribe_acl_change) {
13288       acl_change_stasis_subscribe();
13289    }
13290 
13291    return user;
13292 }

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

Definition at line 13970 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, NULL, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, iax_ie_data::pos, send_command(), create_addr_info::sockfd, and parsed_dial_string::username.

Referenced by find_cache().

13971 {
13972    struct ast_sockaddr addr;
13973    int x;
13974    int callno;
13975    struct iax_ie_data ied;
13976    struct create_addr_info cai;
13977    struct parsed_dial_string pds;
13978    char *tmpstr;
13979 
13980    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13981       /* Look for an *exact match* call.  Once a call is negotiated, it can only
13982          look up entries for a single context */
13983       if (!ast_mutex_trylock(&iaxsl[x])) {
13984          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13985             return x;
13986          ast_mutex_unlock(&iaxsl[x]);
13987       }
13988    }
13989 
13990    /* No match found, we need to create a new one */
13991 
13992    memset(&cai, 0, sizeof(cai));
13993    memset(&ied, 0, sizeof(ied));
13994    memset(&pds, 0, sizeof(pds));
13995 
13996    tmpstr = ast_strdupa(data);
13997    parse_dial_string(tmpstr, &pds);
13998 
13999    if (ast_strlen_zero(pds.peer)) {
14000       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
14001       return -1;
14002    }
14003 
14004    /* Populate our address from the given */
14005    if (create_addr(pds.peer, NULL, &addr, &cai))
14006       return -1;
14007 
14008    ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
14009       pds.peer, pds.username, pds.password, pds.context);
14010 
14011    callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
14012    if (callno < 1) {
14013       ast_log(LOG_WARNING, "Unable to create call\n");
14014       return -1;
14015    }
14016 
14017    ast_string_field_set(iaxs[callno], dproot, data);
14018    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
14019 
14020    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
14021    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
14022    /* the string format is slightly different from a standard dial string,
14023       because the context appears in the 'exten' position
14024    */
14025    if (pds.exten)
14026       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
14027    if (pds.username)
14028       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
14029    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
14030    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
14031    /* Keep password handy */
14032    if (pds.password)
14033       ast_string_field_set(iaxs[callno], secret, pds.password);
14034    if (pds.key)
14035       ast_string_field_set(iaxs[callno], outkey, pds.key);
14036    /* Start the call going */
14037    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
14038    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
14039 
14040    return callno;
14041 }

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

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

06150 {
06151    /* Returns where in "receive time" we are.  That is, how many ms
06152       since we received (or would have received) the frame with timestamp 0 */
06153    int ms;
06154 #ifdef IAXTESTS
06155    int jit;
06156 #endif /* IAXTESTS */
06157    /* Setup rxcore if necessary */
06158    if (ast_tvzero(p->rxcore)) {
06159       p->rxcore = ast_tvnow();
06160       if (iaxdebug)
06161          ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %ums\n",
06162                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06163       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06164 #if 1
06165       if (iaxdebug)
06166          ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06167                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06168 #endif
06169    }
06170 
06171    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06172 #ifdef IAXTESTS
06173    if (test_jit) {
06174       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06175          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06176          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06177             jit = -jit;
06178          ms += jit;
06179       }
06180    }
06181    if (test_late) {
06182       ms += test_late;
06183       test_late = 0;
06184    }
06185 #endif /* IAXTESTS */
06186    return ms;
06187 }

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

Definition at line 6014 of file chan_iax2.c.

References abs, ast_debug, ast_format_get_sample_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_subclass::format, ast_frame::frametype, iax2_trunk_peer::lastsent, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, NULL, chan_iax2_pvt::offset, chan_iax2_pvt::peercallno, ast_frame::samples, and ast_frame::subclass.

Referenced by iax2_send(), and socket_process_helper().

06015 {
06016    int ms;
06017    int voice = 0;
06018    int genuine = 0;
06019    int adjust;
06020    int rate = 0;
06021    struct timeval *delivery = NULL;
06022 
06023 
06024    /* What sort of frame do we have?: voice is self-explanatory
06025       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
06026       non-genuine frames are CONTROL frames [ringing etc], DTMF
06027       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
06028       the others need a timestamp slaved to the voice frames so that they go in sequence
06029    */
06030    if (f->frametype == AST_FRAME_VOICE) {
06031       voice = 1;
06032       rate = ast_format_get_sample_rate(f->subclass.format) / 1000;
06033       delivery = &f->delivery;
06034    } else if (f->frametype == AST_FRAME_IAX) {
06035       genuine = 1;
06036    } else if (f->frametype == AST_FRAME_CNG) {
06037       p->notsilenttx = 0;
06038    }
06039 
06040    if (ast_tvzero(p->offset)) {
06041       p->offset = ast_tvnow();
06042       /* Round to nearest 20ms for nice looking traces */
06043       p->offset.tv_usec -= p->offset.tv_usec % 20000;
06044    }
06045    /* If the timestamp is specified, just send it as is */
06046    if (ts)
06047       return ts;
06048    /* If we have a time that the frame arrived, always use it to make our timestamp */
06049    if (delivery && !ast_tvzero(*delivery)) {
06050       ms = ast_tvdiff_ms(*delivery, p->offset);
06051       if (ms < 0) {
06052          ms = 0;
06053       }
06054       if (iaxdebug)
06055          ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
06056    } else {
06057       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
06058       if (ms < 0)
06059          ms = 0;
06060       if (voice) {
06061          /* On a voice frame, use predicted values if appropriate */
06062          adjust = (ms - p->nextpred);
06063          if (p->notsilenttx && abs(adjust) <= MAX_TIMESTAMP_SKEW) {
06064             /* Adjust our txcore, keeping voice and non-voice synchronized */
06065             /* AN EXPLANATION:
06066                When we send voice, we usually send "calculated" timestamps worked out
06067                on the basis of the number of samples sent. When we send other frames,
06068                we usually send timestamps worked out from the real clock.
06069                The problem is that they can tend to drift out of step because the
06070                   source channel's clock and our clock may not be exactly at the same rate.
06071                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
06072                for this call.  Moving it adjusts timestamps for non-voice frames.
06073                We make the adjustment in the style of a moving average.  Each time we
06074                adjust p->offset by 10% of the difference between our clock-derived
06075                timestamp and the predicted timestamp.  That's why you see "10000"
06076                below even though IAX2 timestamps are in milliseconds.
06077                The use of a moving average avoids offset moving too radically.
06078                Generally, "adjust" roams back and forth around 0, with offset hardly
06079                changing at all.  But if a consistent different starts to develop it
06080                will be eliminated over the course of 10 frames (200-300msecs)
06081             */
06082             if (adjust < 0)
06083                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
06084             else if (adjust > 0)
06085                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
06086 
06087             if (!p->nextpred) {
06088                p->nextpred = ms; /*f->samples / rate;*/
06089                if (p->nextpred <= p->lastsent)
06090                   p->nextpred = p->lastsent + 3;
06091             }
06092             ms = p->nextpred;
06093          } else {
06094                 /* in this case, just use the actual
06095             * time, since we're either way off
06096             * (shouldn't happen), or we're  ending a
06097             * silent period -- and seed the next
06098             * predicted time.  Also, round ms to the
06099             * next multiple of frame size (so our
06100             * silent periods are multiples of
06101             * frame size too) */
06102 
06103             if (iaxdebug && abs(adjust) > MAX_TIMESTAMP_SKEW )
06104                ast_debug(1, "predicted timestamp skew (%d) > max (%d), using real ts instead.\n",
06105                   abs(adjust), MAX_TIMESTAMP_SKEW);
06106 
06107             if (f->samples >= rate) /* check to make sure we don't core dump */
06108             {
06109                int diff = ms % (f->samples / rate);
06110                if (diff)
06111                    ms += f->samples/rate - diff;
06112             }
06113 
06114             p->nextpred = ms;
06115             p->notsilenttx = 1;
06116          }
06117       } else if ( f->frametype == AST_FRAME_VIDEO ) {
06118          /*
06119          * IAX2 draft 03 says that timestamps MUST be in order.
06120          * It does not say anything about several frames having the same timestamp
06121          * When transporting video, we can have a frame that spans multiple iax packets
06122          * (so called slices), so it would make sense to use the same timestamp for all of
06123          * them
06124          * We do want to make sure that frames don't go backwards though
06125          */
06126          if ( (unsigned int)ms < p->lastsent )
06127             ms = p->lastsent;
06128       } else {
06129          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
06130             it's a genuine frame */
06131          adjust = (ms - p->lastsent);
06132          if (genuine) {
06133             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
06134             if (ms <= p->lastsent)
06135                ms = p->lastsent + 3;
06136          } else if (abs(adjust) <= MAX_TIMESTAMP_SKEW) {
06137             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
06138             ms = p->lastsent + 3;
06139          }
06140       }
06141    }
06142    p->lastsent = ms;
06143    if (voice) {
06144       p->nextpred = p->nextpred + f->samples / rate;
06145    }
06146    return ms;
06147 }

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

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

05971 {
05972    unsigned long int mssincetx; /* unsigned to handle overflows */
05973    long int ms, pred;
05974 
05975    tpeer->trunkact = *now;
05976    mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05977    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05978       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
05979       tpeer->txtrunktime = *now;
05980       tpeer->lastsent = 999999;
05981    }
05982    /* Update last transmit time now */
05983    tpeer->lasttxtime = *now;
05984 
05985    /* Calculate ms offset */
05986    ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05987    /* Predict from last value */
05988    pred = tpeer->lastsent + sampms;
05989    if (labs(ms - pred) < MAX_TIMESTAMP_SKEW)
05990       ms = pred;
05991 
05992    /* We never send the same timestamp twice, so fudge a little if we must */
05993    if (ms == tpeer->lastsent)
05994       ms = tpeer->lastsent + 1;
05995    tpeer->lastsent = ms;
05996    return ms;
05997 }

static int calltoken_required ( struct ast_sockaddr addr,
const char *  name,
int  subclass 
) [static]

Definition at line 2446 of file chan_iax2.c.

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

Referenced by handle_call_token().

02447 {
02448    struct addr_range *addr_range;
02449    struct iax2_peer *peer = NULL;
02450    struct iax2_user *user = NULL;
02451    /* if no username is given, check for guest accounts */
02452    const char *find = S_OR(name, "guest");
02453    int res = 1;  /* required by default */
02454    int optional = 0;
02455    enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02456    /* There are only two cases in which calltoken validation is not required.
02457     * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
02458     *         the peer definition has not set the requirecalltoken option.
02459     * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
02460     */
02461 
02462    /* ----- Case 1 ----- */
02463    if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, addr))) {
02464       ao2_ref(addr_range, -1);
02465       optional = 1;
02466    }
02467 
02468    /* ----- Case 2 ----- */
02469    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02470       calltoken_required = user->calltoken_required;
02471    } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, addr))) {
02472       calltoken_required = user->calltoken_required;
02473    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02474       calltoken_required = peer->calltoken_required;
02475    } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, addr))) {
02476       calltoken_required = peer->calltoken_required;
02477    }
02478 
02479    if (peer) {
02480       peer_unref(peer);
02481    }
02482    if (user) {
02483       user_unref(user);
02484    }
02485 
02486    ast_debug(1, "Determining if address %s with username %s requires calltoken validation.  Optional = %d  calltoken_required = %u \n", ast_sockaddr_stringify_addr(addr), name, optional, calltoken_required);
02487    if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02488       (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02489       res = 0;
02490    }
02491 
02492    return res;
02493 }

static int check_access ( int  callno,
struct ast_sockaddr addr,
struct iax_ies ies 
) [static]

Definition at line 7730 of file chan_iax2.c.

References iax2_user::accountcode, iax2_user::acl, 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_acl(), ast_copy_flags64, ast_db_get(), ast_log, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_SENSE_ALLOW, AST_SENSE_DENY, ast_set2_flag64, ast_set_flag64, ast_shrink_phone_number(), ast_sockaddr_stringify_addr(), 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_codec_pref_convert(), iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCE_ENCRYPT, 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, NULL, parkinglot, iax2_user::parkinglot, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, iax_ies::rdnis, realtime_user(), chan_iax2_pvt::rprefs, 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_helper().

07731 {
07732    /* Start pessimistic */
07733    int res = -1;
07734    int version = 2;
07735    struct iax2_user *user = NULL, *best = NULL;
07736    int bestscore = 0;
07737    int gotcapability = 0;
07738    struct ast_variable *v = NULL, *tmpvar = NULL;
07739    struct ao2_iterator i;
07740 
07741    if (!iaxs[callno])
07742       return res;
07743    if (ies->called_number)
07744       ast_string_field_set(iaxs[callno], exten, ies->called_number);
07745    if (ies->calling_number) {
07746       if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) {
07747          ast_shrink_phone_number(ies->calling_number);
07748       }
07749       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07750    }
07751    if (ies->calling_name)
07752       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07753    if (ies->calling_ani)
07754       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07755    if (ies->dnid)
07756       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07757    if (ies->rdnis)
07758       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07759    if (ies->called_context)
07760       ast_string_field_set(iaxs[callno], context, ies->called_context);
07761    if (ies->language)
07762       ast_string_field_set(iaxs[callno], language, ies->language);
07763    if (ies->username)
07764       ast_string_field_set(iaxs[callno], username, ies->username);
07765    if (ies->calling_ton > -1)
07766       iaxs[callno]->calling_ton = ies->calling_ton;
07767    if (ies->calling_tns > -1)
07768       iaxs[callno]->calling_tns = ies->calling_tns;
07769    if (ies->calling_pres > -1)
07770       iaxs[callno]->calling_pres = ies->calling_pres;
07771    if (ies->format)
07772       iaxs[callno]->peerformat = ies->format;
07773    if (ies->adsicpe)
07774       iaxs[callno]->peeradsicpe = ies->adsicpe;
07775    if (ies->capability) {
07776       gotcapability = 1;
07777       iaxs[callno]->peercapability = ies->capability;
07778    }
07779    if (ies->version)
07780       version = ies->version;
07781 
07782    /* Use provided preferences until told otherwise for actual preferences */
07783    if (ies->codec_prefs) {
07784       iax2_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07785    } else {
07786       memset(&iaxs[callno]->rprefs, 0, sizeof(iaxs[callno]->rprefs));
07787    }
07788    iaxs[callno]->prefs = iaxs[callno]->rprefs;
07789 
07790    if (!gotcapability) {
07791       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07792    }
07793    if (version > IAX_PROTO_VERSION) {
07794       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07795             ast_sockaddr_stringify_addr(addr), version);
07796       return res;
07797    }
07798    /* Search the userlist for a compatible entry, and fill in the rest */
07799    i = ao2_iterator_init(users, 0);
07800    while ((user = ao2_iterator_next(&i))) {
07801       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
07802          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
07803          && (ast_apply_acl(user->acl, addr, "IAX2 user ACL: ") == AST_SENSE_ALLOW)  /* Access is permitted from this IP */
07804          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
07805               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
07806          if (!ast_strlen_zero(iaxs[callno]->username)) {
07807             /* Exact match, stop right now. */
07808             if (best)
07809                user_unref(best);
07810             best = user;
07811             break;
07812          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07813             /* No required authentication */
07814             if (user->acl) {
07815                /* There was host authentication and we passed, bonus! */
07816                if (bestscore < 4) {
07817                   bestscore = 4;
07818                   if (best)
07819                      user_unref(best);
07820                   best = user;
07821                   continue;
07822                }
07823             } else {
07824                /* No host access, but no secret, either, not bad */
07825                if (bestscore < 3) {
07826                   bestscore = 3;
07827                   if (best)
07828                      user_unref(best);
07829                   best = user;
07830                   continue;
07831                }
07832             }
07833          } else {
07834             if (user->acl) {
07835                /* Authentication, but host access too, eh, it's something.. */
07836                if (bestscore < 2) {
07837                   bestscore = 2;
07838                   if (best)
07839                      user_unref(best);
07840                   best = user;
07841                   continue;
07842                }
07843             } else {
07844                /* Authentication and no host access...  This is our baseline */
07845                if (bestscore < 1) {
07846                   bestscore = 1;
07847                   if (best)
07848                      user_unref(best);
07849                   best = user;
07850                   continue;
07851                }
07852             }
07853          }
07854       }
07855       user_unref(user);
07856    }
07857    ao2_iterator_destroy(&i);
07858    user = best;
07859    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07860       user = realtime_user(iaxs[callno]->username, addr);
07861       if (user && (ast_apply_acl(user->acl, addr, "IAX2 user ACL: ") == AST_SENSE_DENY    /* Access is denied from this IP */
07862          || (!ast_strlen_zero(iaxs[callno]->context) &&              /* No context specified */
07863             !apply_context(user->contexts, iaxs[callno]->context)))) {  /* Context is permitted */
07864          user = user_unref(user);
07865       }
07866    }
07867    if (user) {
07868       /* We found our match (use the first) */
07869       /* copy vars */
07870       for (v = user->vars ; v ; v = v->next) {
07871          if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07872             tmpvar->next = iaxs[callno]->vars;
07873             iaxs[callno]->vars = tmpvar;
07874          }
07875       }
07876       /* If a max AUTHREQ restriction is in place, activate it */
07877       if (user->maxauthreq > 0)
07878          ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07879       iaxs[callno]->prefs = user->prefs;
07880       ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07881       iaxs[callno]->encmethods = user->encmethods;
07882       /* Store the requested username if not specified */
07883       if (ast_strlen_zero(iaxs[callno]->username))
07884          ast_string_field_set(iaxs[callno], username, user->name);
07885       /* Store whether this is a trunked call, too, of course, and move if appropriate */
07886       ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07887       iaxs[callno]->capability = user->capability;
07888       /* And use the default context */