Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
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 <signal.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/mwi.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/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/astobj2.h"
#include "asterisk/timing.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/test.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 "iax2/include/netsock.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  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
 
struct  chan_iax2_pvt::signaling_queue
 
struct  signaling_queue_entry
 
struct  tpeers
 

Macros

#define ACN_FORMAT1   "%-24.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 AUTH_METHOD_NAMES_BUFSIZE   19
 
#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" /* address + port + ts + randomcalldata */
 
#define CALLTOKEN_IE_FORMAT   "%u?%s" /* time + ? + (40 char hash) */
 
#define DEBUG_SCHED_MULTITHREAD
 
#define DEBUG_SUPPORT
 
#define DEFAULT_CONTEXT   "default"
 
#define DEFAULT_DROP   3
 
#define DEFAULT_FREQ_NOTOK   10 * 1000 /* How often to check, if the host is down... */
 
#define DEFAULT_FREQ_OK   60 * 1000 /* How often to check for the host to be up */
 
#define DEFAULT_MAX_THREAD_COUNT   100
 
#define DEFAULT_MAXMS   2000 /* Must be faster than 2 seconds by default */
 
#define DEFAULT_RETRY_TIME   1000
 
#define DEFAULT_THREAD_COUNT   10
 
#define DEFAULT_TRUNKDATA   640 * 10
 
#define FORMAT   "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
 
#define FORMAT   "%-45.45s %-6.6s %-10.10s %-45.45s %8d %s\n"
 
#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 FORMAT2   "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
 
#define FORMAT2   "%-45.45s %-6.6s %-10.10s %-45.45s %8.8s %s\n"
 
#define FORMAT2   "%-20.20s %-40.40s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\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)(1LLU << 26)
 
#define IAX_ALREADYGONE   (uint64_t)(1LLU << 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)(1LLU << 16)
 
#define IAX_CODEC_NOPREFS   (uint64_t)(1LLU << 15)
 
#define IAX_CODEC_USER_FIRST   (uint64_t)(1LLU << 14)
 
#define IAX_DEBUGDIGEST(msg, key)
 
#define IAX_DELAYPBXSTART   (uint64_t)(1LLU << 25)
 
#define IAX_DELME   (uint64_t)(1LLU << 1)
 
#define IAX_DYNAMIC   (uint64_t)(1LLU << 6)
 
#define IAX_ENCRYPTED   (uint64_t)(1LLU << 12)
 
#define IAX_FORCE_ENCRYPT   (uint64_t)(1LLU << 30)
 
#define IAX_HASCALLERID   (uint64_t)(1LLU << 0)
 
#define IAX_IMMEDIATE   (uint64_t)(1LLU << 27)
 
#define IAX_KEYPOPULATED   (uint64_t)(1LLU << 13)
 
#define IAX_MAXAUTHREQ   (uint64_t)(1LLU << 24)
 
#define IAX_NOTRANSFER   (uint64_t)(1LLU << 4)
 
#define IAX_PROVISION   (uint64_t)(1LLU << 10)
 
#define IAX_QUELCH   (uint64_t)(1LLU << 11)
 
#define IAX_RECVCONNECTEDLINE   (uint64_t)(1LLU << 29)
 
#define IAX_RTAUTOCLEAR   (uint64_t)(1LLU << 19)
 
#define IAX_RTCACHEFRIENDS   (uint64_t)(1LLU << 17)
 
#define IAX_RTIGNOREREGEXPIRE   (uint64_t)(1LLU << 21)
 
#define IAX_RTSAVE_SYSNAME   (uint64_t)(1LLU << 8)
 
#define IAX_RTUPDATE   (uint64_t)(1LLU << 18)
 
#define IAX_SENDANI   (uint64_t)(1LLU << 7)
 
#define IAX_SENDCONNECTEDLINE   (uint64_t)(1LLU << 28)
 
#define IAX_SHRINKCALLERID   (uint64_t)(1LLU << 31)
 
#define IAX_TEMPONLY   (uint64_t)(1LLU << 2)
 
#define IAX_TRANSFERMEDIA   (uint64_t)(1LLU << 23)
 
#define IAX_TRUNK   (uint64_t)(1LLU << 3)
 
#define IAX_TRUNKTIMESTAMPS   (uint64_t)(1LLU << 22)
 
#define IAX_USEJITTERBUF   (uint64_t)(1LLU << 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. More...
 
#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 /* Don't reuse a call number within 60 seconds */
 
#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)
 
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. More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int attempt_transmit (const void *data)
 
static int auth_fail (int callno, int failcode)
 
static char * auth_method_names (int authmethods, char *restrict buf)
 Get names of all auth methods. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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 More...
 
static iax2_format iax2_codec_choose (struct iax2_codec_pref *pref, iax2_format formats)
 
static unsigned int iax2_datetime (const char *tz)
 
static int iax2_delete_from_sched (const void *data)
 
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 —. More...
 
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. More...
 
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. More...
 
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 More...
 
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 int iax2_lock_callno_unless_destroyed (int callno)
 Acquire the iaxsl[callno] if call exists and not having ongoing hangup. More...
 
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. More...
 
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. More...
 
static int iax2_queue_hangup (int callno)
 Queue a hangup frame on the ast_channel owner. More...
 
static int iax2_queue_hold (int callno, const char *musicclass)
 Queue a hold frame on the ast_channel owner. More...
 
static int iax2_queue_unhold (int callno)
 Queue an unhold frame on the ast_channel owner. More...
 
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 int invalid_key (ast_aes_decrypt_key *ecx)
 
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. More...
 
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 More...
 
static int manager_iax2_show_peers (struct mansession *s, const struct message *m)
 callback to display iax peers in manager More...
 
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 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. More...
 
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. More...
 
static int peer_status (struct iax2_peer *peer, char *status, int statuslen)
 peer_status: Report Peer status in character string More...
 
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 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. More...
 
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. More...
 
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. More...
 
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. More...
 
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 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, .requires = "dnsmgr", .optional_modules = "res_crypto", }
 
static char accountcode [AST_MAX_ACCOUNT_CODE]
 
static struct stasis_subscriptionacl_change_sub
 
static struct active_list active_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static int adsi = 0
 
static int amaflags = 0
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static const char * auth_method_labels []
 Name of effective auth method. More...
 
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_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
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
 
static struct dpcache dpcache = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static struct dynamic_list dynamic_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 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 More...
 
static int global_max_trunk_mtu
 
static uint16_t global_maxcallno
 
static uint16_t global_maxcallno_nonval
 
static int global_rtautoclear = 120
 
static struct ast_flags64 globalflags = { 0 }
 
static int iax2_authmethods = 0
 
static iax2_format iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH
 
static int iax2_encryption = 0
 
static int(* iax2_regfunk )(const char *username, int onoff) = NULL
 
static struct ast_switch iax2_switch
 
static struct ast_channel_tech iax2_tech
 
static const struct ast_datastore_info iax2_variable_datastore_info
 
static struct ao2_containeriax_peercallno_pvts
 Another container of iax2_pvt structures. More...
 
static struct ao2_containeriax_transfercallno_pvts
 Another container of iax2_pvt structures. More...
 
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 More...
 
static ast_mutex_t iaxsl [ARRAY_LEN(iaxs)]
 chan_iax2_pvt structure locks More...
 
static int iaxthreadcount = DEFAULT_THREAD_COUNT
 
static int iaxtrunkdebug = 0
 
static struct ast_custom_function iaxvar_function
 
static struct idle_list idle_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
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 int ping_time = 21
 
static struct iax2_codec_pref prefs_global
 
struct {
   unsigned int   cos
 
   unsigned int   tos
 
qos = { 0, 0 }
 
static int randomcalltokendata
 
static char regcontext [AST_MAX_CONTEXT] = ""
 
static struct registrations registrations = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
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 tpeers tpeers = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static struct ast_taskprocessortransmit_processor
 
static int trunk_maxmtu
 
static int trunk_nmaxmtu
 
static int trunk_timed
 
static int trunk_untimed
 
static int trunkfreq = 20
 
static int trunkmaxsize = MAX_TRUNKDATA
 
static struct ao2_containerusers
 

Detailed Description

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

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Todo:
Implement musicclass settings for IAX2 devices

Definition in file chan_iax2.c.

Macro Definition Documentation

◆ ACN_FORMAT1

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

◆ ACN_FORMAT2

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

◆ AUTH_METHOD_NAMES_BUFSIZE

#define AUTH_METHOD_NAMES_BUFSIZE   19

Definition at line 407 of file chan_iax2.c.

◆ CALLNO_ENTRY_GET_CALLNO

#define CALLNO_ENTRY_GET_CALLNO (   a)    ((a) & 0x7FFF)

Definition at line 955 of file chan_iax2.c.

◆ CALLNO_ENTRY_IS_VALIDATED

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

Definition at line 954 of file chan_iax2.c.

◆ CALLNO_ENTRY_SET_VALIDATED

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

Definition at line 953 of file chan_iax2.c.

◆ CALLNO_ENTRY_TO_PTR

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

Definition at line 951 of file chan_iax2.c.

◆ CALLNO_TO_PTR

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

Definition at line 293 of file chan_iax2.c.

◆ CALLTOKEN_HASH_FORMAT

#define CALLTOKEN_HASH_FORMAT   "%s%u%d" /* address + port + ts + randomcalldata */

◆ CALLTOKEN_IE_FORMAT

#define CALLTOKEN_IE_FORMAT   "%u?%s" /* time + ? + (40 char hash) */

◆ DEBUG_SCHED_MULTITHREAD

#define DEBUG_SCHED_MULTITHREAD

Definition at line 285 of file chan_iax2.c.

◆ DEBUG_SUPPORT

#define DEBUG_SUPPORT

Definition at line 301 of file chan_iax2.c.

◆ DEFAULT_CONTEXT

#define DEFAULT_CONTEXT   "default"

Definition at line 320 of file chan_iax2.c.

◆ DEFAULT_DROP

#define DEFAULT_DROP   3

Definition at line 299 of file chan_iax2.c.

◆ DEFAULT_FREQ_NOTOK

#define DEFAULT_FREQ_NOTOK   10 * 1000 /* How often to check, if the host is down... */

Definition at line 396 of file chan_iax2.c.

◆ DEFAULT_FREQ_OK

#define DEFAULT_FREQ_OK   60 * 1000 /* How often to check for the host to be up */

Definition at line 395 of file chan_iax2.c.

◆ DEFAULT_MAX_THREAD_COUNT

#define DEFAULT_MAX_THREAD_COUNT   100

Definition at line 296 of file chan_iax2.c.

◆ DEFAULT_MAXMS

#define DEFAULT_MAXMS   2000 /* Must be faster than 2 seconds by default */

Definition at line 394 of file chan_iax2.c.

◆ DEFAULT_RETRY_TIME

#define DEFAULT_RETRY_TIME   1000

Definition at line 297 of file chan_iax2.c.

◆ DEFAULT_THREAD_COUNT

#define DEFAULT_THREAD_COUNT   10

Definition at line 295 of file chan_iax2.c.

◆ DEFAULT_TRUNKDATA

#define DEFAULT_TRUNKDATA   640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 710 of file chan_iax2.c.

◆ FORMAT [1/3]

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

◆ FORMAT [2/3]

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

◆ FORMAT [3/3]

#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"

◆ FORMAT2 [1/3]

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

◆ FORMAT2 [2/3]

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

◆ FORMAT2 [3/3]

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

◆ FORMATB

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

◆ GAMMA

#define GAMMA   (0.01)

Definition at line 306 of file chan_iax2.c.

◆ IAX2_TRUNK_PREFACE

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

Definition at line 638 of file chan_iax2.c.

◆ IAX_ALLOWFWDOWNLOAD

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

Allow the FWDOWNL command?

Definition at line 523 of file chan_iax2.c.

◆ IAX_ALREADYGONE

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

Already disconnected

Definition at line 507 of file chan_iax2.c.

◆ IAX_CALLENCRYPTED

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

Definition at line 440 of file chan_iax2.c.

◆ IAX_CAPABILITY_FULLBANDWIDTH

#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF

Definition at line 373 of file chan_iax2.c.

◆ IAX_CAPABILITY_LOWBANDWIDTH

#define IAX_CAPABILITY_LOWBANDWIDTH
Value:
~AST_FORMAT_G726 & \
~AST_FORMAT_G726_AAL2 & \
~AST_FORMAT_ADPCM)
#define IAX_CAPABILITY_MEDBANDWIDTH
Definition: chan_iax2.c:375

Definition at line 385 of file chan_iax2.c.

◆ IAX_CAPABILITY_LOWFREE

#define IAX_CAPABILITY_LOWFREE
Value:
~AST_FORMAT_G723)
#define IAX_CAPABILITY_LOWBANDWIDTH
Definition: chan_iax2.c:385

Definition at line 390 of file chan_iax2.c.

◆ IAX_CAPABILITY_MEDBANDWIDTH

#define IAX_CAPABILITY_MEDBANDWIDTH

Definition at line 375 of file chan_iax2.c.

◆ IAX_CODEC_NOCAP

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

only consider requested format and ignore capabilities

Definition at line 514 of file chan_iax2.c.

◆ IAX_CODEC_NOPREFS

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

Force old behaviour by turning off prefs

Definition at line 513 of file chan_iax2.c.

◆ IAX_CODEC_USER_FIRST

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

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

Definition at line 512 of file chan_iax2.c.

◆ IAX_DEBUGDIGEST

#define IAX_DEBUGDIGEST (   msg,
  key 
)

Definition at line 443 of file chan_iax2.c.

◆ IAX_DELAYPBXSTART

#define IAX_DELAYPBXSTART   (uint64_t)(1LLU << 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 522 of file chan_iax2.c.

◆ IAX_DELME

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

Needs to be deleted

Definition at line 499 of file chan_iax2.c.

◆ IAX_DYNAMIC

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

dynamic peer

Definition at line 504 of file chan_iax2.c.

◆ IAX_ENCRYPTED

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

Whether we should assume encrypted tx/rx

Definition at line 510 of file chan_iax2.c.

◆ IAX_FORCE_ENCRYPT

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

Forces call encryption, if encryption not possible hangup

Definition at line 527 of file chan_iax2.c.

◆ IAX_HASCALLERID

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

CallerID has been specified

Definition at line 498 of file chan_iax2.c.

◆ IAX_IMMEDIATE

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

Allow immediate off-hook to extension s

Definition at line 524 of file chan_iax2.c.

◆ IAX_KEYPOPULATED

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

Whether we have a key populated

Definition at line 511 of file chan_iax2.c.

◆ IAX_MAXAUTHREQ

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

Maximum outstanding AUTHREQ restriction is in place

Definition at line 521 of file chan_iax2.c.

◆ IAX_NOTRANSFER

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

Don't native bridge

Definition at line 502 of file chan_iax2.c.

◆ IAX_PROVISION

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

This is a provisioning request

Definition at line 508 of file chan_iax2.c.

◆ IAX_QUELCH

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

Whether or not we quelch audio

Definition at line 509 of file chan_iax2.c.

◆ IAX_RECVCONNECTEDLINE

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

Allow receiving of connected line updates

Definition at line 526 of file chan_iax2.c.

◆ IAX_RTAUTOCLEAR

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

erase me on expire

Definition at line 517 of file chan_iax2.c.

◆ IAX_RTCACHEFRIENDS

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

let realtime stay till your reload

Definition at line 515 of file chan_iax2.c.

◆ IAX_RTIGNOREREGEXPIRE

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

When using realtime, ignore registration expiration

Definition at line 518 of file chan_iax2.c.

◆ IAX_RTSAVE_SYSNAME

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

Save Systname on Realtime Updates

Definition at line 506 of file chan_iax2.c.

◆ IAX_RTUPDATE

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

Send a realtime update

Definition at line 516 of file chan_iax2.c.

◆ IAX_SENDANI

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

Send ANI along with CallerID

Definition at line 505 of file chan_iax2.c.

◆ IAX_SENDCONNECTEDLINE

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

Allow sending of connected line updates

Definition at line 525 of file chan_iax2.c.

◆ IAX_SHRINKCALLERID

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

Turn on and off caller id shrinking

Definition at line 528 of file chan_iax2.c.

◆ IAX_TEMPONLY

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

Temporary (realtime)

Definition at line 500 of file chan_iax2.c.

◆ IAX_TRANSFERMEDIA

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

When doing IAX2 transfers, transfer media only

Definition at line 520 of file chan_iax2.c.

◆ IAX_TRUNK

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

Treat as a trunk

Definition at line 501 of file chan_iax2.c.

◆ IAX_TRUNKTIMESTAMPS

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

Send trunk timestamps

Definition at line 519 of file chan_iax2.c.

◆ IAX_USEJITTERBUF

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

Use jitter buffer

Definition at line 503 of file chan_iax2.c.

◆ MARK_IAX_SUBCLASS_TX

#define MARK_IAX_SUBCLASS_TX   0x8000

Definition at line 718 of file chan_iax2.c.

◆ MAX_JITTER_BUFFER

#define MAX_JITTER_BUFFER   50

Definition at line 707 of file chan_iax2.c.

◆ MAX_PEER_BUCKETS

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

◆ MAX_RETRY_TIME

#define MAX_RETRY_TIME   10000

Definition at line 705 of file chan_iax2.c.

◆ MAX_TIMESTAMP_SKEW

#define MAX_TIMESTAMP_SKEW   160

maximum difference between actual and predicted ts for sending

Definition at line 712 of file chan_iax2.c.

◆ MAX_TRUNK_MTU

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

◆ MAX_TRUNKDATA

#define MAX_TRUNKDATA   640 * 200

40ms, uncompressed linear * 200 channels

Definition at line 340 of file chan_iax2.c.

◆ MAX_USER_BUCKETS

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

Definition at line 1002 of file chan_iax2.c.

◆ MEMORY_SIZE

#define MEMORY_SIZE   100

Definition at line 298 of file chan_iax2.c.

◆ MIN_JITTER_BUFFER

#define MIN_JITTER_BUFFER   10

Definition at line 708 of file chan_iax2.c.

◆ MIN_RETRY_TIME

#define MIN_RETRY_TIME   100

Definition at line 704 of file chan_iax2.c.

◆ MIN_REUSE_TIME

#define MIN_REUSE_TIME   60 /* Don't reuse a call number within 60 seconds */

Definition at line 303 of file chan_iax2.c.

◆ PEERS_FORMAT

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

Definition at line 6943 of file chan_iax2.c.

◆ PEERS_FORMAT2

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

Definition at line 6942 of file chan_iax2.c.

◆ PTR_TO_CALLNO

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

Definition at line 292 of file chan_iax2.c.

◆ PTR_TO_CALLNO_ENTRY

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

Definition at line 950 of file chan_iax2.c.

◆ SCHED_MULTITHREADED

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

◆ schedule_action

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

Definition at line 1724 of file chan_iax2.c.

◆ TRUNK_CALL_START

#define TRUNK_CALL_START   (IAX_MAX_CALLS / 2)

Definition at line 1222 of file chan_iax2.c.

◆ TS_GAP_FOR_JB_RESYNC

#define TS_GAP_FOR_JB_RESYNC   5000

Definition at line 715 of file chan_iax2.c.

Typedef Documentation

◆ callno_entry

typedef uint16_t callno_entry

Definition at line 740 of file chan_iax2.c.

Enumeration Type Documentation

◆ anonymous enum

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

1049 {
1050 /*! Extension exists */
1051 CACHE_FLAG_EXISTS = (1 << 0),
1052 /*! Extension is nonexistent */
1053 CACHE_FLAG_NONEXISTENT = (1 << 1),
1054 /*! Extension can exist */
1055 CACHE_FLAG_CANEXIST = (1 << 2),
1056 /*! Waiting to hear back response */
1057 CACHE_FLAG_PENDING = (1 << 3),
1058 /*! Timed out */
1059 CACHE_FLAG_TIMEOUT = (1 << 4),
1060 /*! Request transmitted */
1061 CACHE_FLAG_TRANSMITTED = (1 << 5),
1062 /*! Timeout */
1063 CACHE_FLAG_UNKNOWN = (1 << 6),
1064 /*! Matchmore */
1065 CACHE_FLAG_MATCHMORE = (1 << 7),
1066};
@ CACHE_FLAG_TIMEOUT
Definition: chan_iax2.c:1059
@ CACHE_FLAG_EXISTS
Definition: chan_iax2.c:1051
@ CACHE_FLAG_UNKNOWN
Definition: chan_iax2.c:1063
@ CACHE_FLAG_MATCHMORE
Definition: chan_iax2.c:1065
@ CACHE_FLAG_CANEXIST
Definition: chan_iax2.c:1055
@ CACHE_FLAG_PENDING
Definition: chan_iax2.c:1057
@ CACHE_FLAG_NONEXISTENT
Definition: chan_iax2.c:1053
@ CACHE_FLAG_TRANSMITTED
Definition: chan_iax2.c:1061

◆ anonymous enum

anonymous enum
Enumerator
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 2350 of file chan_iax2.c.

2350 {
2351 /* do not allow a new call number, only search ones in use for match */
2352 NEW_PREVENT = 0,
2353 /* search for match first, then allow a new one to be allocated */
2354 NEW_ALLOW = 1,
2355 /* do not search for match, force a new call number */
2356 NEW_FORCE = 2,
2357 /* do not search for match, force a new call number. Signifies call number
2358 * has been calltoken validated */
2360};
@ NEW_PREVENT
Definition: chan_iax2.c:2352
@ NEW_ALLOW
Definition: chan_iax2.c:2354
@ NEW_FORCE
Definition: chan_iax2.c:2356
@ NEW_ALLOW_CALLTOKEN_VALIDATED
Definition: chan_iax2.c:2359

◆ callno_type

Enumerator
CALLNO_TYPE_NORMAL 
CALLNO_TYPE_TRUNK 

Definition at line 945 of file chan_iax2.c.

945 {
948};
@ CALLNO_TYPE_TRUNK
Definition: chan_iax2.c:947
@ CALLNO_TYPE_NORMAL
Definition: chan_iax2.c:946

◆ calltoken_peer_enum

Call token validation settings.

Enumerator
CALLTOKEN_DEFAULT 

Default calltoken required unless the ip is in the ignorelist.

CALLTOKEN_YES 

Require call token validation.

CALLTOKEN_AUTO 

Require call token validation after a successful registration using call token validation occurs.

CALLTOKEN_NO 

Do not require call token validation.

Definition at line 536 of file chan_iax2.c.

536 {
537 /*! \brief Default calltoken required unless the ip is in the ignorelist */
539 /*! \brief Require call token validation. */
540 CALLTOKEN_YES = 1,
541 /*! \brief Require call token validation after a successful registration
542 * using call token validation occurs. */
543 CALLTOKEN_AUTO = 2,
544 /*! \brief Do not require call token validation. */
545 CALLTOKEN_NO = 3,
546};
@ CALLTOKEN_DEFAULT
Default calltoken required unless the ip is in the ignorelist.
Definition: chan_iax2.c:538
@ CALLTOKEN_AUTO
Require call token validation after a successful registration using call token validation occurs.
Definition: chan_iax2.c:543
@ CALLTOKEN_NO
Do not require call token validation.
Definition: chan_iax2.c:545
@ CALLTOKEN_YES
Require call token validation.
Definition: chan_iax2.c:540

◆ iax2_state

enum iax2_state
Enumerator
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 486 of file chan_iax2.c.

486 {
487 IAX_STATE_STARTED = (1 << 0),
488 IAX_STATE_AUTHENTICATED = (1 << 1),
489 IAX_STATE_TBD = (1 << 2),
490};
@ IAX_STATE_TBD
Definition: chan_iax2.c:489
@ IAX_STATE_AUTHENTICATED
Definition: chan_iax2.c:488
@ IAX_STATE_STARTED
Definition: chan_iax2.c:487

◆ iax2_thread_iostate

Enumerator
IAX_IOSTATE_IDLE 
IAX_IOSTATE_READY 
IAX_IOSTATE_PROCESSING 
IAX_IOSTATE_SCHEDREADY 

Definition at line 1090 of file chan_iax2.c.

1090 {
1095};
@ IAX_IOSTATE_PROCESSING
Definition: chan_iax2.c:1093
@ IAX_IOSTATE_SCHEDREADY
Definition: chan_iax2.c:1094
@ IAX_IOSTATE_IDLE
Definition: chan_iax2.c:1091
@ IAX_IOSTATE_READY
Definition: chan_iax2.c:1092

◆ iax2_thread_type

Enumerator
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 1097 of file chan_iax2.c.

1097 {
1100};
@ IAX_THREAD_TYPE_DYNAMIC
Definition: chan_iax2.c:1099
@ IAX_THREAD_TYPE_POOL
Definition: chan_iax2.c:1098

◆ iax_reg_state

Enumerator
REG_STATE_UNREGISTERED 
REG_STATE_REGSENT 
REG_STATE_AUTHSENT 
REG_STATE_REGISTERED 
REG_STATE_REJECTED 
REG_STATE_TIMEOUT 
REG_STATE_NOAUTH 

Definition at line 661 of file chan_iax2.c.

661 {
669};
@ REG_STATE_REGSENT
Definition: chan_iax2.c:663
@ REG_STATE_TIMEOUT
Definition: chan_iax2.c:667
@ REG_STATE_AUTHSENT
Definition: chan_iax2.c:664
@ REG_STATE_NOAUTH
Definition: chan_iax2.c:668
@ REG_STATE_REGISTERED
Definition: chan_iax2.c:665
@ REG_STATE_REJECTED
Definition: chan_iax2.c:666
@ REG_STATE_UNREGISTERED
Definition: chan_iax2.c:662

◆ iax_transfer_state

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

Definition at line 671 of file chan_iax2.c.

671 {
672 TRANSFER_NONE = 0,
683};
@ TRANSFER_MEDIA
Definition: chan_iax2.c:681
@ TRANSFER_NONE
Definition: chan_iax2.c:672
@ TRANSFER_MPASSTHROUGH
Definition: chan_iax2.c:680
@ TRANSFER_MEDIAPASS
Definition: chan_iax2.c:682
@ TRANSFER_PASSTHROUGH
Definition: chan_iax2.c:676
@ TRANSFER_MRELEASED
Definition: chan_iax2.c:679
@ TRANSFER_BEGIN
Definition: chan_iax2.c:673
@ TRANSFER_MREADY
Definition: chan_iax2.c:678
@ TRANSFER_READY
Definition: chan_iax2.c:674
@ TRANSFER_MBEGIN
Definition: chan_iax2.c:677
@ TRANSFER_RELEASED
Definition: chan_iax2.c:675

Function Documentation

◆ __attempt_transmit()

static void __attempt_transmit ( const void *  data)
static

Definition at line 3595 of file chan_iax2.c.

3596{
3597 /* Attempt to transmit the frame to the remote peer...
3598 Called without iaxsl held. */
3599 struct iax_frame *f = (struct iax_frame *)data;
3600 int freeme = 0;
3601 int callno = f->callno;
3602
3603 /* Make sure this call is still active */
3604 if (callno)
3606 if (callno && iaxs[callno]) {
3607 if (f->retries < 0) {
3608 /* Already ACK'd */
3609 freeme = 1;
3610 } else if (f->retries >= max_retries) {
3611 /* Too many attempts. Record an error. */
3612 if (f->transfer) {
3613 /* Transfer timeout */
3615 } else if (f->final) {
3617 } else {
3618 if (iaxs[callno]->owner) {
3619 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %u, subclass = %d, ts=%u, seqno=%d)\n",
3622 f->af.frametype,
3623 f->af.subclass.integer,
3624 f->ts,
3625 f->oseqno);
3626 }
3627 iaxs[callno]->error = ETIMEDOUT;
3628 if (iaxs[callno]->owner) {
3630 /* Hangup the fd */
3631 iax2_queue_frame(callno, &fr); /* XXX */
3632 /* Remember, owner could disappear */
3633 if (iaxs[callno] && iaxs[callno]->owner)
3635 } else {
3636 if (iaxs[callno]->reg) {
3637 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
3638 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
3640 }
3641 iax2_destroy(callno);
3642 }
3643 }
3644 freeme = 1;
3645 } else {
3646 /* Update it if it needs it */
3647 update_packet(f);
3648 /* Attempt transmission */
3649 send_packet(f);
3650 f->retries++;
3651 /* Try again later after 10 times as long */
3652 f->retrytime *= 10;
3653 if (f->retrytime > MAX_RETRY_TIME)
3655 /* Transfer messages max out at one second */
3656 if (f->transfer && (f->retrytime > 1000))
3657 f->retrytime = 1000;
3659 }
3660 } else {
3661 /* Make sure it gets freed */
3662 f->retries = -1;
3663 freeme = 1;
3664 }
3665
3666 if (freeme) {
3667 /* Don't attempt delivery, just remove it from the queue */
3668 AST_LIST_REMOVE(&frame_queue[callno], f, list);
3669 ast_mutex_unlock(&iaxsl[callno]);
3670 f->retrans = -1; /* this is safe because this is the scheduled function */
3671 /* Free the IAX frame */
3672 iax2_frame_free(f);
3673 } else if (callno) {
3674 ast_mutex_unlock(&iaxsl[callno]);
3675 }
3676}
#define ast_log
Definition: astobj2.c:42
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition: causes.h:115
static int update_packet(struct iax_frame *f)
Definition: chan_iax2.c:3568
static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)]
chan_iax2_pvt structure locks
Definition: chan_iax2.c:1211
static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
Definition: chan_iax2.c:7831
static int attempt_transmit(const void *data)
Definition: chan_iax2.c:3678
#define MAX_RETRY_TIME
Definition: chan_iax2.c:705
static void iax2_destroy(int callno)
Definition: chan_iax2.c:3506
static struct @117 frame_queue[IAX_MAX_CALLS]
a list of frames that may need to be retransmitted
static int iax2_sched_add(struct ast_sched_context *sched, int when, ast_sched_cb callback, const void *data)
Definition: chan_iax2.c:1733
static int max_retries
Definition: chan_iax2.c:332
static struct chan_iax2_pvt * iaxs[IAX_MAX_CALLS]
an array of iax2 pvt structures
Definition: chan_iax2.c:1173
static int iax2_queue_frame(int callno, struct ast_frame *f)
Queue a frame to a call's owning asterisk channel.
Definition: chan_iax2.c:3300
static int send_packet(struct iax_frame *f)
Definition: chan_iax2.c:3449
static void iax2_frame_free(struct iax_frame *fr)
Definition: chan_iax2.c:2177
const char * ast_channel_name(const struct ast_channel *chan)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
@ IAX_COMMAND_TXREJ
Definition: iax2.h:93
#define IAX_DEFAULT_REG_EXPIRE
Definition: iax2.h:123
@ AST_FRAME_CONTROL
@ AST_CONTROL_HANGUP
#define LOG_WARNING
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:856
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:286
#define NULL
Definition: resample.c:96
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum ast_frame_type frametype
struct ast_sockaddr addr
Definition: chan_iax2.c:776
struct ast_channel * owner
Definition: chan_iax2.c:808
struct iax2_registry * reg
Definition: chan_iax2.c:882
enum iax_reg_state regstate
Definition: chan_iax2.c:691
struct ast_sockaddr us
Definition: chan_iax2.c:694
unsigned int final
Definition: parser.h:120
int retrans
Definition: parser.h:130
unsigned int ts
Definition: parser.h:110
void * data
Definition: parser.h:104
unsigned short callno
Definition: parser.h:100
int retries
Definition: parser.h:108
int retrytime
Definition: parser.h:112
unsigned int transfer
Definition: parser.h:118
struct ast_frame af
Definition: parser.h:142
int oseqno
Definition: parser.h:126
Definition: sched.c:76

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, iax_frame::data, chan_iax2_pvt::error, 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, iaxs, iaxsl, ast_frame_subclass::integer, LOG_WARNING, max_retries, 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().

◆ __auth_reject()

static void __auth_reject ( const void *  nothing)
static

Definition at line 9424 of file chan_iax2.c.

9425{
9426 /* Called from IAX thread only, without iaxs lock */
9427 int callno = (int)(long)(nothing);
9428 struct iax_ie_data ied;
9429 ast_mutex_lock(&iaxsl[callno]);
9430 if (iaxs[callno]) {
9431 memset(&ied, 0, sizeof(ied));
9432 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
9433 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
9435 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
9436 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
9438 }
9439 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
9440 }
9441 ast_mutex_unlock(&iaxsl[callno]);
9442}
#define AST_CAUSE_FACILITY_NOT_SUBSCRIBED
Definition: causes.h:126
#define AST_CAUSE_FACILITY_REJECTED
Definition: causes.h:117
static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
Definition: chan_iax2.c:7856
@ IAX_COMMAND_REJECT
Definition: iax2.h:57
@ IAX_COMMAND_REGREJ
Definition: iax2.h:71
#define IAX_IE_CAUSE
Definition: iax2.h:152
#define IAX_IE_CAUSECODE
Definition: iax2.h:172
int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigned char dat)
Definition: parser.c:775
int iax_ie_append_str(struct iax_ie_data *ied, unsigned char ie, const char *str)
Definition: parser.c:770

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

Referenced by auth_reject().

◆ __auto_congest()

static void __auto_congest ( const void *  nothing)
static

Definition at line 4782 of file chan_iax2.c.

4783{
4784 int callno = PTR_TO_CALLNO(nothing);
4786 ast_mutex_lock(&iaxsl[callno]);
4787 if (iaxs[callno]) {
4788 iaxs[callno]->initid = -1;
4789 iax2_queue_frame(callno, &f);
4790 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
4791 }
4792 ast_mutex_unlock(&iaxsl[callno]);
4793}
#define PTR_TO_CALLNO(a)
Definition: chan_iax2.c:292
@ AST_CONTROL_CONGESTION
#define LOG_NOTICE

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

Referenced by auto_congest().

◆ __auto_hangup()

static void __auto_hangup ( const void *  nothing)
static

Definition at line 9473 of file chan_iax2.c.

9474{
9475 /* Called from IAX thread only, without iaxs lock */
9476 int callno = (int)(long)(nothing);
9477 struct iax_ie_data ied;
9478 ast_mutex_lock(&iaxsl[callno]);
9479 if (iaxs[callno]) {
9480 memset(&ied, 0, sizeof(ied));
9481 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
9483 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
9484 }
9485 ast_mutex_unlock(&iaxsl[callno]);
9486}
#define AST_CAUSE_NO_USER_RESPONSE
Definition: causes.h:108
@ IAX_COMMAND_HANGUP
Definition: iax2.h:56

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

Referenced by auto_hangup().

◆ __do_deliver()

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

3388{
3389 /* Just deliver the packet by using queueing. This is called by
3390 the IAX thread with the iaxsl lock held. */
3391 struct iax_frame *fr = data;
3392 fr->retrans = -1;
3395 iax2_queue_frame(fr->callno, &fr->af);
3396 /* Free our iax frame */
3397 iax2_frame_free(fr);
3398 /* And don't run again */
3399 return 0;
3400}
#define IAX_ALREADYGONE
Definition: chan_iax2.c:507
@ AST_FRFLAG_HAS_TIMING_INFO
#define ast_test_flag64(p, flag)
Definition: utils.h:120
#define ast_clear_flag(p, flag)
Definition: utils.h:77

References iax_frame::af, ast_clear_flag, AST_FRFLAG_HAS_TIMING_INFO, ast_test_flag64, iax_frame::callno, iax_frame::data, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.

Referenced by __get_from_jb(), and schedule_delivery().

◆ __expire_registry()

static void __expire_registry ( const void *  data)
static

Definition at line 9040 of file chan_iax2.c.

9041{
9042 struct iax2_peer *peer = (struct iax2_peer *) data;
9043 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
9044
9045 if (!peer)
9046 return;
9047 if (peer->expire == -1) {
9048 /* Removed already (possibly through CLI), ignore */
9049 return;
9050 }
9051
9052 peer->expire = -1;
9053
9054 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
9056 realtime_update_peer(peer->name, &peer->addr, 0);
9058 blob = ast_json_pack("{s: s, s: s}",
9059 "peer_status", "Unregistered",
9060 "cause", "Expired");
9062 /* modify entry in peercnts table as _not_ registered */
9063 peercnt_modify((unsigned char) 0, 0, &peer->addr);
9064 /* Reset the address */
9065 ast_sockaddr_setnull(&peer->addr);
9066 /* Reset expiry value */
9067 peer->expiry = min_reg_expire;
9068 if (!ast_test_flag64(peer, IAX_TEMPONLY))
9069 ast_db_del("IAX/Registry", peer->name);
9070 register_peer_exten(peer, 0);
9071 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
9072 if (iax2_regfunk)
9073 iax2_regfunk(peer->name, 0);
9074
9076 unlink_peer(peer);
9077
9078 peer_unref(peer);
9079}
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Definition: main/db.c:476
static void peercnt_modify(unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
Definition: chan_iax2.c:2650
static int min_reg_expire
Definition: chan_iax2.c:359
static void register_peer_exten(struct iax2_peer *peer, int onoff)
Definition: chan_iax2.c:9002
#define IAX_RTUPDATE
Definition: chan_iax2.c:516
static int(* iax2_regfunk)(const char *username, int onoff)
Definition: chan_iax2.c:370
#define IAX_RTCACHEFRIENDS
Definition: chan_iax2.c:515
static void unlink_peer(struct iax2_peer *peer)
Definition: chan_iax2.c:9021
static struct iax2_peer * peer_unref(struct iax2_peer *peer)
Definition: chan_iax2.c:2075
static struct ast_flags64 globalflags
Definition: chan_iax2.c:482
static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
Definition: chan_iax2.c:4624
#define IAX_RTAUTOCLEAR
Definition: chan_iax2.c:517
#define IAX_TEMPONLY
Definition: chan_iax2.c:500
@ AST_DEVSTATE_CACHABLE
Definition: devicestate.h:70
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
@ AST_DEVICE_UNAVAILABLE
Definition: devicestate.h:58
@ AST_ENDPOINT_OFFLINE
Definition: endpoints.h:55
void ast_endpoint_set_state(struct ast_endpoint *endpoint, enum ast_endpoint_state state)
Updates the state of the given endpoint.
void ast_endpoint_blob_publish(struct ast_endpoint *endpoint, struct stasis_message_type *type, struct ast_json *blob)
Creates and publishes a ast_endpoint_blob message.
struct stasis_message_type * ast_endpoint_state_type(void)
Message type for endpoint state changes.
#define ast_debug(level,...)
Log a DEBUG message.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:138
Abstract JSON element (object, array, string, int, ...).
struct ast_sockaddr addr
Definition: chan_iax2.c:602
int expire
Definition: chan_iax2.c:614
struct ast_endpoint * endpoint
Definition: chan_iax2.c:635
int expiry
Definition: chan_iax2.c:615
const ast_string_field name
Definition: chan_iax2.c:599
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

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, globalflags, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, min_reg_expire, iax2_peer::name, NULL, peer_unref(), peercnt_modify(), RAII_VAR, realtime_update_peer(), register_peer_exten(), and unlink_peer().

Referenced by expire_registry().

◆ __find_callno()

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
Note
Calling this function while holding another pvt lock can cause a deadlock.

Definition at line 3155 of file chan_iax2.c.

3156{
3157 int res = 0;
3158 int x;
3159 /* this call is calltoken validated as long as it is either NEW_FORCE
3160 * or NEW_ALLOW_CALLTOKEN_VALIDATED */
3161 int validated = (new > NEW_ALLOW) ? 1 : 0;
3162 char host[80];
3163
3164 if (new <= NEW_ALLOW) {
3165 if (callno) {
3166 struct chan_iax2_pvt *pvt;
3167 struct chan_iax2_pvt tmp_pvt = {
3168 .callno = dcallno,
3169 .peercallno = callno,
3170 .transfercallno = callno,
3171 /* hack!! */
3172 .frames_received = check_dcallno,
3173 };
3174
3175 ast_sockaddr_copy(&tmp_pvt.addr, addr);
3176 /* this works for finding normal call numbers not involving transfering */
3177 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
3178 if (return_locked) {
3179 ast_mutex_lock(&iaxsl[pvt->callno]);
3180 }
3181 res = pvt->callno;
3182 ao2_ref(pvt, -1);
3183 pvt = NULL;
3184 return res;
3185 }
3186 /* this searches for transfer call numbers that might not get caught otherwise */
3187 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
3188 ast_sockaddr_copy(&tmp_pvt.transfer, addr);
3189 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
3190 if (return_locked) {
3191 ast_mutex_lock(&iaxsl[pvt->callno]);
3192 }
3193 res = pvt->callno;
3194 ao2_ref(pvt, -1);
3195 pvt = NULL;
3196 return res;
3197 }
3198 }
3199 /* This will occur on the first response to a message that we initiated,
3200 * such as a PING. */
3201 if (dcallno) {
3202 ast_mutex_lock(&iaxsl[dcallno]);
3203 }
3204 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(addr, callno, dcallno, iaxs[dcallno], check_dcallno)) {
3205 iaxs[dcallno]->peercallno = callno;
3206 res = dcallno;
3207 store_by_peercallno(iaxs[dcallno]);
3208 if (!res || !return_locked) {
3209 ast_mutex_unlock(&iaxsl[dcallno]);
3210 }
3211 return res;
3212 }
3213 if (dcallno) {
3214 ast_mutex_unlock(&iaxsl[dcallno]);
3215 }
3216 }
3217 if (!res && (new >= NEW_ALLOW)) {
3219
3220 /* It may seem odd that we look through the peer list for a name for
3221 * this *incoming* call. Well, it is weird. However, users don't
3222 * have an IP address/port number that we can match against. So,
3223 * this is just checking for a peer that has that IP/port and
3224 * assuming that we have a user of the same name. This isn't always
3225 * correct, but it will be changed if needed after authentication. */
3226 if (!iax2_getpeername(*addr, host, sizeof(host)))
3227 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(addr));
3228
3229 if (peercnt_add(addr)) {
3230 /* This address has hit its callnumber limit. When the limit
3231 * is reached, the connection is not added to the peercnts table.*/
3232 return 0;
3233 }
3234
3235 if (get_unused_callno(CALLNO_TYPE_NORMAL, validated, &entry)) {
3236 /* since we ran out of space, remove the peercnt
3237 * entry we added earlier */
3239 ast_log(LOG_WARNING, "No more space\n");
3240 return 0;
3241 }
3243 ast_mutex_lock(&iaxsl[x]);
3244
3245 iaxs[x] = new_iax(addr, host);
3246 if (iaxs[x]) {
3247 if (iaxdebug)
3248 ast_debug(1, "Creating new call structure %d\n", x);
3249 iaxs[x]->callno_entry = entry;
3250 iaxs[x]->sockfd = sockfd;
3252 iaxs[x]->peercallno = callno;
3253 iaxs[x]->callno = x;
3256 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
3257 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
3258 iaxs[x]->amaflags = amaflags;
3264
3265 if (iaxs[x]->peercallno) {
3267 }
3268 } else {
3269 ast_log(LOG_WARNING, "Out of resources\n");
3272 return 0;
3273 }
3274 if (!return_locked)
3276 res = x;
3277 }
3278 return res;
3279}
#define OBJ_POINTER
Definition: astobj2.h:1150
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static int send_ping(const void *data)
Definition: chan_iax2.c:1787
static int replace_callno(const void *obj)
Definition: chan_iax2.c:3029
static struct chan_iax2_pvt * new_iax(struct ast_sockaddr *addr, const char *host)
Definition: chan_iax2.c:2290
static char default_parkinglot[AST_MAX_CONTEXT]
Definition: chan_iax2.c:322
static int ping_time
Definition: chan_iax2.c:333
#define IAX_NOTRANSFER
Definition: chan_iax2.c:502
static int iax2_getpeername(struct ast_sockaddr addr, char *host, int len)
Definition: chan_iax2.c:2092
#define CALLNO_ENTRY_GET_CALLNO(a)
Definition: chan_iax2.c:955
static struct ao2_container * iax_transfercallno_pvts
Another container of iax2_pvt structures.
Definition: chan_iax2.c:1218
#define IAX_RECVCONNECTEDLINE
Definition: chan_iax2.c:526
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2362
#define IAX_FORCE_ENCRYPT
Definition: chan_iax2.c:527
#define IAX_SENDCONNECTEDLINE
Definition: chan_iax2.c:525
static int get_unused_callno(enum callno_type type, int validated, callno_entry *entry)
Definition: chan_iax2.c:2952
static int send_lagrq(const void *data)
Definition: chan_iax2.c:1851
static int peercnt_add(struct ast_sockaddr *addr)
Definition: chan_iax2.c:2678
#define DEFAULT_RETRY_TIME
Definition: chan_iax2.c:297
static int lagrq_time
Definition: chan_iax2.c:334
static void store_by_peercallno(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:2465
static int peercnt_remove_by_addr(struct ast_sockaddr *addr)
Definition: chan_iax2.c:2769
#define CALLNO_ENTRY_TO_PTR(a)
Definition: chan_iax2.c:951
#define IAX_USEJITTERBUF
Definition: chan_iax2.c:503
#define IAX_TRANSFERMEDIA
Definition: chan_iax2.c:520
static int iaxdebug
Definition: chan_iax2.c:461
uint16_t callno_entry
Definition: chan_iax2.c:740
static int amaflags
Definition: chan_iax2.c:476
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:473
static char mohsuggest[MAX_MUSICCLASS]
Definition: chan_iax2.c:475
static char mohinterpret[MAX_MUSICCLASS]
Definition: chan_iax2.c:474
static struct ao2_container * iax_peercallno_pvts
Another container of iax2_pvt structures.
Definition: chan_iax2.c:1202
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
unsigned int pingtime
Definition: chan_iax2.c:772
struct ast_sockaddr transfer
Definition: chan_iax2.c:894
unsigned short peercallno
Definition: chan_iax2.c:786
unsigned short callno
Definition: chan_iax2.c:782
const ast_string_field parkinglot
Definition: chan_iax2.c:861
const ast_string_field host
Definition: chan_iax2.c:861
callno_entry callno_entry
Definition: chan_iax2.c:784
Definition: search.h:40
#define ast_copy_flags64(dest, src, flagz)
Definition: utils.h:141

References accountcode, chan_iax2_pvt::addr, amaflags, 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_parkinglot, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), globalflags, chan_iax2_pvt::host, iax2_getpeername(), iax2_sched_add(), IAX_FORCE_ENCRYPT, IAX_NOTRANSFER, iax_peercallno_pvts, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, iax_transfercallno_pvts, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxdebug, iaxs, iaxsl, chan_iax2_pvt::lagid, lagrq_time, LOG_WARNING, match(), min_reg_expire, mohinterpret, mohsuggest, NEW_ALLOW, new_iax(), NULL, OBJ_POINTER, chan_iax2_pvt::parkinglot, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), ping_time, 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().

◆ __get_from_jb()

static void __get_from_jb ( const void *  p)
static

Definition at line 4172 of file chan_iax2.c.

4173{
4174 int callno = PTR_TO_CALLNO(p);
4175 struct chan_iax2_pvt *pvt = NULL;
4176 struct iax_frame *fr;
4177 jb_frame frame;
4178 int ret;
4179 long ms;
4180 long next;
4181 struct timeval now = ast_tvnow();
4182 struct ast_format *voicefmt;
4183
4184 /* Make sure we have a valid private structure before going on */
4185 ast_mutex_lock(&iaxsl[callno]);
4186 pvt = iaxs[callno];
4187 if (!pvt) {
4188 /* No go! */
4189 ast_mutex_unlock(&iaxsl[callno]);
4190 return;
4191 }
4192
4193 pvt->jbid = -1;
4194
4195 /* round up a millisecond since ast_sched_runq does; */
4196 /* prevents us from spinning while waiting for our now */
4197 /* to catch up with runq's now */
4198 now.tv_usec += 1000;
4199
4200 ms = ast_tvdiff_ms(now, pvt->rxcore);
4201 if (ms >= (next = jb_next(pvt->jb))) {
4203 if (!voicefmt) {
4204 /* pvt->voiceformat won't be set if we haven't received any voice frames yet.
4205 * In this case, fall back to using the format negotiated during call setup,
4206 * so we don't stall the jitterbuffer completely. */
4208 }
4209 if (!voicefmt) {
4210 /* Really shouldn't happen, but if it does, should be looked into */
4211 ast_log(LOG_WARNING, "No voice format and no peer format available on %s, backlogging frame\n", ast_channel_name(pvt->owner));
4212 goto cleanup; /* Don't crash if there's no voice format */
4213 }
4214 ret = jb_get(pvt->jb, &frame, ms, ast_format_get_default_ms(voicefmt));
4215 switch(ret) {
4216 case JB_OK:
4217 fr = frame.data;
4218 __do_deliver(fr);
4219 /* __do_deliver() can cause the call to disappear */
4220 pvt = iaxs[callno];
4221 break;
4222 case JB_INTERP:
4223 {
4224 struct ast_frame af = { 0, };
4225
4226 /* create an interpolation frame */
4228 af.subclass.format = voicefmt;
4229 af.samples = frame.ms * (ast_format_get_sample_rate(voicefmt) / 1000);
4230 af.src = "IAX2 JB interpolation";
4231 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
4233
4234 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
4235 * which we'd need to malloc, and then it would free it. That seems like a drag */
4236 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
4237 iax2_queue_frame(callno, &af);
4238 /* iax2_queue_frame() could cause the call to disappear */
4239 pvt = iaxs[callno];
4240 }
4241 }
4242 break;
4243 case JB_DROP:
4244 iax2_frame_free(frame.data);
4245 break;
4246 case JB_NOFRAME:
4247 case JB_EMPTY:
4248 /* do nothing */
4249 break;
4250 default:
4251 /* shouldn't happen */
4252 break;
4253 }
4254 }
4255cleanup:
4256 if (pvt)
4257 update_jbsched(pvt);
4258 ast_mutex_unlock(&iaxsl[callno]);
4259}
static int __do_deliver(void *data)
Definition: chan_iax2.c:3387
static void update_jbsched(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:4155
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
unsigned int ast_format_get_default_ms(const struct ast_format *format)
Get the default framing size (in milliseconds) for a format.
Definition: format.c:359
struct ast_format * ast_format_compatibility_bitfield2format(uint64_t bitfield)
Convert a bitfield to its respective format structure.
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
@ AST_FRAME_VOICE
enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frame, long now, long interpl)
get a frame for time now (receiver's time) return value is one of JB_OK: You've got frame!...
Definition: jitterbuf.c:785
long jb_next(jitterbuf *jb)
when is the next frame due out, in receiver's time (0=EMPTY) This value may change as frames are adde...
Definition: jitterbuf.c:767
@ JB_EMPTY
Definition: jitterbuf.h:52
@ JB_DROP
Definition: jitterbuf.h:55
@ JB_NOFRAME
Definition: jitterbuf.h:53
@ JB_INTERP
Definition: jitterbuf.h:54
@ JB_OK
Definition: jitterbuf.h:51
static void * cleanup(void *unused)
Definition: pbx_realtime.c:124
Definition of a media format.
Definition: format.c:43
struct ast_format * format
struct timeval delivery
struct ast_frame * next
const char * src
struct timeval rxcore
Definition: chan_iax2.c:798
iax2_format voiceformat
Definition: chan_iax2.c:748
iax2_format peerformat
Definition: chan_iax2.c:792
jitterbuf * jb
Definition: chan_iax2.c:800
struct iax_frame * next
Definition: parser.h:140
long ms
Definition: jitterbuf.h:104
void * data
Definition: jitterbuf.h:102
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:282
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References __do_deliver(), ast_channel_name(), ast_format_compatibility_bitfield2format(), ast_format_get_default_ms(), ast_format_get_sample_rate(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_test_flag64, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), cleanup(), jb_frame::data, ast_frame::delivery, ast_frame_subclass::format, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, LOG_WARNING, jb_frame::ms, iax_frame::next, ast_frame::next, NULL, ast_frame::offset, chan_iax2_pvt::owner, chan_iax2_pvt::peerformat, 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().

◆ __iax2_do_register_s()

static void __iax2_do_register_s ( const void *  data)
static

Definition at line 8683 of file chan_iax2.c.

8684{
8685 struct iax2_registry *reg = (struct iax2_registry *)data;
8686
8687 if (ast_sockaddr_isnull(&reg->addr)) {
8688 reg->addr.ss.ss_family = AST_AF_UNSPEC;
8689 ast_dnsmgr_lookup(reg->hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL);
8690 if (!ast_sockaddr_port(&reg->addr)) {
8691 ast_sockaddr_set_port(&reg->addr, reg->port);
8692 } else {
8693 reg->port = ast_sockaddr_port(&reg->addr);
8694 }
8695 }
8696
8697 reg->expire = -1;
8698 iax2_do_register(reg);
8699}
static int iax2_do_register(struct iax2_registry *reg)
Definition: chan_iax2.c:12304
static int srvlookup
Definition: chan_iax2.c:362
int ast_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service)
Allocate and initialize a DNS manager entry.
Definition: dnsmgr.c:191
@ AST_AF_UNSPEC
Definition: netsock2.h:54
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized,...
Definition: netsock2.h:127
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
struct sockaddr_storage ss
Definition: netsock2.h:98
struct ast_sockaddr addr
Definition: chan_iax2.c:686
struct ast_dnsmgr_entry * dnsmgr
Definition: chan_iax2.c:695
char hostname[]
Definition: chan_iax2.c:698

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, srvlookup, and ast_sockaddr::ss.

Referenced by iax2_do_register_s().

◆ __iax2_poke_noanswer()

static void __iax2_poke_noanswer ( const void *  data)
static

Definition at line 12485 of file chan_iax2.c.

12486{
12487 struct iax2_peer *peer = (struct iax2_peer *)data;
12488 int callno;
12489
12490 if (peer->lastms > -1) {
12491 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
12492
12493 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
12495 blob = ast_json_pack("{s: s, s: i}",
12496 "peer_status", "Unreachable",
12497 "time", peer->lastms);
12499 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
12500 }
12501 if ((callno = peer->callno) > 0) {
12505 }
12506 peer->callno = 0;
12507 peer->lastms = -1;
12508 /* Try again quickly */
12510 if (peer->pokeexpire == -1)
12511 peer_unref(peer);
12512}
static int iax2_poke_peer_s(const void *data)
Definition: chan_iax2.c:9540
static struct iax2_peer * peer_ref(struct iax2_peer *peer)
Definition: chan_iax2.c:2069
int callno
Definition: chan_iax2.c:619
int pokefreqnotok
Definition: chan_iax2.c:625
int lastms
Definition: chan_iax2.c:621
int pokeexpire
Definition: chan_iax2.c:620

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

◆ __iax2_poke_peer_s()

static void __iax2_poke_peer_s ( const void *  data)
static

Definition at line 9533 of file chan_iax2.c.

9534{
9535 struct iax2_peer *peer = (struct iax2_peer *)data;
9536 iax2_poke_peer(peer, 0);
9537 peer_unref(peer);
9538}
static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
Definition: chan_iax2.c:12535

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

◆ __iax2_show_peers()

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

Definition at line 7046 of file chan_iax2.c.

7047{
7048 struct show_peers_context cont = {
7049 .havepattern = 0,
7050 .idtext = "",
7051 .registeredonly = 0,
7052
7053 .peerlist = 0,
7054
7055 .total_peers = 0,
7056 .online_peers = 0,
7057 .offline_peers = 0,
7058 .unmonitored_peers = 0,
7059 };
7060
7061 struct ao2_iterator i;
7062
7063 struct iax2_peer *peer = NULL;
7064
7065 switch (argc) {
7066 case 6:
7067 if (!strcasecmp(argv[3], "registered"))
7068 cont.registeredonly = 1;
7069 else
7070 return RESULT_SHOWUSAGE;
7071 if (!strcasecmp(argv[4], "like")) {
7072 if (regcomp(&cont.regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
7073 return RESULT_SHOWUSAGE;
7074 cont.havepattern = 1;
7075 } else
7076 return RESULT_SHOWUSAGE;
7077 break;
7078 case 5:
7079 if (!strcasecmp(argv[3], "like")) {
7080 if (regcomp(&cont.regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
7081 return RESULT_SHOWUSAGE;
7082 cont.havepattern = 1;
7083 } else
7084 return RESULT_SHOWUSAGE;
7085 break;
7086 case 4:
7087 if (!strcasecmp(argv[3], "registered")) {
7088 cont.registeredonly = 1;
7089 } else {
7090 return RESULT_SHOWUSAGE;
7091 }
7092 break;
7093 case 3:
7094 break;
7095 default:
7096 return RESULT_SHOWUSAGE;
7097 }
7098
7099
7100 if (!s) {
7101 ast_cli(fd, PEERS_FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", "Description");
7102 }
7103
7104 i = ao2_iterator_init(peers, 0);
7105 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
7106
7107 if (cont.registeredonly && ast_sockaddr_isnull(&peer->addr)) {
7108 continue;
7109 }
7110 if (cont.havepattern && regexec(&cont.regexbuf, peer->name, 0, NULL, 0)) {
7111 continue;
7112 }
7113
7114 _iax2_show_peers_one(fd, s, &cont, peer);
7115
7116 }
7118
7119 if (!s) {
7120 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
7122 }
7123
7124 if (cont.havepattern) {
7125 regfree(&cont.regexbuf);
7126 }
7127
7128 if (total) {
7129 *total = cont.total_peers;
7130 }
7131
7132 return RESULT_SUCCESS;
7133
7134}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define PEERS_FORMAT2
Definition: chan_iax2.c:6942
static void _iax2_show_peers_one(int fd, struct mansession *s, struct show_peers_context *cont, struct iax2_peer *peer)
Definition: chan_iax2.c:6945
#define RESULT_SHOWUSAGE
Definition: cli.h:41
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define RESULT_SUCCESS
Definition: cli.h:40
static int total
Definition: res_adsi.c:970
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821

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, total, show_peers_context::total_peers, and show_peers_context::unmonitored_peers.

Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 15136 of file chan_iax2.c.

◆ __schedule_action()

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

Definition at line 1699 of file chan_iax2.c.

1700{
1701 struct iax2_thread *thread;
1702 static time_t lasterror;
1703 time_t t;
1704
1706 if (thread != NULL) {
1707 thread->schedfunc = func;
1708 thread->scheddata = data;
1709 thread->iostate = IAX_IOSTATE_SCHEDREADY;
1710#ifdef DEBUG_SCHED_MULTITHREAD
1711 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
1712#endif
1713 signal_condition(&thread->lock, &thread->cond);
1714 return 0;
1715 }
1716 time(&t);
1717 if (t != lasterror) {
1718 lasterror = t;
1719 ast_debug(1, "Out of idle IAX2 threads for scheduling! (%s)\n", funcname);
1720 }
1721
1722 return -1;
1723}
pthread_t thread
Definition: app_sla.c:329
static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
Definition: chan_iax2.c:1158
static struct iax2_thread * find_idle_thread(void)
Definition: chan_iax2.c:1632
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425

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

◆ __send_command()

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

7814{
7815 struct ast_frame f = { 0, };
7816 int res = 0;
7817
7818 f.frametype = type;
7819 f.subclass.integer = command;
7820 f.datalen = datalen;
7821 f.src = __FUNCTION__;
7822 f.data.ptr = (void *) data;
7823
7824 if ((res = queue_signalling(i, &f)) <= 0) {
7825 return res;
7826 }
7827
7828 return iax2_send(i, &f, ts, seqno, now, transfer, final);
7829}
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 ca...
Definition: chan_iax2.c:2218
static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
Definition: chan_iax2.c:6643
static const char type[]
Definition: chan_ooh323.c:109
static int transfer(void *data)
Definition: chan_pjsip.c:2129
union ast_frame::@226 data

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

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

◆ __send_lagrq()

static void __send_lagrq ( const void *  data)
static

Definition at line 1827 of file chan_iax2.c.

1828{
1829 int callno = PTR_TO_CALLNO(data);
1830
1831 if (iax2_lock_callno_unless_destroyed(callno) == 0) {
1832 ast_debug(3, "Hangup initiated on call %d, aborting __send_lagrq\n", callno);
1833 return;
1834 }
1835
1836 /* Mark lagid as invalid scheduler id. */
1837 iaxs[callno]->lagid = -1;
1838
1839 /* callno is now locked. */
1840 if (iaxs[callno]->peercallno) {
1841 /* Send LAGRQ packet. */
1843
1844 /* Schedule sending next lagrq. */
1845 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
1846 }
1847
1848 ast_mutex_unlock(&iaxsl[callno]);
1849}
static int iax2_lock_callno_unless_destroyed(int callno)
Acquire the iaxsl[callno] if call exists and not having ongoing hangup.
Definition: chan_iax2.c:1745
@ IAX_COMMAND_LAGRQ
Definition: iax2.h:62

References ast_debug, AST_FRAME_IAX, ast_mutex_unlock, iax2_thread::callno, iax2_lock_callno_unless_destroyed(), iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, lagrq_time, NULL, PTR_TO_CALLNO, send_command(), and send_lagrq().

Referenced by send_lagrq().

◆ __send_ping()

static void __send_ping ( const void *  data)
static

Definition at line 1763 of file chan_iax2.c.

1764{
1765 int callno = PTR_TO_CALLNO(data);
1766
1767 if (iax2_lock_callno_unless_destroyed(callno) == 0) {
1768 ast_debug(3, "Hangup initiated on call %d, aborting __send_ping\n", callno);
1769 return;
1770 }
1771
1772 /* Mark pingid as invalid scheduler id. */
1773 iaxs[callno]->pingid = -1;
1774
1775 /* callno is now locked. */
1776 if (iaxs[callno]->peercallno) {
1777 /* Send PING packet. */
1778 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
1779
1780 /* Schedule sending next ping. */
1781 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
1782 }
1783
1784 ast_mutex_unlock(&iaxsl[callno]);
1785}
@ IAX_COMMAND_PING
Definition: iax2.h:53

References ast_debug, AST_FRAME_IAX, ast_mutex_unlock, iax2_thread::callno, iax2_lock_callno_unless_destroyed(), iax2_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, NULL, ping_time, chan_iax2_pvt::pingid, PTR_TO_CALLNO, send_command(), and send_ping().

Referenced by send_ping().

◆ __unload_module()

static int __unload_module ( void  )
static

Definition at line 14763 of file chan_iax2.c.

14764{
14765 int x;
14766
14769
14770 ast_manager_unregister("IAXpeers");
14771 ast_manager_unregister("IAXpeerlist");
14772 ast_manager_unregister("IAXnetstats");
14773 ast_manager_unregister("IAXregistry");
14778
14780 pthread_cancel(netthreadid);
14781 pthread_kill(netthreadid, SIGURG);
14782 pthread_join(netthreadid, NULL);
14783 }
14784
14785 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14786 if (iaxs[x]) {
14787 iax2_destroy(x);
14788 }
14789 }
14790
14791 /* Call for all threads to halt */
14795
14798 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14799 if (iaxs[x]) {
14800 iax2_destroy(x);
14801 }
14802 }
14803 ast_manager_unregister( "IAXpeers" );
14804 ast_manager_unregister( "IAXpeerlist" );
14805 ast_manager_unregister( "IAXnetstats" );
14806 ast_manager_unregister( "IAXregistry" );
14811 delete_users();
14814
14815 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14817 }
14818
14819 ao2_ref(peers, -1);
14820 ao2_ref(users, -1);
14825 if (timer) {
14827 timer = NULL;
14828 }
14830
14833 sched = NULL;
14834 ao2_ref(peercnts, -1);
14835
14837 ast_unload_realtime("iaxpeers");
14838
14841 return 0;
14842}
static struct ao2_container * peercnts
Definition: chan_iax2.c:1006
static struct ast_channel_tech iax2_tech
Definition: chan_iax2.c:1341
static int peercnt_remove_cb(const void *obj)
Definition: chan_iax2.c:2755
static char regcontext[AST_MAX_CONTEXT]
Definition: chan_iax2.c:325
static struct ao2_container * callno_limits
Definition: chan_iax2.c:1009
static struct ast_netsock_list * netsock
Definition: chan_iax2.c:366
static struct ast_netsock_list * outsock
Definition: chan_iax2.c:367
static void acl_change_stasis_unsubscribe(void)
Definition: chan_iax2.c:1526
static struct ast_switch iax2_switch
Definition: chan_iax2.c:14705
static char * papp
Definition: chan_iax2.c:12412
static struct ast_taskprocessor * transmit_processor
Definition: chan_iax2.c:982
static struct ast_timer * timer
Definition: chan_iax2.c:364
static pthread_t netthreadid
Definition: chan_iax2.c:484
static void network_change_stasis_unsubscribe(void)
Definition: chan_iax2.c:1511
static struct ao2_container * calltoken_ignores
Definition: chan_iax2.c:1012
static void delete_users(void)
Definition: chan_iax2.c:13569
static void cleanup_thread_list(void *head)
Definition: chan_iax2.c:14743
static struct ast_cli_entry cli_iax2[]
Definition: chan_iax2.c:14715
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
void iax_firmware_unload(void)
Definition: firmware.c:250
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8041
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
Definition: main/config.c:3576
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_mutex_destroy(a)
Definition: lock.h:188
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_netsock_release(struct ast_netsock_list *list)
Definition: netsock.c:85
int ast_context_destroy_by_name(const char *context, const char *registrar)
Destroy a context by name.
Definition: pbx.c:8205
void ast_unregister_switch(struct ast_switch *sw)
Unregister an alternative switch.
Definition: pbx_switch.c:76
int iax_provision_unload(void)
Definition: provision.c:517
void ast_sched_clean_by_callback(struct ast_sched_context *con, ast_sched_cb match, ast_sched_cb cleanup_cb)
Clean all scheduled events with matching callback.
Definition: sched.c:409
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:271
struct ast_format_cap * capabilities
Definition: channel.h:632
list of users found in the config file
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
Definition: timing.c:154
#define ARRAY_LEN(a)
Definition: utils.h:666

References acl_change_stasis_unsubscribe(), ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy_by_name(), 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_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), callno_limits, calltoken_ignores, ast_channel_tech::capabilities, cleanup_thread_list(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, iax_firmware_unload(), iax_peercallno_pvts, iax_provision_unload(), iax_transfercallno_pvts, iaxs, iaxsl, netsock, netthreadid, network_change_stasis_unsubscribe(), NULL, outsock, papp, peercnt_remove_cb(), peercnts, regcontext, timer, and transmit_processor.

Referenced by load_module(), and unload_module().

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 15136 of file chan_iax2.c.

◆ _iax2_show_peers_one()

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

Definition at line 6945 of file chan_iax2.c.

6946{
6947 char name[256] = "";
6948 char status[64];
6949 int retstatus;
6950 struct ast_str *encmethods = ast_str_alloca(256);
6951
6952 char *tmp_host, *tmp_mask, *tmp_port;
6953
6954 tmp_host = ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr));
6955 tmp_mask = ast_strdupa(ast_sockaddr_stringify_addr(&peer->mask));
6956 tmp_port = ast_strdupa(ast_sockaddr_stringify_port(&peer->addr));
6957
6958 if (!ast_strlen_zero(peer->username)) {
6959 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
6960 } else {
6961 ast_copy_string(name, peer->name, sizeof(name));
6962 }
6963
6964 encmethods_to_str(peer->encmethods, &encmethods);
6965 retstatus = peer_status(peer, status, sizeof(status));
6966 if (retstatus > 0) {
6967 cont->online_peers++;
6968 } else if (!retstatus) {
6969 cont->offline_peers++;
6970 } else {
6971 cont->unmonitored_peers++;
6972 }
6973
6974 if (s) {
6975 if (cont->peerlist) { /* IAXpeerlist */
6976 astman_append(s,
6977 "Event: PeerEntry\r\n%s"
6978 "Channeltype: IAX\r\n",
6979 cont->idtext);
6980 if (!ast_strlen_zero(peer->username)) {
6981 astman_append(s,
6982 "ObjectName: %s\r\n"
6983 "ObjectUsername: %s\r\n",
6984 peer->name,
6985 peer->username);
6986 } else {
6987 astman_append(s,
6988 "ObjectName: %s\r\n",
6989 name);
6990 }
6991 } else { /* IAXpeers */
6992 astman_append(s,
6993 "Event: PeerEntry\r\n%s"
6994 "Channeltype: IAX2\r\n"
6995 "ObjectName: %s\r\n",
6996 cont->idtext,
6997 name);
6998 }
6999 astman_append(s,
7000 "ChanObjectType: peer\r\n"
7001 "IPaddress: %s\r\n",
7002 tmp_host);
7003 if (cont->peerlist) { /* IAXpeerlist */
7004 astman_append(s,
7005 "Mask: %s\r\n"
7006 "Port: %s\r\n",
7007 tmp_mask,
7008 tmp_port);
7009 } else { /* IAXpeers */
7010 astman_append(s,
7011 "IPport: %s\r\n",
7012 tmp_port);
7013 }
7014 astman_append(s,
7015 "Dynamic: %s\r\n"
7016 "Trunk: %s\r\n"
7017 "Encryption: %s\r\n"
7018 "Status: %s\r\n",
7019 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
7020 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
7021 peer->encmethods ? ast_str_buffer(encmethods) : "no",
7022 status);
7023 if (cont->peerlist) { /* IAXpeerlist */
7024 astman_append(s, "\r\n");
7025 } else { /* IAXpeers */
7026 astman_append(s,
7027 "Description: %s\r\n\r\n",
7028 peer->description);
7029 }
7030 } else {
7032 name,
7033 tmp_host,
7034 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
7035 tmp_mask,
7036 tmp_port,
7037 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ",
7038 peer->encmethods ? "(E)" : " ",
7039 status,
7040 peer->description);
7041 }
7042
7043 cont->total_peers++;
7044}
jack_status_t status
Definition: app_jack.c:146
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define IAX_TRUNK
Definition: chan_iax2.c:501
static void encmethods_to_str(int e, struct ast_str **buf)
Definition: chan_iax2.c:1797
static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
peer_status: Report Peer status in character string
Definition: chan_iax2.c:3839
#define IAX_DYNAMIC
Definition: chan_iax2.c:504
#define PEERS_FORMAT
Definition: chan_iax2.c:6943
static const char name[]
Definition: format_mp3.c:68
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3302
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition: netsock2.h:358
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_str_alloca(init_len)
Definition: strings.h:848
Support for dynamic strings.
Definition: strings.h:623
const ast_string_field username
Definition: chan_iax2.c:599
const ast_string_field description
Definition: chan_iax2.c:599
struct ast_sockaddr mask
Definition: chan_iax2.c:605
int encmethods
Definition: chan_iax2.c:612
char idtext[256]
Definition: chan_iax2.c:6933

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, name, iax2_peer::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().

◆ acf_channel_read()

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

Definition at line 14629 of file chan_iax2.c.

14630{
14631 struct chan_iax2_pvt *pvt;
14632 unsigned int callno;
14633 int res = 0;
14634
14635 if (!chan || ast_channel_tech(chan) != &iax2_tech) {
14636 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
14637 return -1;
14638 }
14639
14642 if (!(pvt = iaxs[callno])) {
14644 return -1;
14645 }
14646
14647 if (!strcasecmp(args, "osptoken")) {
14648 ast_copy_string(buf, pvt->osptoken, buflen);
14649 } else if (!strcasecmp(args, "peerip")) {
14651 } else if (!strcasecmp(args, "peername")) {
14652 ast_copy_string(buf, pvt->username, buflen);
14653 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
14654 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
14655 } else {
14656 res = -1;
14657 }
14658
14660
14661 return res;
14662}
#define IAX_CALLENCRYPTED(pvt)
Definition: chan_iax2.c:440
void * ast_channel_tech_pvt(const struct ast_channel *chan)
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_ERROR
const ast_string_field username
Definition: chan_iax2.c:861
const ast_string_field osptoken
Definition: chan_iax2.c:861
const char * args

References chan_iax2_pvt::addr, args, 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(), buf, chan_iax2_pvt::callno, iax2_tech, IAX_CALLENCRYPTED, iaxs, iaxsl, LOG_ERROR, chan_iax2_pvt::osptoken, PTR_TO_CALLNO, and chan_iax2_pvt::username.

◆ acf_iaxvar_read()

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

Definition at line 10119 of file chan_iax2.c.

10120{
10121 struct ast_datastore *variablestore;
10122 AST_LIST_HEAD(, ast_var_t) *varlist;
10123 struct ast_var_t *var;
10124
10125 if (!chan) {
10126 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
10127 return -1;
10128 }
10129
10131 if (!variablestore) {
10132 *buf = '\0';
10133 return 0;
10134 }
10135 varlist = variablestore->data;
10136
10137 AST_LIST_LOCK(varlist);
10138 AST_LIST_TRAVERSE(varlist, var, entries) {
10139 if (strcmp(var->name, data) == 0) {
10140 ast_copy_string(buf, var->value, len);
10141 break;
10142 }
10143 }
10144 AST_LIST_UNLOCK(varlist);
10145 return 0;
10146}
#define var
Definition: ast_expr2f.c:605
static const struct ast_datastore_info iax2_variable_datastore_info
Definition: chan_iax2.c:1569
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
Definition: linkedlists.h:173
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
struct ast_var_t::@211 entries

References ast_channel_datastore_find(), ast_copy_string(), AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, buf, ast_datastore::data, ast_var_t::entries, iax2_variable_datastore_info, len(), LOG_WARNING, NULL, and var.

◆ acf_iaxvar_write()

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

Definition at line 10148 of file chan_iax2.c.

10149{
10150 struct ast_datastore *variablestore;
10151 AST_LIST_HEAD(, ast_var_t) *varlist;
10152 struct ast_var_t *var;
10153
10154 if (!chan) {
10155 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
10156 return -1;
10157 }
10158
10160 if (!variablestore) {
10162 if (!variablestore) {
10163 ast_log(LOG_ERROR, "Memory allocation error\n");
10164 return -1;
10165 }
10166 varlist = ast_calloc(1, sizeof(*varlist));
10167 if (!varlist) {
10168 ast_datastore_free(variablestore);
10169 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
10170 return -1;
10171 }
10172
10173 AST_LIST_HEAD_INIT(varlist);
10174 variablestore->data = varlist;
10175 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10176 ast_channel_datastore_add(chan, variablestore);
10177 } else
10178 varlist = variablestore->data;
10179
10180 AST_LIST_LOCK(varlist);
10182 if (strcmp(var->name, data) == 0) {
10185 break;
10186 }
10187 }
10189 var = ast_var_assign(data, value);
10190 if (var)
10191 AST_LIST_INSERT_TAIL(varlist, var, entries);
10192 else
10193 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
10194 AST_LIST_UNLOCK(varlist);
10195 return 0;
10196}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:192
#define ast_var_assign(name, value)
Definition: chanvars.h:40
void ast_var_delete(struct ast_var_t *var)
Definition: extconf.c:2471
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:626
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
unsigned int inheritance
Definition: datastore.h:69
int value
Definition: syslog.c:37

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

◆ acl_change_stasis_cb()

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

Definition at line 1558 of file chan_iax2.c.

1560{
1562 return;
1563 }
1564
1565 ast_log(LOG_NOTICE, "Reloading chan_iax2 in response to ACL change event.\n");
1566 reload_config(1);
1567}
struct stasis_message_type * ast_named_acl_change_type(void)
a stasis_message_type for changes against a named ACL or the set of all named ACLs
static int reload_config(int forced_reload)
Definition: chan_iax2.c:14180
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.

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

Referenced by acl_change_stasis_subscribe(), and rtp_reload().

◆ acl_change_stasis_subscribe()

static void acl_change_stasis_subscribe ( void  )
static

Definition at line 1516 of file chan_iax2.c.

1517{
1518 if (!acl_change_sub) {
1523 }
1524}
static struct stasis_subscription * acl_change_sub
Definition: chan_iax2.c:328
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: chan_iax2.c:1558
struct stasis_topic * ast_security_topic(void)
A stasis_topic which publishes messages for security related issues.
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
Definition: stasis.h:297
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1023
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1077
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:649

References acl_change_stasis_cb(), acl_change_sub, ast_named_acl_change_type(), ast_security_topic(), NULL, stasis_subscribe, stasis_subscription_accept_message_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, and stasis_subscription_set_filter().

Referenced by build_peer(), and build_user().

◆ acl_change_stasis_unsubscribe()

static void acl_change_stasis_unsubscribe ( void  )
static

Definition at line 1526 of file chan_iax2.c.

1527{
1529}
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1134

References acl_change_sub, and stasis_unsubscribe_and_join().

Referenced by __unload_module().

◆ add_calltoken_ignore()

static int add_calltoken_ignore ( const char *  addr)
static

Definition at line 2842 of file chan_iax2.c.

2843{
2844 struct addr_range tmp;
2845 struct addr_range *addr_range = NULL;
2846 struct ast_ha *ha = NULL;
2847 int error = 0;
2848
2849 if (ast_strlen_zero(addr)) {
2850 ast_log(LOG_WARNING, "invalid calltokenoptional (null)\n");
2851 return -1;
2852 }
2853
2854 ha = ast_append_ha("permit", addr, NULL, &error);
2855
2856 /* check for valid config information */
2857 if (error) {
2858 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
2859 return -1;
2860 }
2861
2862 ast_copy_ha(ha, &tmp.ha);
2863 /* find or create the addr_range */
2866 addr_range->delme = 0;
2868 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
2869 /* copy over config data into addr_range object */
2870 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
2872 } else {
2873 ast_free_ha(ha);
2874 return -1;
2875 }
2876
2877 ast_free_ha(ha);
2878 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
2879
2880 return 0;
2881}
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:222
void ast_copy_ha(const struct ast_ha *from, struct ast_ha *to)
Copy the contents of one HA to another.
Definition: acl.c:255
struct ast_ha * ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule to a list of HAs.
Definition: acl.c:712
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static int tmp()
Definition: bt_open.c:389
struct ast_ha ha
Definition: chan_iax2.c:1042
unsigned char delme
Definition: chan_iax2.c:1046
internal representation of ACL entries In principle user applications would have no need for this,...
Definition: acl.h:51
struct ast_sockaddr addr
Definition: acl.h:53
int error(const char *format,...)
Definition: utils/frame.c:999

References ast_ha::addr, ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log, ast_strlen_zero(), calltoken_ignores, addr_range::delme, error(), addr_range::ha, LOG_WARNING, NULL, OBJ_POINTER, and tmp().

Referenced by set_config().

◆ add_empty_calltoken_ie()

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

Definition at line 4858 of file chan_iax2.c.

4859{
4860 /* first make sure their are two empty bytes left in ied->buf */
4861 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
4862 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */
4863 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */
4864 pvt->calltoken_ie_len = 2;
4865 }
4866}
#define IAX_IE_CALLTOKEN
Definition: iax2.h:185
unsigned char calltoken_ie_len
Definition: chan_iax2.c:933
int pos
Definition: parser.h:151
unsigned char buf[1024]
Definition: parser.h:150

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

◆ addr_range_cmp_cb()

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

Definition at line 2498 of file chan_iax2.c.

2499{
2500 struct addr_range *lim1 = obj, *lim2 = arg;
2501 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
2502 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
2503 CMP_MATCH | CMP_STOP : 0;
2504}
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:413
struct ast_sockaddr netmask
Definition: acl.h:54

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

Referenced by load_objects().

◆ addr_range_delme_cb()

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

Definition at line 2485 of file chan_iax2.c.

2486{
2487 struct addr_range *lim = obj;
2488 lim->delme = 1;
2489 return 0;
2490}

References addr_range::delme.

Referenced by set_config_destroy().

◆ addr_range_hash_cb()

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

Definition at line 2492 of file chan_iax2.c.

2493{
2494 const struct addr_range *lim = obj;
2495 return abs(ast_sockaddr_hash(&lim->ha.addr));
2496}
#define abs(x)
Definition: f2c.h:195
int ast_sockaddr_hash(const struct ast_sockaddr *addr)
Computes a hash value from the address. The port is ignored.
Definition: netsock2.c:548

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

Referenced by load_objects().

◆ addr_range_match_address_cb()

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

Definition at line 2522 of file chan_iax2.c.

2523{
2524 struct addr_range *addr_range = obj;
2525 struct ast_sockaddr *addr = arg;
2526 struct ast_sockaddr tmp_addr;
2527
2528 ast_sockaddr_apply_netmask(addr, &addr_range->ha.netmask, &tmp_addr);
2529
2530 if (!ast_sockaddr_cmp_addr(&tmp_addr, &addr_range->ha.addr)) {
2531 return CMP_MATCH | CMP_STOP;
2532 }
2533 return 0;
2534}
int ast_sockaddr_apply_netmask(const struct ast_sockaddr *addr, const struct ast_sockaddr *netmask, struct ast_sockaddr *result)
Apply a netmask to an address and store the result in a separate structure.
Definition: netsock2.c:357
Socket address structure.
Definition: netsock2.h:97

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

◆ apply_context()

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

Definition at line 7876 of file chan_iax2.c.

7877{
7878 while(con) {
7879 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
7880 return -1;
7881 con = con->next;
7882 }
7883 return 0;
7884}
char context[AST_MAX_CONTEXT]
Definition: chan_iax2.c:493
struct iax2_context * next
Definition: chan_iax2.c:494

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

Referenced by check_access().

◆ ast_cli_netstats()

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

Definition at line 7577 of file chan_iax2.c.

7578{
7579 int x;
7580 int numchans = 0;
7581 char first_message[10] = { 0, };
7582 char last_message[10] = { 0, };
7583#define ACN_FORMAT1 "%-24.25s %4u %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
7584#define ACN_FORMAT2 "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
7585 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
7586 ast_mutex_lock(&iaxsl[x]);
7587 if (iaxs[x]) {
7588 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
7589 jb_info jbinfo;
7590 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
7591 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
7592
7594 jb_getinfo(iaxs[x]->jb, &jbinfo);
7595 localjitter = jbinfo.jitter;
7596 localdelay = jbinfo.current - jbinfo.min;
7597 locallost = jbinfo.frames_lost;
7598 locallosspct = jbinfo.losspct/1000;
7599 localdropped = jbinfo.frames_dropped;
7600 localooo = jbinfo.frames_ooo;
7601 } else {
7602 localjitter = -1;
7603 localdelay = 0;
7604 locallost = -1;
7605 locallosspct = -1;
7606 localdropped = 0;
7607 localooo = -1;
7608 }
7609 if (s)
7610 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
7611 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
7612 iaxs[x]->pingtime,
7613 localjitter,
7614 localdelay,
7615 locallost,
7616 locallosspct,
7617 localdropped,
7618 localooo,
7619 iaxs[x]->frames_received/1000,
7620 iaxs[x]->remote_rr.jitter,
7621 iaxs[x]->remote_rr.delay,
7625 iaxs[x]->remote_rr.ooo,
7626 iaxs[x]->remote_rr.packets/1000,
7627 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7628 first_message,
7629 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7630 last_message);
7631 else
7632 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
7633 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
7634 iaxs[x]->pingtime,
7635 localjitter,
7636 localdelay,
7637 locallost,
7638 locallosspct,
7639 localdropped,
7640 localooo,
7641 iaxs[x]->frames_received/1000,
7642 iaxs[x]->remote_rr.jitter,
7643 iaxs[x]->remote_rr.delay,
7647 iaxs[x]->remote_rr.ooo,
7648 iaxs[x]->remote_rr.packets/1000,
7649 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7650 first_message,
7651 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7652 last_message);
7653 numchans++;
7654 }
7656 }
7657
7658 return numchans;
7659}
#define MARK_IAX_SUBCLASS_TX
Definition: chan_iax2.c:718
#define ACN_FORMAT2
#define ACN_FORMAT1
enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats)
get jitterbuf info: only "statistics" may be valid
Definition: jitterbuf.c:815
void iax_frame_subclass2str(enum iax_frame_subclass subclass, char *str, size_t len)
Definition: parser.c:463
int first_iax_message
Definition: chan_iax2.c:766
struct iax_rr remote_rr
Definition: chan_iax2.c:923
int last_iax_message
Definition: chan_iax2.c:768
int ooo
Definition: chan_iax2.c:733
int losscnt
Definition: chan_iax2.c:729
int delay
Definition: chan_iax2.c:731
int losspct
Definition: chan_iax2.c:728
int dropped
Definition: chan_iax2.c:732
int packets
Definition: chan_iax2.c:730
long min
Definition: jitterbuf.h:87
long current
Definition: jitterbuf.h:88
long losspct
Definition: jitterbuf.h:90
long frames_lost
Definition: jitterbuf.h:82
long frames_ooo
Definition: jitterbuf.h:84
long frames_dropped
Definition: jitterbuf.h:83
long jitter
Definition: jitterbuf.h:86

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, iaxs, iaxsl, jb_getinfo(), 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().

◆ ast_iax2_new()

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

Create new call, interface with the PBX core.

Definition at line 5906 of file chan_iax2.c.

5909{
5910 struct ast_channel *tmp = NULL;
5911 struct chan_iax2_pvt *i;
5912 struct iax2_peer *peer;
5913 struct ast_variable *v = NULL;
5914 struct ast_format_cap *native;
5915 struct ast_format *tmpfmt;
5916 ast_callid callid;
5917 char *peer_name = NULL;
5918
5919 if (!(i = iaxs[callno])) {
5920 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
5921 return NULL;
5922 }
5923
5924 if (!capability) {
5925 ast_log(LOG_WARNING, "No formats specified for call to: IAX2/%s-%d\n",
5926 i->host, i->callno);
5927 return NULL;
5928 }
5930 if (!native) {
5931 return NULL;
5932 }
5933 if (iax2_codec_pref_best_bitfield2cap(capability, prefs, native)
5934 || !ast_format_cap_count(native)) {
5935 ast_log(LOG_WARNING, "No requested formats available for call to: IAX2/%s-%d\n",
5936 i->host, i->callno);
5937 ao2_ref(native, -1);
5938 return NULL;
5939 }
5940
5941 if (!ast_strlen_zero(i->peer)) {
5942 peer_name = ast_strdupa(i->peer);
5943 } else if (!ast_strlen_zero(i->host)) {
5944 peer_name = ast_strdupa(i->host);
5945 }
5946
5947 /* Don't hold call lock while making a channel or looking up a peer */
5948 ast_mutex_unlock(&iaxsl[callno]);
5949
5950 if (!ast_strlen_zero(peer_name)) {
5951 peer = find_peer(peer_name, 1);
5952 if (peer && peer->endpoint) {
5954 i->accountcode, i->exten, i->context, assignedids, requestor,
5955 i->amaflags, peer->endpoint, "IAX2/%s-%d", i->host, i->callno);
5956 }
5957 ao2_cleanup(peer);
5958 }
5959
5960 if (!tmp) {
5962 i->exten, i->context, assignedids, requestor, i->amaflags, "IAX2/%s-%d",
5963 i->host, i->callno);
5964 }
5965
5966 ast_mutex_lock(&iaxsl[callno]);
5967 if (i != iaxs[callno]) {
5968 if (tmp) {
5969 /* unlock and relock iaxsl[callno] to preserve locking order */
5970 ast_mutex_unlock(&iaxsl[callno]);
5973 ast_mutex_lock(&iaxsl[callno]);
5974 }
5975 ao2_ref(native, -1);
5976 return NULL;
5977 }
5978 if (!tmp) {
5979 ao2_ref(native, -1);
5980 return NULL;
5981 }
5982
5984
5985 if ((callid = iaxs[callno]->callid)) {
5986 ast_channel_callid_set(tmp, callid);
5987 }
5988
5990
5991 /* We can support any format by default, until we get restricted */
5993 tmpfmt = ast_format_cap_get_format(native, 0);
5994
5999
6000 ao2_ref(tmpfmt, -1);
6001 ao2_ref(native, -1);
6002
6004
6005 if (!ast_strlen_zero(i->parkinglot))
6006 ast_channel_parkinglot_set(tmp, i->parkinglot);
6007 /* Don't use ast_set_callerid() here because it will
6008 * generate a NewCallerID event before the NewChannel event */
6009 if (!ast_strlen_zero(i->ani)) {
6012 } else if (!ast_strlen_zero(i->cid_num)) {
6015 }
6017 if (!ast_strlen_zero(i->rdnis)) {
6020 }
6026 if (!ast_strlen_zero(i->language))
6027 ast_channel_language_set(tmp, i->language);
6029 ast_channel_accountcode_set(tmp, i->accountcode);
6030 if (i->amaflags)
6034 if (i->adsi)
6036 else
6038 i->owner = tmp;
6039 i->capability = capability;
6040
6041 if (!cachable) {
6043 }
6044
6045 /* Set inherited variables */
6046 if (i->vars) {
6047 for (v = i->vars ; v ; v = v->next)
6049 }
6050 if (i->iaxvars) {
6051 struct ast_datastore *variablestore;
6052 struct ast_variable *var, *prev = NULL;
6053 AST_LIST_HEAD(, ast_var_t) *varlist;
6054 ast_debug(1, "Loading up the channel with IAXVARs\n");
6055 varlist = ast_calloc(1, sizeof(*varlist));
6057 if (variablestore && varlist) {
6058 variablestore->data = varlist;
6059 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
6060 AST_LIST_HEAD_INIT(varlist);
6061 for (var = i->iaxvars; var; var = var->next) {
6062 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
6063 if (prev)
6064 ast_free(prev);
6065 prev = var;
6066 if (!newvar) {
6067 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
6068 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
6069 } else {
6070 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
6071 }
6072 }
6073 if (prev)
6074 ast_free(prev);
6075 i->iaxvars = NULL;
6076 ast_channel_datastore_add(i->owner, variablestore);
6077 } else {
6078 if (variablestore) {
6079 ast_datastore_free(variablestore);
6080 }
6081 if (varlist) {
6082 ast_free(varlist);
6083 }
6084 }
6085 }
6086
6089
6090 if (state != AST_STATE_DOWN) {
6091 if (ast_pbx_start(tmp)) {
6092 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
6093 /* unlock and relock iaxsl[callno] to preserve locking order */
6094 ast_mutex_unlock(&iaxsl[callno]);
6095 ast_hangup(tmp);
6096 ast_mutex_lock(&iaxsl[callno]);
6097 return NULL;
6098 }
6099 }
6100
6102 return tmp;
6103}
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define CALLNO_TO_PTR(a)
Definition: chan_iax2.c:293
static struct iax2_peer * find_peer(const char *name, int realtime)
Definition: chan_iax2.c:2056
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
#define ast_channel_alloc_with_endpoint(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag, endpoint,...)
Definition: channel.h:1262
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1258
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
@ AST_ADSI_UNAVAILABLE
Definition: channel.h:871
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1584
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
@ AST_FLAG_DISABLE_DEVSTATE_CACHE
Definition: channel.h:1029
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_channel_callid_set(struct ast_channel *chan, ast_callid value)
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
@ AST_STATE_DOWN
Definition: channelstate.h:36
int iax2_codec_pref_best_bitfield2cap(uint64_t bitfield, struct iax2_codec_pref *prefs, struct ast_format_cap *cap)
Convert a bitfield to a format capabilities structure in the "best" order.
Definition: codec_pref.c:112
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
unsigned int ast_callid
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4708
Main Channel structure associated with a channel.
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
struct ast_module * self
Definition: module.h:342
struct ast_party_id id
Caller party ID.
Definition: channel.h:420
int ani2
Automatic Number Identification 2 (Info Digits)
Definition: channel.h:433
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:427
struct ast_party_dialed::@208 number
Dialed/Called number.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:386
int transit_network_select
Transit Network Select.
Definition: channel.h:397
struct ast_party_name name
Subscriber name.
Definition: channel.h:340
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:342
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:277
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:295
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:297
char * str
Subscriber phone number (Malloced)
Definition: channel.h:291
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:293
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:527
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
struct ast_variable * vars
Definition: chan_iax2.c:919
const ast_string_field language
Definition: chan_iax2.c:861
int calling_ani2
Definition: chan_iax2.c:915
const ast_string_field cid_num
Definition: chan_iax2.c:861
iax2_format capability
Definition: chan_iax2.c:756
const ast_string_field accountcode
Definition: chan_iax2.c:861
struct ast_variable * iaxvars
Definition: chan_iax2.c:921
const ast_string_field context
Definition: chan_iax2.c:861
const ast_string_field rdnis
Definition: chan_iax2.c:861
int calling_pres
Definition: chan_iax2.c:914
const ast_string_field exten
Definition: chan_iax2.c:861
const ast_string_field ani
Definition: chan_iax2.c:861
const ast_string_field cid_name
Definition: chan_iax2.c:861
const ast_string_field dnid
Definition: chan_iax2.c:861
const ast_string_field peer
Definition: chan_iax2.c:861
#define ast_set_flag(p, flag)
Definition: utils.h:70

References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, chan_iax2_pvt::amaflags, chan_iax2_pvt::ani, ast_party_caller::ani, ast_party_caller::ani2, 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_ani2, 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(), iax2_tech, iax2_variable_datastore_info, iaxs, iaxsl, chan_iax2_pvt::iaxvars, ast_party_caller::id, ast_datastore::inheritance, chan_iax2_pvt::language, LOG_ERROR, LOG_WARNING, ast_party_id::name, ast_variable::name, ast_variable::next, NULL, ast_party_id::number, ast_party_dialed::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_name::presentation, ast_party_number::presentation, chan_iax2_pvt::rdnis, ast_module_info::self, ast_party_number::str, ast_party_dialed::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().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 15136 of file chan_iax2.c.

◆ attempt_transmit()

static int attempt_transmit ( const void *  data)
static

Definition at line 3678 of file chan_iax2.c.

3679{
3680#ifdef SCHED_MULTITHREADED
3682#endif
3683 __attempt_transmit(data);
3684 return 0;
3685}
#define schedule_action(func, data)
Definition: chan_iax2.c:1724
static void __attempt_transmit(const void *data)
Definition: chan_iax2.c:3595

References __attempt_transmit(), ast_frame::data, and schedule_action.

Referenced by __attempt_transmit(), and transmit_frame().

◆ auth_fail()

static int auth_fail ( int  callno,
int  failcode 
)
static

Definition at line 9458 of file chan_iax2.c.

9459{
9460 /* Schedule sending the authentication failure in one second, to prevent
9461 guessing */
9462 if (iaxs[callno]) {
9463 iaxs[callno]->authfail = failcode;
9464 if (delayreject) {
9465 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
9466 sched, 1000, auth_reject, (void *)(long)callno);
9467 } else
9468 auth_reject((void *)(long)callno);
9469 }
9470 return 0;
9471}
static int delayreject
Definition: chan_iax2.c:478
static int auth_reject(const void *data)
Definition: chan_iax2.c:9444
static int iax2_sched_replace(int id, struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data)
Definition: chan_iax2.c:1727

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

Referenced by socket_process_helper().

◆ auth_method_names()

static char * auth_method_names ( int  authmethods,
char *restrict  buf 
)
static

Get names of all auth methods.

Parameters
Bitfield of auth methods
[out]bufBuffer into which to write the names. Must be of size AUTH_METHOD_NAMES_BUFSIZE.
Returns
Auth methods name

Definition at line 415 of file chan_iax2.c.

416{
417 char *pos = buf;
418
419 *pos = '\0';
420
421 if (authmethods & IAX_AUTH_RSA) {
422 pos += sprintf(pos, "|RSA");
423 }
424 if (authmethods & IAX_AUTH_MD5) {
425 pos += sprintf(pos, "|MD5");
426 }
427 if (authmethods & IAX_AUTH_PLAINTEXT) {
428 pos += sprintf(pos, "|plaintext");
429 }
430
431 if (pos == buf) { /* No auth methods */
432 strcpy(buf, "none");
433 return buf;
434 }
435
436 return buf + 1; /* Skip leading | */
437}
#define IAX_AUTH_RSA
Definition: iax2.h:199
#define IAX_AUTH_MD5
Definition: iax2.h:198
#define IAX_AUTH_PLAINTEXT
Definition: iax2.h:197

References buf, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by socket_process_helper().

◆ auth_reject()

static int auth_reject ( const void *  data)
static

Definition at line 9444 of file chan_iax2.c.

9445{
9446 int callno = (int)(long)(data);
9447 ast_mutex_lock(&iaxsl[callno]);
9448 if (iaxs[callno])
9449 iaxs[callno]->authid = -1;
9450 ast_mutex_unlock(&iaxsl[callno]);
9451#ifdef SCHED_MULTITHREADED
9452 if (schedule_action(__auth_reject, data))
9453#endif
9454 __auth_reject(data);
9455 return 0;
9456}
static void __auth_reject(const void *nothing)
Definition: chan_iax2.c:9424

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

Referenced by auth_fail().

◆ authenticate()

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

8466{
8467 int res = -1;
8468 int x;
8469 if (!ast_strlen_zero(keyn)) {
8470 if (!(authmethods & IAX_AUTH_RSA)) {
8471 if (ast_strlen_zero(secret)) {
8472 ast_log(LOG_WARNING, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_sockaddr_stringify_addr(addr));
8473 }
8474 } else if (ast_strlen_zero(challenge)) {
8475 ast_log(LOG_WARNING, "No challenge provided for RSA authentication to %s\n", ast_sockaddr_stringify_addr(addr));
8476 } else {
8477 char sig[256];
8478 struct ast_key *key;
8479 key = ast_key_get(keyn, AST_KEY_PRIVATE);
8480 if (!key) {
8481 ast_log(LOG_WARNING, "Unable to find private key '%s'\n", keyn);
8482 } else {
8483 if (ast_sign(key, (char*)challenge, sig)) {
8484 ast_log(LOG_WARNING, "Unable to sign challenge with key\n");
8485 res = -1;
8486 } else {
8488 if (pvt) {
8490 }
8491 res = 0;
8492 }
8493 }
8494
8495 if (pvt && !ast_strlen_zero(secret)) {
8496 struct MD5Context md5;
8497 unsigned char digest[16];
8498
8499 MD5Init(&md5);
8500 MD5Update(&md5, (unsigned char *) challenge, strlen(challenge));
8501 MD5Update(&md5, (unsigned char *) secret, strlen(secret));
8502 MD5Final(digest, &md5);
8503
8504 build_encryption_keys(digest, pvt);
8505 }
8506 }
8507 }
8508 /* Fall back */
8509 if (res && !ast_strlen_zero(secret)) {
8510 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
8511 struct MD5Context md5;
8512 unsigned char digest[16];
8513 char digres[128];
8514 MD5Init(&md5);
8515 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
8516 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
8517 MD5Final(digest, &md5);
8518 /* If they support md5, authenticate with it. */
8519 for (x=0;x<16;x++)
8520 sprintf(digres + (x << 1), "%02hhx", digest[x]); /* safe */
8521 if (pvt) {
8522 build_encryption_keys(digest, pvt);
8524 }
8526 res = 0;
8527 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
8528 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
8529 if (pvt) {
8531 }
8532 res = 0;
8533 } else
8534 ast_log(LOG_WARNING, "No way to send secret to peer '%s' (their methods: %d)\n", ast_sockaddr_stringify_addr(addr), authmethods);
8535 }
8536 return res;
8537}
static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:6459
struct ast_key * ast_key_get(const char *kname, int ktype)
Retrieve a key.
Definition: res_crypto.c:149
#define AST_KEY_PRIVATE
Definition: crypto.h:47
int ast_sign(struct ast_key *key, char *msg, char *sig)
Sign a message signature using a given private key.
Definition: res_crypto.c:584
static int md5(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_md5.c:52
#define IAX_IE_PASSWORD
Definition: iax2.h:137
#define IAX_IE_RSA_RESULT
Definition: iax2.h:147
#define IAX_IE_MD5_RESULT
Definition: iax2.h:146
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
Definition: md5.c:72
void MD5Init(struct MD5Context *context)
Definition: md5.c:57
void MD5Final(unsigned char digest[16], struct MD5Context *context)
Definition: md5.c:120
static void challenge(const char *realm, pjsip_tx_data *tdata, const pjsip_rx_data *rdata, int is_stale)
astobj2 callback for adding digest challenges to responses
Definition: md5.h:26
int eff_auth_method
Definition: chan_iax2.c:867

References ast_key_get(), AST_KEY_PRIVATE, ast_log, ast_sign(), ast_sockaddr_stringify_addr(), ast_strlen_zero(), build_encryption_keys(), challenge(), chan_iax2_pvt::eff_auth_method, 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_WARNING, md5(), MD5Final(), MD5Init(), and MD5Update().

Referenced by authenticate_reply(), and registry_rerequest().

◆ authenticate_reply()

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

8544{
8545 struct iax2_peer *peer = NULL;
8546 /* Start pessimistic */
8547 int res = -1;
8548 int authmethods = 0;
8549 struct iax_ie_data ied;
8550 uint16_t callno = p->callno;
8551
8552 memset(&ied, 0, sizeof(ied));
8553
8554 if (ies->username)
8555 ast_string_field_set(p, username, ies->username);
8556 if (ies->challenge)
8558 if (ies->authmethods)
8559 authmethods = ies->authmethods;
8560 if (authmethods & IAX_AUTH_MD5)
8562 else
8563 p->encmethods = 0;
8564
8565 /* Check for override RSA authentication first */
8566 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
8567 /* Normal password authentication */
8568 res = authenticate(p->challenge, override, okey, authmethods, &ied, addr, p);
8569 } else {
8570 struct ao2_iterator i = ao2_iterator_init(peers, 0);
8571 while ((peer = ao2_iterator_next(&i))) {
8572 struct ast_sockaddr peer_addr;
8573 struct ast_sockaddr tmp_sockaddr1;
8574 struct ast_sockaddr tmp_sockaddr2;
8575
8576 ast_sockaddr_copy(&peer_addr, &peer->addr);
8577
8578 ast_sockaddr_apply_netmask(addr, &peer->mask, &tmp_sockaddr1);
8579 ast_sockaddr_apply_netmask(&peer_addr, &peer->mask, &tmp_sockaddr2);
8580
8581 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
8582 /* No peer specified at our end, or this is the peer */
8583 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
8584 /* No username specified in peer rule, or this is the right username */
8585 && (ast_sockaddr_isnull(&peer_addr) || !(ast_sockaddr_cmp_addr(&tmp_sockaddr1, &tmp_sockaddr2)))
8586 /* No specified host, or this is our host */
8587 ) {
8588 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, addr, p);
8589 if (!res) {
8590 peer_unref(peer);
8591 break;
8592 }
8593 }
8594 peer_unref(peer);
8595 }
8597 if (!peer) {
8598 /* We checked our list and didn't find one. It's unlikely, but possible,
8599 that we're trying to authenticate *to* a realtime peer */
8600 const char *peer_name = ast_strdupa(p->peer);
8601 ast_mutex_unlock(&iaxsl[callno]);
8602 if ((peer = realtime_peer(peer_name, NULL))) {
8603 ast_mutex_lock(&iaxsl[callno]);
8604 if (!(p = iaxs[callno])) {
8605 peer_unref(peer);
8606 return -1;
8607 }
8608 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, addr, p);
8609 peer_unref(peer);
8610 }
8611 if (!peer) {
8612 ast_mutex_lock(&iaxsl[callno]);
8613 if (!(p = iaxs[callno]))
8614 return -1;
8615 }
8616 }
8617 }
8618
8619 if (!(ies->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT)) && (ies->authmethods & IAX_AUTH_RSA) && ast_strlen_zero(okey)) {
8620 /* If the only thing available is RSA, and we don't have an outkey, we can't do it... */
8621 ast_log(LOG_WARNING, "Call terminated. RSA authentication requires an outkey\n");
8622 return -1;
8623 }
8624
8625 if (ies->encmethods) {
8626 if (ast_strlen_zero(p->secret) &&
8628 ast_log(LOG_WARNING, "Call terminated. Encryption requested by peer but no secret available locally\n");
8629 return -1;
8630 }
8631 /* Don't even THINK about trying to encrypt or decrypt anything if we don't have valid keys, for some reason... */
8632 /* If either of these happens, it's our fault, not the user's. But we should abort rather than crash. */
8636 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
8637 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n");
8638 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */
8639 }
8640 if (!res) {
8641 struct ast_datastore *variablestore;
8642 struct ast_variable *var, *prev = NULL;
8643 AST_LIST_HEAD(, ast_var_t) *varlist;
8644 varlist = ast_calloc(1, sizeof(*varlist));
8646 if (variablestore && varlist && p->owner) {
8647 variablestore->data = varlist;
8648 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
8649 AST_LIST_HEAD_INIT(varlist);
8650 for (var = ies->vars; var; var = var->next) {
8651 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
8652 if (prev)
8653 ast_free(prev);
8654 prev = var;
8655 if (!newvar) {
8656 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */
8657 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
8658 } else {
8659 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
8660 }
8661 }
8662 if (prev)
8663 ast_free(prev);
8664 ies->vars = NULL;
8665 ast_channel_datastore_add(p->owner, variablestore);
8666 } else {
8667 if (p->owner)
8668 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
8669 if (variablestore)
8670 ast_datastore_free(variablestore);
8671 if (varlist)
8672 ast_free(varlist);
8673 }
8674 }
8675
8676 if (!res)
8677 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
8678 return res;
8679}
static struct iax2_peer * realtime_peer(const char *peername, struct ast_sockaddr *addr)
Definition: chan_iax2.c:4417
#define IAX_ENCRYPTED
Definition: chan_iax2.c:510
static int invalid_key(ast_aes_decrypt_key *ecx)
Definition: chan_iax2.c:6443
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)
Definition: chan_iax2.c:8465
#define IAX_KEYPOPULATED
Definition: chan_iax2.c:511
static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
Definition: chan_iax2.c:8136
@ IAX_COMMAND_AUTHREP
Definition: iax2.h:60
const ast_string_field challenge
Definition: chan_iax2.c:861
ast_aes_decrypt_key dcx
Definition: chan_iax2.c:875
const ast_string_field secret
Definition: chan_iax2.c:861
ast_aes_encrypt_key ecx
Definition: chan_iax2.c:871
const ast_string_field outkey
Definition: chan_iax2.c:599
int authmethods
Definition: chan_iax2.c:611
const ast_string_field secret
Definition: chan_iax2.c:599
struct ast_variable * vars
Definition: parser.h:81
unsigned int authmethods
Definition: parser.h:47
char * challenge
Definition: parser.h:49
unsigned int encmethods
Definition: parser.h:48
char * username
Definition: parser.h:37
#define ast_assert_return(a,...)
Definition: utils.h:740
#define ast_set_flag64(p, flag)
Definition: utils.h:127

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_assert_return, 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(), iax2_peer::authmethods, iax_ies::authmethods, iax_ie_data::buf, chan_iax2_pvt::callno, chan_iax2_pvt::challenge, iax_ies::challenge, challenge(), ast_datastore::data, DATASTORE_INHERIT_FOREVER, chan_iax2_pvt::dcx, chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_ies::encmethods, ast_var_t::entries, iax2_variable_datastore_info, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_FORCE_ENCRYPT, IAX_KEYPOPULATED, iaxs, iaxsl, ast_datastore::inheritance, invalid_key(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, iax2_peer::mask, merge_encryption(), iax2_peer::name, NULL, iax2_peer::outkey, chan_iax2_pvt::owner, chan_iax2_pvt::peer, peer_unref(), iax_ie_data::pos, realtime_peer(), iax2_peer::secret, chan_iax2_pvt::secret, send_command(), iax2_peer::username, chan_iax2_pvt::username, iax_ies::username, var, and iax_ies::vars.

Referenced by socket_process_helper().

◆ authenticate_request()

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

8158{
8159 struct iax_ie_data ied;
8160 int res = -1, authreq_restrict = 0;
8161 char challenge[10];
8162 struct chan_iax2_pvt *p = iaxs[call_num];
8163
8164 memset(&ied, 0, sizeof(ied));
8165
8166 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
8168 struct iax2_user *user;
8169
8171 if (user) {
8172 if (user->curauthreq == user->maxauthreq)
8173 authreq_restrict = 1;
8174 else
8175 user->curauthreq++;
8176 user = user_unref(user);
8177 }
8178 }
8179
8180 /* If the AUTHREQ limit test failed, send back an error */
8181 if (authreq_restrict) {
8182 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
8184 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
8185 return 0;
8186 }
8187
8189 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
8190 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
8192 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
8194 }
8195 if (p->encmethods)
8197
8199
8200 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
8201
8202 if (p->encmethods)
8204
8205 return res;
8206}
#define OBJ_KEY
Definition: astobj2.h:1151
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:111
static struct iax2_user * user_unref(struct iax2_user *user)
Definition: chan_iax2.c:2086
#define IAX_MAXAUTHREQ
Definition: chan_iax2.c:521
@ IAX_COMMAND_AUTHREQ
Definition: iax2.h:59
#define IAX_IE_ENCRYPTION
Definition: iax2.h:173
#define IAX_IE_AUTHMETHODS
Definition: iax2.h:144
#define IAX_IE_USERNAME
Definition: iax2.h:136
#define IAX_IE_CHALLENGE
Definition: iax2.h:145
int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsigned short value)
Definition: parser.c:763
static char user[512]
structure to hold users read from users.conf
long int ast_random(void)
Definition: utils.c:2312

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

Referenced by socket_process_helper().

◆ authenticate_verify()

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

Definition at line 8208 of file chan_iax2.c.

8209{
8210 char requeststr[256];
8211 char md5secret[256] = "";
8212 char secret[256] = "";
8213 char rsasecret[256] = "";
8214 int res = -1;
8215 int x;
8216 struct iax2_user *user;
8217
8218 if (p->authrej) {
8219 return res;
8220 }
8221
8223 if (user) {
8225 ast_atomic_fetchadd_int(&user->curauthreq, -1);
8227 }
8228 ast_string_field_set(p, host, user->name);
8229 user = user_unref(user);
8230 }
8232 ast_log(LOG_WARNING, "Call Terminated, incoming call is unencrypted while force encrypt is enabled.\n");
8233 return res;
8234 }
8236 return res;
8237 if (ies->password)
8238 ast_copy_string(secret, ies->password, sizeof(secret));
8239 if (ies->md5_result)
8240 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
8241 if (ies->rsa_result)
8242 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
8243 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
8244 struct ast_key *key;
8245 char *keyn;
8246 char *tmpkey;
8247 char *stringp=NULL;
8248 if (!(tmpkey = ast_strdup(p->inkeys))) {
8249 ast_log(LOG_ERROR, "Unable to create a temporary string for parsing stored 'inkeys'\n");
8250 return res;
8251 }
8252 stringp = tmpkey;
8253 keyn = strsep(&stringp, ":");
8254 while(keyn) {
8255 key = ast_key_get(keyn, AST_KEY_PUBLIC);
8256 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
8257 res = 0;
8259 break;
8260 } else if (!key) {
8261 ast_log(LOG_WARNING, "Requested inkey '%s' for RSA authentication does not exist\n", keyn);
8262 }
8263 keyn = strsep(&stringp, ":");
8264 }
8265 ast_free(tmpkey);
8266 if (res && authdebug) {
8267 ast_log(LOG_WARNING, "No RSA public keys on file matched incoming call\n");
8268 }
8269 } else if (p->authmethods & IAX_AUTH_MD5) {
8270 struct MD5Context md5;
8271 unsigned char digest[16];
8272 char *tmppw, *stringp;
8273 tmppw = ast_strdupa(p->secret);
8274 stringp = tmppw;
8275 while((tmppw = strsep(&stringp, ";"))) {
8276 MD5Init(&md5);
8277 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
8278 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
8279 MD5Final(digest, &md5);
8280 /* If they support md5, authenticate with it. */
8281 for (x=0;x<16;x++)
8282 sprintf(requeststr + (x << 1), "%02hhx", digest[x]); /* safe */
8283 if (!strcasecmp(requeststr, md5secret)) {
8284 res = 0;
8286 break;
8287 } else if (authdebug) {
8288 ast_log(LOG_WARNING, "MD5 secret mismatch\n");
8289 }
8290 }
8291 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
8292 if (!strcmp(secret, p->secret)) {
8293 res = 0;
8295 } else if (authdebug) {
8296 ast_log(LOG_WARNING, "Plaintext secret mismatch\n");
8297 }
8298 }
8299 return res;
8300}
static int authdebug
Definition: chan_iax2.c:345
#define AST_KEY_PUBLIC
Definition: crypto.h:46
int ast_check_signature(struct ast_key *key, const char *msg, const char *sig)
Check the authenticity of a message signature using a given public key.
Definition: res_crypto.c:673
char * strsep(char **str, const char *delims)
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:757
const ast_string_field inkeys
Definition: chan_iax2.c:861
struct ast_flags state
Definition: chan_iax2.c:810
const ast_string_field secret
Definition: chan_iax2.c:561
char * password
Definition: parser.h:38
char * md5_result
Definition: parser.h:50
char * rsa_result
Definition: parser.h:51
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_clear_flag64(p, flag)
Definition: utils.h:134

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, authdebug, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::challenge, chan_iax2_pvt::eff_auth_method, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_FORCE_ENCRYPT, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, LOG_ERROR, LOG_WARNING, md5(), iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), NULL, OBJ_KEY, iax_ies::password, iax_ies::rsa_result, iax2_user::secret, chan_iax2_pvt::secret, chan_iax2_pvt::state, strsep(), user, user_unref(), and chan_iax2_pvt::username.

Referenced by socket_process_helper().

◆ auto_congest()

static int auto_congest ( const void *  data)
static

Definition at line 4795 of file chan_iax2.c.

4796{
4797#ifdef SCHED_MULTITHREADED
4799#endif
4800 __auto_congest(data);
4801 return 0;
4802}
static void __auto_congest(const void *nothing)
Definition: chan_iax2.c:4782

References __auto_congest(), ast_frame::data, and schedule_action.

Referenced by iax2_call().

◆ auto_hangup()

static int auto_hangup ( const void *  data)
static

Definition at line 9488 of file chan_iax2.c.

9489{
9490 int callno = (int)(long)(data);
9491 ast_mutex_lock(&iaxsl[callno]);
9492 if (iaxs[callno]) {
9493 iaxs[callno]->autoid = -1;
9494 }
9495 ast_mutex_unlock(&iaxsl[callno]);
9496#ifdef SCHED_MULTITHREADED
9497 if (schedule_action(__auto_hangup, data))
9498#endif
9499 __auto_hangup(data);
9500 return 0;
9501}
static void __auto_hangup(const void *nothing)
Definition: chan_iax2.c:9473

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

Referenced by iax2_dprequest(), and iax2_provision().

◆ build_callno_limits()

static void build_callno_limits ( struct ast_variable v)
static

Definition at line 2787 of file chan_iax2.c.

2788{
2789 struct addr_range *addr_range = NULL;
2790 struct addr_range tmp;
2791 struct ast_ha *ha;
2792 int limit;
2793 int error;
2794 int found;
2795
2796 for (; v; v = v->next) {
2797 limit = -1;
2798 error = 0;
2799 found = 0;
2800 ha = ast_append_ha("permit", v->name, NULL, &error);
2801
2802 /* check for valid config information */
2803 if (error) {
2804 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
2805 continue;
2806 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
2807 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
2808 ast_free_ha(ha);
2809 continue;
2810 }
2811
2812 ast_copy_ha(ha, &tmp.ha);
2813 /* find or create the addr_range */
2816 found = 1;
2817 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
2818 ast_free_ha(ha);
2819 return; /* out of memory */
2820 }
2821
2822 /* copy over config data into addr_range object */
2823 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
2824 ast_free_ha(ha); /* cleanup the tmp ha */
2825 addr_range->limit = limit;
2826 addr_range->delme = 0;
2827
2828 /* cleanup */
2829 if (found) {
2831 } else {
2833 }
2834 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
2835 }
2836}
uint16_t limit
Definition: chan_iax2.c:1044

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

Referenced by set_config().

◆ build_context()

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

Definition at line 12815 of file chan_iax2.c.

12816{
12817 struct iax2_context *con;
12818
12819 if ((con = ast_calloc(1, sizeof(*con))))
12820 ast_copy_string(con->context, context, sizeof(con->context));
12821
12822 return con;
12823}

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

Referenced by build_user().

◆ build_ecx_key()

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

Definition at line 6465 of file chan_iax2.c.

6466{
6467 /* it is required to hold the corresponding decrypt key to our encrypt key
6468 * in the pvt struct because queued frames occasionally need to be decrypted and
6469 * re-encrypted when updated for a retransmission */
6470 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
6471 ast_aes_set_encrypt_key(digest, &pvt->ecx);
6472 ast_aes_set_decrypt_key(digest, &pvt->mydcx);
6473}
static void build_rand_pad(unsigned char *buf, ssize_t len)
Definition: chan_iax2.c:6433
int ast_aes_set_encrypt_key(const unsigned char *key, ast_aes_encrypt_key *ctx)
Set an encryption key.
Definition: res_crypto.c:700
int ast_aes_set_decrypt_key(const unsigned char *key, ast_aes_decrypt_key *ctx)
Set a decryption key.
Definition: res_crypto.c:709
unsigned char semirand[32]
Definition: chan_iax2.c:880
ast_aes_decrypt_key mydcx
Definition: chan_iax2.c:873

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

◆ build_encryption_keys()

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

Definition at line 6459 of file chan_iax2.c.

6460{
6461 build_ecx_key(digest, pvt);
6462 ast_aes_set_decrypt_key(digest, &pvt->dcx);
6463}
static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:6465

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

Referenced by authenticate(), and decrypt_frame().

◆ build_peer()

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

Create peer structure based on configuration.

Definition at line 12964 of file chan_iax2.c.

12965{
12966 struct iax2_peer *peer = NULL;
12967 struct ast_acl_list *oldacl = NULL;
12968 int maskfound = 0;
12969 int found = 0;
12970 int firstpass = 1;
12971 int subscribe_acl_change = 0;
12972
12973 if (!temponly) {
12974 peer = ao2_find(peers, name, OBJ_KEY);
12975 if (peer && !ast_test_flag64(peer, IAX_DELME))
12976 firstpass = 0;
12977 }
12978
12979 if (peer) {
12980 found++;
12981 if (firstpass) {
12982 oldacl = peer->acl;
12983 peer->acl = NULL;
12984 }
12985 unlink_peer(peer);
12986 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12987 peer->expire = -1;
12988 peer->pokeexpire = -1;
12989 peer->sockfd = defaultsockfd;
12990 if (ast_string_field_init(peer, 32))
12991 peer = peer_unref(peer);
12992 if (!(peer->endpoint = ast_endpoint_create("IAX2", name))) {
12993 peer = peer_unref(peer);
12994 }
12995 }
12996
12997 if (peer) {
12998 if (firstpass) {
13002 peer->adsi = adsi;
13003 ast_string_field_set(peer, secret, "");
13004 if (!found) {
13006 ast_sockaddr_parse(&peer->addr, "0.0.0.0", 0);
13008 peer->expiry = min_reg_expire;
13009 }
13010 peer->prefs = prefs_global;
13012 peer->smoothing = 0;
13015 peer->maxcallno = 0;
13016 peercnt_modify((unsigned char) 0, 0, &peer->addr);
13019 ast_string_field_set(peer,peercontext,"");
13021 ast_string_field_set(peer, cid_name, "");
13022 ast_string_field_set(peer, cid_num, "");
13025 }
13026
13027 if (!v) {
13028 v = alt;
13029 alt = NULL;
13030 }
13031 while(v) {
13032 if (!strcasecmp(v->name, "secret")) {
13033 ast_string_field_set(peer, secret, v->value);
13034 } else if (!strcasecmp(v->name, "mailbox")) {
13036 } else if (!strcasecmp(v->name, "hasvoicemail")) {
13037 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
13038 /*
13039 * hasvoicemail is a users.conf legacy voicemail enable method.
13040 * hasvoicemail is only going to work for app_voicemail mailboxes.
13041 */
13042 if (strchr(name, '@')) {
13044 } else {
13045 ast_string_field_build(peer, mailbox, "%s@default", name);
13046 }
13047 }
13048 } else if (!strcasecmp(v->name, "mohinterpret")) {
13050 } else if (!strcasecmp(v->name, "mohsuggest")) {
13052 } else if (!strcasecmp(v->name, "dbsecret")) {
13053 ast_string_field_set(peer, dbsecret, v->value);
13054 } else if (!strcasecmp(v->name, "description")) {
13055 ast_string_field_set(peer, description, v->value);
13056 } else if (!strcasecmp(v->name, "trunk")) {
13058 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
13059 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
13061 }
13062 } else if (!strcasecmp(v->name, "auth")) {
13064 if (peer->authmethods & IAX_AUTH_PLAINTEXT) {
13065 ast_log(LOG_WARNING, "Auth method for peer '%s' is set to deprecated 'plaintext' at line %d of iax.conf\n", peer->name, v->lineno);
13066 }
13067 } else if (!strcasecmp(v->name, "encryption")) {
13069 if (!peer->encmethods) {
13071 }
13072 } else if (!strcasecmp(v->name, "forceencryption")) {
13073 if (ast_false(v->value)) {
13075 } else {
13077 if (peer->encmethods) {
13079 }
13080 }
13081 } else if (!strcasecmp(v->name, "transfer")) {
13082 if (!strcasecmp(v->value, "mediaonly")) {
13084 } else if (ast_true(v->value)) {
13086 } else
13088 } else if (!strcasecmp(v->name, "jitterbuffer")) {
13090 } else if (!strcasecmp(v->name, "host")) {
13091 if (!strcasecmp(v->value, "dynamic")) {
13092 /* They'll register with us */
13094 if (!found) {
13095 int peer_port = ast_sockaddr_port(&peer->addr);
13096 if (peer_port) {
13097 ast_sockaddr_set_port(&peer->defaddr, peer_port);
13098 }
13099 ast_sockaddr_setnull(&peer->addr);
13100 }
13101 } else {
13102 /* Non-dynamic. Make sure we become that way if we're not */
13103 AST_SCHED_DEL(sched, peer->expire);
13105 if (peer->dnsmgr) {
13106 // Make sure we refresh dnsmgr if we're using it
13108 } else {
13109 // Or just invalidate the address
13110 peer->addr.ss.ss_family = AST_AF_UNSPEC;
13111 }
13112 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) {
13113 return peer_unref(peer);
13114 }
13115 if (!ast_sockaddr_port(&peer->addr)) {
13117 }
13118 }
13119 } else if (!strcasecmp(v->name, "defaultip")) {
13120 struct ast_sockaddr peer_defaddr_tmp;
13121 peer_defaddr_tmp.ss.ss_family = AF_UNSPEC;
13122 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
13123 return peer_unref(peer);
13124 }
13125 ast_sockaddr_set_port(&peer_defaddr_tmp, ast_sockaddr_port(&peer->defaddr));
13126 ast_sockaddr_copy(&peer->defaddr, &peer_defaddr_tmp);
13127 } else if (!strcasecmp(v->name, "sourceaddress")) {
13128 peer_set_srcaddr(peer, v->value);
13129 } else if (!strcasecmp(v->name, "permit") ||
13130 !strcasecmp(v->name, "deny") ||
13131 !strcasecmp(v->name, "acl")) {
13132 ast_append_acl(v->name, v->value, &peer->acl, NULL, &subscribe_acl_change);
13133 } else if (!strcasecmp(v->name, "mask")) {
13134 maskfound++;
13135 ast_sockaddr_parse(&peer->mask, v->value, 0);
13136 } else if (!strcasecmp(v->name, "context")) {
13138 } else if (!strcasecmp(v->name, "regexten")) {
13139 ast_string_field_set(peer, regexten, v->value);
13140 } else if (!strcasecmp(v->name, "peercontext")) {
13141 ast_string_field_set(peer, peercontext, v->value);
13142 } else if (!strcasecmp(v->name, "port")) {
13143 int bindport;
13144 if (ast_parse_arg(v->value, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535)) {
13145 bindport = IAX_DEFAULT_PORTNO;
13146 }
13147 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
13148 ast_sockaddr_set_port(&peer->defaddr, bindport);
13149 } else {
13150 ast_sockaddr_set_port(&peer->addr, bindport);
13151 }
13152 } else if (!strcasecmp(v->name, "username")) {
13153 ast_string_field_set(peer, username, v->value);
13154 } else if (!strcasecmp(v->name, "allow")) {
13155 iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
13156 } else if (!strcasecmp(v->name, "disallow")) {
13157 iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
13158 } else if (!strcasecmp(v->name, "callerid")) {
13159 if (!ast_strlen_zero(v->value)) {
13160 char name2[80];
13161 char num2[80];
13162 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
13163 ast_string_field_set(peer, cid_name, name2);
13164 ast_string_field_set(peer, cid_num, num2);
13165 } else {
13166 ast_string_field_set(peer, cid_name, "");
13167 ast_string_field_set(peer, cid_num, "");
13168 }
13170 } else if (!strcasecmp(v->name, "fullname")) {
13171 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
13173 } else if (!strcasecmp(v->name, "cid_number")) {
13174 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
13176 } else if (!strcasecmp(v->name, "sendani")) {
13178 } else if (!strcasecmp(v->name, "inkeys")) {
13179 ast_string_field_set(peer, inkeys, v->value);
13180 } else if (!strcasecmp(v->name, "outkey")) {
13181 ast_string_field_set(peer, outkey, v->value);
13182 } else if (!strcasecmp(v->name, "qualify")) {
13183 if (!strcasecmp(v->value, "no")) {
13184 peer->maxms = 0;
13185 } else if (!strcasecmp(v->value, "yes")) {
13186 peer->maxms = DEFAULT_MAXMS;
13187 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
13188 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);
13189 peer->maxms = 0;
13190 }
13191 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
13192 peer->smoothing = ast_true(v->value);
13193 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
13194 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
13195 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);
13196 }
13197 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
13198 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
13199 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);
13200 }
13201 } else if (!strcasecmp(v->name, "timezone")) {
13203 } else if (!strcasecmp(v->name, "adsi")) {
13204 peer->adsi = ast_true(v->value);
13205 } else if (!strcasecmp(v->name, "connectedline")) {
13206 if (ast_true(v->value)) {
13208 } else if (!strcasecmp(v->value, "send")) {
13211 } else if (!strcasecmp(v->value, "receive")) {
13214 } else {
13216 }
13217 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13218 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
13219 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
13220 } else {
13221 peercnt_modify((unsigned char) 1, peer->maxcallno, &peer->addr);
13222 }
13223 } else if (!strcasecmp(v->name, "requirecalltoken")) {
13224 /* default is required unless in optional ip list */
13225 if (ast_false(v->value)) {
13227 } else if (!strcasecmp(v->value, "auto")) {
13229 } else if (ast_true(v->value)) {
13231 } else {
13232 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13233 }
13234 } /* else if (strcasecmp(v->name,"type")) */
13235 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13236 v = v->next;
13237 if (!v) {
13238 v = alt;
13239 alt = NULL;
13240 }
13241 }
13242 if (!peer->authmethods)
13243 peer->authmethods = IAX_AUTH_MD5;
13245 }
13246
13247 if (!maskfound && !ast_sockaddr_isnull(&peer->addr)) {
13248 if (ast_sockaddr_is_ipv4_mapped(&peer->addr)) {
13249 ast_sockaddr_parse(&peer->mask, "::ffff:ffff:ffff", 0);
13250 } else if (ast_sockaddr_is_ipv6(&peer->addr)) {
13251 ast_sockaddr_parse(&peer->mask, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0);
13252 } else {
13253 ast_sockaddr_parse(&peer->mask, "255.255.255.255", 0);
13254 }
13255 }
13256
13257 if (oldacl) {
13258 ast_free_acl_list(oldacl);
13259 }
13260
13261 if (!ast_strlen_zero(peer->mailbox) && !peer->mwi_event_sub) {
13262 /* The MWI subscriptions exist just so the core knows we care about those
13263 * mailboxes. However, we just grab the events out of the cache when it
13264 * is time to send MWI, since it is only sent with a REGACK. */
13266 }
13267
13268 if (subscribe_acl_change) {
13270 }
13271
13272 return peer;
13273}
void ast_append_acl(const char *sense, const char *stuff, struct ast_acl_list **path, int *error, int *named_acl_flag)
Add a rule to an ACL struct.
Definition: acl.c:429
int ast_get_ip(struct ast_sockaddr *addr, const char *hostname)
Get the IP address given a hostname.
Definition: acl.c:999
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition: acl.c:233
static char zonetag[80]
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1292
static void acl_change_stasis_subscribe(void)
Definition: chan_iax2.c:1516
static int get_auth_methods(const char *value)
Definition: chan_iax2.c:12825
static iax2_format iax2_capability
Definition: chan_iax2.c:459
#define IAX_HASCALLERID
Definition: chan_iax2.c:498
#define IAX_SENDANI
Definition: chan_iax2.c:505
static int adsi
Definition: chan_iax2.c:477
#define DEFAULT_FREQ_OK
Definition: chan_iax2.c:395
static int iax2_authmethods
Definition: chan_iax2.c:480
#define DEFAULT_MAXMS
Definition: chan_iax2.c:394
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 defaultsoc...
Definition: chan_iax2.c:12866
#define DEFAULT_FREQ_NOTOK
Definition: chan_iax2.c:396
static int iax2_encryption
Definition: chan_iax2.c:479
static void peer_destructor(void *obj)
Definition: chan_iax2.c:12936
static int get_encrypt_methods(const char *s)
Definition: chan_iax2.c:1813
static struct iax2_codec_pref prefs_global
Definition: chan_iax2.c:308
static int iax2_parse_allow_disallow(struct iax2_codec_pref *pref, iax2_format *formats, const char *list, int allowing)
Definition: chan_iax2.c:1976
#define IAX_DELME
Definition: chan_iax2.c:499
static int defaultsockfd
Definition: chan_iax2.c:368
int ast_dnsmgr_refresh(struct ast_dnsmgr_entry *entry)
Force a refresh of a dnsmgr entry.
Definition: dnsmgr.c:239
struct ast_endpoint * ast_endpoint_create(const char *tech, const char *resource)
Create an endpoint struct.
#define IAX_DEFAULT_PORTNO
Definition: iax2.h:128
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *p_result,...)
The argument parsing routine.
Definition: main/config.c:3827
struct ast_mwi_subscriber * ast_mwi_subscribe_pool(const char *mailbox, stasis_subscription_cb callback, void *data)
Add an MWI state subscriber, and stasis subscription to the mailbox.
Definition: mwi.c:235
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
Definition: netsock2.c:507
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46
void stasis_subscription_cb_noop(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Stasis subscription callback function that does nothing.
Definition: stasis.c:809
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"....
Definition: utils.c:2216
Wrapper for an ast_acl linked list.
Definition: acl.h:76
int pokefreqok
Definition: chan_iax2.c:624
struct ast_dnsmgr_entry * dnsmgr
Definition: chan_iax2.c:601
struct ast_mwi_subscriber * mwi_event_sub
Definition: chan_iax2.c:630
enum calltoken_peer_enum calltoken_required
Definition: chan_iax2.c:633
iax2_format capability
Definition: chan_iax2.c:616
int adsi
Definition: chan_iax2.c:606
struct ast_sockaddr defaddr
Definition: chan_iax2.c:610
uint16_t maxcallno
Definition: chan_iax2.c:628
struct iax2_codec_pref prefs
Definition: chan_iax2.c:600
struct ast_acl_list * acl
Definition: chan_iax2.c:632
int maxms
Definition: chan_iax2.c:622
int sockfd
Definition: chan_iax2.c:604
int smoothing
Definition: chan_iax2.c:627
const ast_string_field mailbox
Definition: chan_iax2.c:599
#define ast_set2_flag64(p, value, flag)
Definition: utils.h:151
#define ast_set_flags_to64(p, flag, value)
Definition: utils.h:161

References iax2_peer::acl, acl_change_stasis_subscribe(), iax2_peer::addr, adsi, 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_dnsmgr_refresh(), ast_endpoint_create(), ast_false(), ast_free_acl_list(), ast_get_ip(), ast_log, ast_mwi_subscribe_pool(), 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, voicemailpwcheck::context, iax2_peer::defaddr, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, defaultsockfd, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::endpoint, iax2_peer::expire, iax2_peer::expiry, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_authmethods, iax2_capability, iax2_encryption, 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, voicemailpwcheck::mailbox, iax2_peer::mask, iax2_peer::maxcallno, iax2_peer::maxms, min_reg_expire, mohinterpret, mohsuggest, iax2_peer::mwi_event_sub, name, 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, srvlookup, ast_sockaddr::ss, stasis_subscription_cb_noop(), timer, unlink_peer(), ast_variable::value, and zonetag.

Referenced by realtime_peer(), and set_config().

◆ build_rand_pad()

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

Definition at line 6433 of file chan_iax2.c.

6434{
6435 long tmp;
6436 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
6437 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
6438 buf += sizeof(tmp);
6439 len -= sizeof(tmp);
6440 }
6441}

References ast_random(), buf, len(), and tmp().

Referenced by build_ecx_key(), and update_packet().

◆ build_user()

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

Create in-memory user structure from configuration.

Definition at line 13289 of file chan_iax2.c.

13290{
13291 struct iax2_user *user = NULL;
13292 struct iax2_context *con, *conl = NULL;
13293 struct ast_acl_list *oldacl = NULL;
13294 struct iax2_context *oldcon = NULL;
13295 int format;
13296 int firstpass=1;
13297 int oldcurauthreq = 0;
13298 int subscribe_acl_change = 0;
13299 char *varname = NULL, *varval = NULL;
13300 struct ast_variable *tmpvar = NULL;
13301
13302 if (!temponly) {
13305 firstpass = 0;
13306 }
13307
13308 if (user) {
13309 if (firstpass) {
13310 oldcurauthreq = user->curauthreq;
13311 oldacl = user->acl;
13312 oldcon = user->contexts;
13313 user->acl = NULL;
13314 user->contexts = NULL;
13315 }
13316 /* Already in the list, remove it and it will be added back (or FREE'd) */
13318 } else {
13319 user = ao2_alloc(sizeof(*user), user_destructor);
13320 }
13321
13322 if (user) {
13323 if (firstpass) {
13325 memset(user, 0, sizeof(struct iax2_user));
13326 if (ast_string_field_init(user, 32)) {
13327 user = user_unref(user);
13328 goto cleanup;
13329 }
13330 user->maxauthreq = maxauthreq;
13331 user->curauthreq = oldcurauthreq;
13332 user->prefs = prefs_global;
13333 user->capability = iax2_capability;
13334 user->encmethods = iax2_encryption;
13335 user->authmethods = iax2_authmethods;
13336 user->adsi = adsi;
13337 user->calltoken_required = CALLTOKEN_DEFAULT;
13342 ast_string_field_set(user, cid_name, "");
13343 ast_string_field_set(user, cid_num, "");
13347 }
13348 if (!v) {
13349 v = alt;
13350 alt = NULL;
13351 }
13352 while(v) {
13353 if (!strcasecmp(v->name, "context")) {
13354 con = build_context(v->value);
13355 if (con) {
13356 if (conl)
13357 conl->next = con;
13358 else
13359 user->contexts = con;
13360 conl = con;
13361 }
13362 } else if (!strcasecmp(v->name, "permit") ||
13363 !strcasecmp(v->name, "deny") ||
13364 !strcasecmp(v->name, "acl")) {
13365 ast_append_acl(v->name, v->value, &user->acl, NULL, &subscribe_acl_change);
13366 } else if (!strcasecmp(v->name, "setvar")) {
13367 varname = ast_strdupa(v->value);
13368 if ((varval = strchr(varname, '='))) {
13369 *varval = '\0';
13370 varval++;
13371 if ((tmpvar = ast_variable_new(varname, varval, ""))) {
13372 if (ast_variable_list_replace(&user->vars, tmpvar)) {
13373 tmpvar->next = user->vars;
13374 user->vars = tmpvar;
13375 }
13376 }
13377 }
13378 } else if (!strcasecmp(v->name, "allow")) {
13379 iax2_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
13380 } else if (!strcasecmp(v->name, "disallow")) {
13381 iax2_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
13382 } else if (!strcasecmp(v->name, "trunk")) {
13384 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
13385 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
13387 }
13388 } else if (!strcasecmp(v->name, "auth")) {
13389 user->authmethods = get_auth_methods(v->value);
13390 if (user->authmethods & IAX_AUTH_PLAINTEXT) {
13391 ast_log(LOG_WARNING, "Auth method for user '%s' is set to deprecated 'plaintext' at line %d of iax.conf\n", user->name, v->lineno);
13392 }
13393 } else if (!strcasecmp(v->name, "encryption")) {
13394 user->encmethods |= get_encrypt_methods(v->value);
13395 if (!user->encmethods) {
13397 }
13398 } else if (!strcasecmp(v->name, "forceencryption")) {
13399 if (ast_false(v->value)) {
13401 } else {
13402 user->encmethods |= get_encrypt_methods(v->value);
13403 if (user->encmethods) {
13405 }
13406 }
13407 } else if (!strcasecmp(v->name, "transfer")) {
13408 if (!strcasecmp(v->value, "mediaonly")) {
13410 } else if (ast_true(v->value)) {
13412 } else
13414 } else if (!strcasecmp(v->name, "codecpriority")) {
13415 if(!strcasecmp(v->value, "caller"))
13417 else if(!strcasecmp(v->value, "disabled"))
13419 else if(!strcasecmp(v->value, "reqonly")) {
13422 }
13423 } else if (!strcasecmp(v->name, "immediate")) {
13425 } else if (!strcasecmp(v->name, "jitterbuffer")) {
13427 } else if (!strcasecmp(v->name, "dbsecret")) {
13428 ast_string_field_set(user, dbsecret, v->value);
13429 } else if (!strcasecmp(v->name, "secret")) {
13430 if (!ast_strlen_zero(user->secret)) {
13431 char *old = ast_strdupa(user->secret);
13432
13433 ast_string_field_build(user, secret, "%s;%s", old, v->value);
13434 } else
13435 ast_string_field_set(user, secret, v->value);
13436 } else if (!strcasecmp(v->name, "callerid")) {
13437 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
13438 char name2[80];
13439 char num2[80];
13440 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
13441 ast_string_field_set(user, cid_name, name2);
13442 ast_string_field_set(user, cid_num, num2);
13444 } else {
13446 ast_string_field_set(user, cid_name, "");
13447 ast_string_field_set(user, cid_num, "");
13448 }
13449 } else if (!strcasecmp(v->name, "fullname")) {
13450 if (!ast_strlen_zero(v->value)) {
13451 ast_string_field_set(user, cid_name, v->value);
13453 } else {
13454 ast_string_field_set(user, cid_name, "");
13455 if (ast_strlen_zero(user->cid_num))
13457 }
13458 } else if (!strcasecmp(v->name, "cid_number")) {
13459 if (!ast_strlen_zero(v->value)) {
13460 ast_string_field_set(user, cid_num, v->value);
13462 } else {
13463 ast_string_field_set(user, cid_num, "");
13464 if (ast_strlen_zero(user->cid_name))
13466 }
13467 } else if (!strcasecmp(v->name, "accountcode")) {
13469 } else if (!strcasecmp(v->name, "mohinterpret")) {
13471 } else if (!strcasecmp(v->name, "mohsuggest")) {
13473 } else if (!strcasecmp(v->name, "parkinglot")) {
13474 ast_string_field_set(user, parkinglot, v->value);
13475 } else if (!strcasecmp(v->name, "language")) {
13477 } else if (!strcasecmp(v->name, "amaflags")) {
13478 format = ast_channel_string2amaflag(v->value);
13479 if (format < 0) {
13480 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13481 } else {
13482 user->amaflags = format;
13483 }
13484 } else if (!strcasecmp(v->name, "inkeys")) {
13485 ast_string_field_set(user, inkeys, v->value);
13486 } else if (!strcasecmp(v->name, "maxauthreq")) {
13487 user->maxauthreq = atoi(v->value);
13488 if (user->maxauthreq < 0)
13489 user->maxauthreq = 0;
13490 } else if (!strcasecmp(v->name, "adsi")) {
13491 user->adsi = ast_true(v->value);
13492 } else if (!strcasecmp(v->name, "connectedline")) {
13493 if (ast_true(v->value)) {
13495 } else if (!strcasecmp(v->value, "send")) {
13498 } else if (!strcasecmp(v->value, "receive")) {
13501 } else {
13503 }
13504 } else if (!strcasecmp(v->name, "requirecalltoken")) {
13505 /* default is required unless in optional ip list */
13506 if (ast_false(v->value)) {
13507 user->calltoken_required = CALLTOKEN_NO;
13508 } else if (!strcasecmp(v->value, "auto")) {
13509 user->calltoken_required = CALLTOKEN_AUTO;
13510 } else if (ast_true(v->value)) {
13511 user->calltoken_required = CALLTOKEN_YES;
13512 } else {
13513 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13514 }
13515 } /* else if (strcasecmp(v->name,"type")) */
13516 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13517 v = v->next;
13518 if (!v) {
13519 v = alt;
13520 alt = NULL;
13521 }
13522 }
13523 if (!user->authmethods) {
13524 if (!ast_strlen_zero(user->secret)) {
13525 user->authmethods = IAX_AUTH_MD5;
13526 if (!ast_strlen_zero(user->inkeys))
13527 user->authmethods |= IAX_AUTH_RSA;
13528 } else if (!ast_strlen_zero(user->inkeys)) {
13529 user->authmethods = IAX_AUTH_RSA;
13530 } else {
13531 user->authmethods = IAX_AUTH_MD5;
13532 }
13533 }
13535 }
13536cleanup:
13537 if (oldacl) {
13538 ast_free_acl_list(oldacl);
13539 }
13540 if (oldcon) {
13541 free_context(oldcon);
13542 }
13543
13544 if (subscribe_acl_change) {
13546 }
13547
13548 return user;
13549}
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578
static struct iax2_context * build_context(const char *context)
Definition: chan_iax2.c:12815
#define IAX_CODEC_NOCAP
Definition: chan_iax2.c:514
#define IAX_IMMEDIATE
Definition: chan_iax2.c:524
static void user_destructor(void *obj)
Definition: chan_iax2.c:13275
static void free_context(struct iax2_context *con)
Definition: chan_iax2.c:12616
static int maxauthreq
Definition: chan_iax2.c:331
static char language[MAX_LANGUAGE]
Definition: chan_iax2.c:324
#define IAX_CODEC_USER_FIRST
Definition: chan_iax2.c:512
#define IAX_CODEC_NOPREFS
Definition: chan_iax2.c:513
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
Definition: channel.c:4360
#define ast_variable_new(name, value, filename)
int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *replacement)
Replace a variable in the given list with a new value.
Definition: main/config.c:667
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

References accountcode, acl_change_stasis_subscribe(), adsi, 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_list_replace(), ast_variable_new, build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cleanup(), free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, iax2_authmethods, iax2_capability, iax2_encryption, 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, language, ast_variable::lineno, LOG_WARNING, maxauthreq, mohinterpret, mohsuggest, name, ast_variable::name, iax2_context::next, ast_variable::next, NULL, OBJ_KEY, prefs_global, timer, user, user_destructor(), user_unref(), and ast_variable::value.

Referenced by realtime_user(), and set_config().

◆ cache_get_callno_locked()

static int cache_get_callno_locked ( const char *  data)
static

Definition at line 14234 of file chan_iax2.c.

14235{
14236 struct ast_sockaddr addr;
14237 int x;
14238 int callno;
14239 struct iax_ie_data ied;
14240 struct create_addr_info cai;
14241 struct parsed_dial_string pds;
14242 char *tmpstr;
14243
14244 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14245 /* Look for an *exact match* call. Once a call is negotiated, it can only
14246 look up entries for a single context */
14247 if (!ast_mutex_trylock(&iaxsl[x])) {
14248 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
14249 return x;
14251 }
14252 }
14253
14254 /* No match found, we need to create a new one */
14255
14256 memset(&cai, 0, sizeof(cai));
14257 memset(&ied, 0, sizeof(ied));
14258 memset(&pds, 0, sizeof(pds));
14259
14260 tmpstr = ast_strdupa(data);
14261 parse_dial_string(tmpstr, &pds);
14262
14263 if (ast_strlen_zero(pds.peer)) {
14264 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
14265 return -1;
14266 }
14267
14268 /* Populate our address from the given */
14269 if (create_addr(pds.peer, NULL, &addr, &cai))
14270 return -1;
14271
14272 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
14273 pds.peer, pds.username, pds.password, pds.context);
14274
14275 callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
14276 if (callno < 1) {
14277 ast_log(LOG_WARNING, "Unable to create call\n");
14278 return -1;
14279 }
14280
14281 ast_string_field_set(iaxs[callno], dproot, data);
14283
14286 /* the string format is slightly different from a standard dial string,
14287 because the context appears in the 'exten' position
14288 */
14289 if (pds.exten)
14290 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
14291 if (pds.username)
14292 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
14295 /* Keep password handy */
14296 if (pds.password)
14297 ast_string_field_set(iaxs[callno], secret, pds.password);
14298 if (pds.key)
14299 ast_string_field_set(iaxs[callno], outkey, pds.key);
14300 /* Start the call going */
14301 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
14302 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
14303
14304 return callno;
14305}
static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, int new, int sockfd, int full_frame)
Definition: chan_iax2.c:3285
#define IAX_CAPABILITY_FULLBANDWIDTH
Definition: chan_iax2.c:373
static void parse_dial_string(char *data, struct parsed_dial_string *pds)
Parses an IAX dial string into its component parts.
Definition: chan_iax2.c:5092
static int create_addr(const char *peername, struct ast_channel *c, struct ast_sockaddr *addr, struct create_addr_info *cai)
Definition: chan_iax2.c:4666
static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
Definition: chan_iax2.c:4858
@ IAX_COMMAND_NEW
Definition: iax2.h:52
#define IAX_IE_FORMAT
Definition: iax2.h:139
#define IAX_IE_CALLED_NUMBER
Definition: iax2.h:131
#define IAX_IE_CAPABILITY
Definition: iax2.h:138
#define IAX_PROTO_VERSION
Definition: iax2.h:27
#define IAX_IE_VERSION
Definition: iax2.h:141
#define IAX_IE_CALLED_CONTEXT
Definition: iax2.h:135
#define ast_mutex_trylock(a)
Definition: lock.h:191
int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value)
Definition: parser.c:756

References add_empty_calltoken_ie(), ARRAY_LEN, ast_debug, AST_FRAME_IAX, ast_log, ast_mutex_trylock, ast_mutex_unlock, ast_strdupa, ast_string_field_set, ast_strlen_zero(), iax_ie_data::buf, chan_iax2_pvt::capability, parsed_dial_string::context, create_addr(), parsed_dial_string::exten, find_callno_locked(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, iaxs, iaxsl, parsed_dial_string::key, LOG_WARNING, NEW_FORCE, 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().

◆ calc_rxstamp()

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

Definition at line 6284 of file chan_iax2.c.

6285{
6286 /* Returns where in "receive time" we are. That is, how many ms
6287 since we received (or would have received) the frame with timestamp 0 */
6288 int ms;
6289#ifdef IAXTESTS
6290 int jit;
6291#endif /* IAXTESTS */
6292 /* Setup rxcore if necessary */
6293 if (ast_tvzero(p->rxcore)) {
6294 p->rxcore = ast_tvnow();
6295 if (iaxdebug)
6296 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %ums\n",
6297 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
6298 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
6299#if 1
6300 if (iaxdebug)
6301 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
6302 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
6303#endif
6304 }
6305
6306 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
6307#ifdef IAXTESTS
6308 if (test_jit) {
6309 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
6310 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
6311 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
6312 jit = -jit;
6313 ms += jit;
6314 }
6315 }
6316 if (test_late) {
6317 ms += test_late;
6318 test_late = 0;
6319 }
6320#endif /* IAXTESTS */
6321 return ms;
6322}
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2297

References ast_debug, ast_random(), ast_samp2tv(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, iaxdebug, and chan_iax2_pvt::rxcore.

Referenced by schedule_delivery().

◆ calc_timestamp()

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

Definition at line 6149 of file chan_iax2.c.

6150{
6151 int ms;
6152 int voice = 0;
6153 int genuine = 0;
6154 int adjust;
6155 int rate = 0;
6156 struct timeval *delivery = NULL;
6157
6158
6159 /* What sort of frame do we have?: voice is self-explanatory
6160 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
6161 non-genuine frames are CONTROL frames [ringing etc], DTMF
6162 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
6163 the others need a timestamp slaved to the voice frames so that they go in sequence
6164 */
6165 if (f->frametype == AST_FRAME_VOICE) {
6166 voice = 1;
6167 rate = ast_format_get_sample_rate(f->subclass.format) / 1000;
6168 delivery = &f->delivery;
6169 } else if (f->frametype == AST_FRAME_IAX) {
6170 genuine = 1;
6171 } else if (f->frametype == AST_FRAME_CNG) {
6172 p->notsilenttx = 0;
6173 }
6174
6175 if (ast_tvzero(p->offset)) {
6176 p->offset = ast_tvnow();
6177 /* Round to nearest 20ms for nice looking traces */
6178 p->offset.tv_usec -= p->offset.tv_usec % 20000;
6179 }
6180 /* If the timestamp is specified, just send it as is */
6181 if (ts)
6182 return ts;
6183 /* If we have a time that the frame arrived, always use it to make our timestamp */
6184 if (delivery && !ast_tvzero(*delivery)) {
6185 ms = ast_tvdiff_ms(*delivery, p->offset);
6186 if (ms < 0) {
6187 ms = 0;
6188 }
6189 if (iaxdebug)
6190 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
6191 } else {
6192 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
6193 if (ms < 0)
6194 ms = 0;
6195 if (voice) {
6196 /* On a voice frame, use predicted values if appropriate */
6197 adjust = (ms - p->nextpred);
6198 if (p->notsilenttx && abs(adjust) <= MAX_TIMESTAMP_SKEW) {
6199 /* Adjust our txcore, keeping voice and non-voice synchronized */
6200 /* AN EXPLANATION:
6201 When we send voice, we usually send "calculated" timestamps worked out
6202 on the basis of the number of samples sent. When we send other frames,
6203 we usually send timestamps worked out from the real clock.
6204 The problem is that they can tend to drift out of step because the
6205 source channel's clock and our clock may not be exactly at the same rate.
6206 We fix this by continuously "tweaking" p->offset. p->offset is "time zero"
6207 for this call. Moving it adjusts timestamps for non-voice frames.
6208 We make the adjustment in the style of a moving average. Each time we
6209 adjust p->offset by 10% of the difference between our clock-derived
6210 timestamp and the predicted timestamp. That's why you see "10000"
6211 below even though IAX2 timestamps are in milliseconds.
6212 The use of a moving average avoids offset moving too radically.
6213 Generally, "adjust" roams back and forth around 0, with offset hardly
6214 changing at all. But if a consistent different starts to develop it
6215 will be eliminated over the course of 10 frames (200-300msecs)
6216 */
6217 if (adjust < 0)
6218 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
6219 else if (adjust > 0)
6220 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
6221
6222 if (!p->nextpred) {
6223 p->nextpred = ms; /*f->samples / rate;*/
6224 if (p->nextpred <= p->lastsent)
6225 p->nextpred = p->lastsent + 3;
6226 }
6227 ms = p->nextpred;
6228 } else {
6229 /* in this case, just use the actual
6230 * time, since we're either way off
6231 * (shouldn't happen), or we're ending a
6232 * silent period -- and seed the next
6233 * predicted time. Also, round ms to the
6234 * next multiple of frame size (so our
6235 * silent periods are multiples of
6236 * frame size too) */
6237
6238 if (iaxdebug && abs(adjust) > MAX_TIMESTAMP_SKEW )
6239 ast_debug(1, "predicted timestamp skew (%d) > max (%d), using real ts instead.\n",
6240 abs(adjust), MAX_TIMESTAMP_SKEW);
6241
6242 if (f->samples >= rate) /* check to make sure we don't core dump */
6243 {
6244 int diff = ms % (f->samples / rate);
6245 if (diff)
6246 ms += f->samples/rate - diff;
6247 }
6248
6249 p->nextpred = ms;
6250 p->notsilenttx = 1;
6251 }
6252 } else if ( f->frametype == AST_FRAME_VIDEO ) {
6253 /*
6254 * IAX2 draft 03 says that timestamps MUST be in order.
6255 * It does not say anything about several frames having the same timestamp
6256 * When transporting video, we can have a frame that spans multiple iax packets
6257 * (so called slices), so it would make sense to use the same timestamp for all of
6258 * them
6259 * We do want to make sure that frames don't go backwards though
6260 */
6261 if ( (unsigned int)ms < p->lastsent )
6262 ms = p->lastsent;
6263 } else {
6264 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
6265 it's a genuine frame */
6266 adjust = (ms - p->lastsent);
6267 if (genuine) {
6268 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
6269 if (ms <= p->lastsent)
6270 ms = p->lastsent + 3;
6271 } else if (abs(adjust) <= MAX_TIMESTAMP_SKEW) {
6272 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
6273 ms = p->lastsent + 3;
6274 }
6275 }
6276 }
6277 p->lastsent = ms;
6278 if (voice) {
6279 p->nextpred = p->nextpred + f->samples / rate;
6280 }
6281 return ms;
6282}
#define MAX_TIMESTAMP_SKEW
Definition: chan_iax2.c:712
@ AST_FRAME_VIDEO
unsigned int lastsent
Definition: chan_iax2.c:760
unsigned int nextpred
Definition: chan_iax2.c:764
unsigned int notsilenttx
Definition: chan_iax2.c:770
struct timeval offset
Definition: chan_iax2.c:796

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, iaxdebug, iaxs, 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().

◆ calc_txpeerstamp()

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

Definition at line 6105 of file chan_iax2.c.

6106{
6107 unsigned long int mssincetx; /* unsigned to handle overflows */
6108 long int ms, pred;
6109
6110 tpeer->trunkact = *now;
6111 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
6112 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
6113 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
6114 tpeer->txtrunktime = *now;
6115 tpeer->lastsent = 999999;
6116 }
6117 /* Update last transmit time now */
6118 tpeer->lasttxtime = *now;
6119
6120 /* Calculate ms offset */
6121 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
6122 /* Predict from last value */
6123 pred = tpeer->lastsent + sampms;
6124 if (labs(ms - pred) < MAX_TIMESTAMP_SKEW)
6125 ms = pred;
6126
6127 /* We never send the same timestamp twice, so fudge a little if we must */
6128 if (ms == tpeer->lastsent)
6129 ms = tpeer->lastsent + 1;
6130 tpeer->lastsent = ms;
6131 return ms;
6132}
struct timeval lasttxtime
Definition: chan_iax2.c:646
unsigned int lastsent
Definition: chan_iax2.c:648
struct timeval trunkact
Definition: chan_iax2.c:647
struct timeval txtrunktime
Definition: chan_iax2.c:644

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

◆ calltoken_required()

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

Definition at line 2541 of file chan_iax2.c.

2542{
2543 struct addr_range *addr_range;
2544 struct iax2_peer *peer = NULL;
2545 struct iax2_user *user = NULL;
2546 /* if no username is given, check for guest accounts */
2547 const char *find = S_OR(name, "guest");
2548 int res = 1; /* required by default */
2549 int optional = 0;
2551 /* There are only two cases in which calltoken validation is not required.
2552 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
2553 * the peer definition has not set the requirecalltoken option.
2554 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
2555 */
2556
2557 /* ----- Case 1 ----- */
2559 ao2_ref(addr_range, -1);
2560 optional = 1;
2561 }
2562
2563 /* ----- Case 2 ----- */
2564 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
2565 calltoken_required = user->calltoken_required;
2566 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, addr))) {
2567 calltoken_required = user->calltoken_required;
2568 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
2570 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, addr))) {
2572 }
2573
2574 if (peer) {
2575 peer_unref(peer);
2576 }
2577 if (user) {
2579 }
2580
2581 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);
2583 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
2584 res = 0;
2585 }
2586
2587 return res;
2588}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
static int addr_range_match_address_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:2522
static int calltoken_required(struct ast_sockaddr *addr, const char *name, int subclass)
Definition: chan_iax2.c:2541
static struct iax2_user * find_user(const char *name)
Definition: chan_iax2.c:2081
calltoken_peer_enum
Call token validation settings.
Definition: chan_iax2.c:536
static struct iax2_user * realtime_user(const char *username, struct ast_sockaddr *addr)
Definition: chan_iax2.c:4549

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

Referenced by calltoken_required(), and handle_call_token().

◆ check_access()

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

Definition at line 7887 of file chan_iax2.c.

7888{
7889 /* Start pessimistic */
7890 int res = -1;
7891 int version = 2;
7892 struct iax2_user *user = NULL, *best = NULL;
7893 int bestscore = 0;
7894 int gotcapability = 0;
7895 struct ast_variable *v = NULL, *tmpvar = NULL;
7896 struct ao2_iterator i;
7897
7898 if (!iaxs[callno])
7899 return res;
7900 if (ies->called_number)
7901 ast_string_field_set(iaxs[callno], exten, ies->called_number);
7902 if (ies->calling_number) {
7905 }
7906 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
7907 }
7908 if (ies->calling_name)
7909 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
7910 if (ies->calling_ani)
7911 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
7912 if (ies->dnid)
7913 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
7914 if (ies->rdnis)
7915 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
7916 if (ies->called_context)
7918 if (ies->language)
7920 if (ies->username)
7921 ast_string_field_set(iaxs[callno], username, ies->username);
7922 if (ies->calling_ton > -1)
7923 iaxs[callno]->calling_ton = ies->calling_ton;
7924 if (ies->calling_tns > -1)
7925 iaxs[callno]->calling_tns = ies->calling_tns;
7926 if (ies->calling_pres > -1)
7927 iaxs[callno]->calling_pres = ies->calling_pres;
7928 if (ies->calling_ani2 > -1)
7929 iaxs[callno]->calling_ani2 = ies->calling_ani2;
7930 if (ies->format)
7931 iaxs[callno]->peerformat = ies->format;
7932 if (ies->adsicpe)
7933 iaxs[callno]->peeradsicpe = ies->adsicpe;
7934 if (ies->capability) {
7935 gotcapability = 1;
7936 iaxs[callno]->peercapability = ies->capability;
7937 }
7938 if (ies->version)
7939 version = ies->version;
7940
7941 /* Use provided preferences until told otherwise for actual preferences */
7942 if (ies->codec_prefs) {
7943 iax2_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
7944 } else {
7945 memset(&iaxs[callno]->rprefs, 0, sizeof(iaxs[callno]->rprefs));
7946 }
7947 iaxs[callno]->prefs = iaxs[callno]->rprefs;
7948
7949 if (!gotcapability) {
7950 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
7951 }
7952 if (version > IAX_PROTO_VERSION) {
7953 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
7955 return res;
7956 }
7957 /* Search the userlist for a compatible entry, and fill in the rest */
7958 i = ao2_iterator_init(users, 0);
7959 while ((user = ao2_iterator_next(&i))) {
7960 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */
7961 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
7962 && (ast_apply_acl(user->acl, addr, "IAX2 user ACL: ") == AST_SENSE_ALLOW) /* Access is permitted from this IP */
7963 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */
7964 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */
7965 if (!ast_strlen_zero(iaxs[callno]->username)) {
7966 /* Exact match, stop right now. */
7967 if (best)
7968 user_unref(best);
7969 best = user;
7970 break;
7971 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
7972 /* No required authentication */
7973 if (user->acl) {
7974 /* There was host authentication and we passed, bonus! */
7975 if (bestscore < 4) {
7976 bestscore = 4;
7977 if (best)
7978 user_unref(best);
7979 best = user;
7980 continue;
7981 }
7982 } else {
7983 /* No host access, but no secret, either, not bad */
7984 if (bestscore < 3) {
7985 bestscore = 3;
7986 if (best)
7987 user_unref(best);
7988 best = user;
7989 continue;
7990 }
7991 }
7992 } else {
7993 if (user->acl) {
7994 /* Authentication, but host access too, eh, it's something.. */
7995 if (bestscore < 2) {
7996 bestscore = 2;
7997 if (best)
7998 user_unref(best);
7999 best = user;
8000 continue;
8001 }
8002 } else {
8003 /* Authentication and no host access... This is our baseline */
8004 if (bestscore < 1) {
8005 bestscore = 1;
8006 if (best)
8007 user_unref(best);
8008 best = user;
8009 continue;
8010 }
8011 }
8012 }
8013 }
8015 }
8017 user = best;
8018 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
8019 user = realtime_user(iaxs[callno]->username, addr);
8020 if (user && (ast_apply_acl(user->acl, addr, "IAX2 user ACL: ") == AST_SENSE_DENY /* Access is denied from this IP */
8021 || (!ast_strlen_zero(iaxs[callno]->context) && /* No context specified */
8022 !apply_context(user->contexts, iaxs[callno]->context)))) { /* Context is permitted */
8023 user = user_unref(user);
8024 }
8025 }
8026 if (user) {
8027 /* We found our match (use the first) */
8028 /* copy vars */
8029 for (v = user->vars ; v ; v = v->next) {
8030 if ((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
8031 if (ast_variable_list_replace(&iaxs[callno]->vars, tmpvar)) {
8032 tmpvar->next = iaxs[callno]->vars;
8033 iaxs[callno]->vars = tmpvar;
8034 }
8035 }
8036 }
8037 /* If a max AUTHREQ restriction is in place, activate it */
8038 if (user->maxauthreq > 0)
8040 iaxs[callno]->prefs = user->prefs;
8042 iaxs[callno]->encmethods = user->encmethods;
8043 /* Store the requested username if not specified */
8044 if (ast_strlen_zero(iaxs[callno]->username))
8045 ast_string_field_set(iaxs[callno], username, user->name);
8046 /* Store whether this is a trunked call, too, of course, and move if appropriate */
8048 iaxs[callno]->capability = user->capability;
8049 /* And use the default context */
8050 if (ast_strlen_zero(iaxs[callno]->context)) {
8051 if (user->contexts)
8052 ast_string_field_set(iaxs[callno], context, user->contexts->context);
8053 else
8055 }
8056 /* And any input keys */
8057 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
8058 /* And the permitted authentication methods */
8059 iaxs[callno]->authmethods = user->authmethods;
8060 iaxs[callno]->adsi = user->adsi;
8061 /* If the user has callerid, override the remote caller id. */
8063 iaxs[callno]->calling_tns = 0;
8064 iaxs[callno]->calling_ton = 0;
8065 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
8066 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
8067 ast_string_field_set(iaxs[callno], ani, user->cid_num);
8069 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
8071 } /* else user is allowed to set their own CID settings */
8072 if (!ast_strlen_zero(user->accountcode))
8073 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
8074 if (!ast_strlen_zero(user->mohinterpret))
8075 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
8076 if (!ast_strlen_zero(user->mohsuggest))
8077 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
8078 if (!ast_strlen_zero(user->parkinglot))
8079 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
8080 if (user->amaflags)
8081 iaxs[callno]->amaflags = user->amaflags;
8082 if (!ast_strlen_zero(user->language))
8083 ast_string_field_set(iaxs[callno], language, user->language);
8085 /* Keep this check last */
8086 if (!ast_strlen_zero(user->dbsecret)) {
8087 char *family, *key=NULL;
8088 char buf[80];
8089 family = ast_strdupa(user->dbsecret);
8090 key = strchr(family, '/');
8091 if (key) {
8092 *key = '\0';
8093 key++;
8094 }
8095 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
8096 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
8097 else
8098 ast_string_field_set(iaxs[callno], secret, buf);
8099 } else
8100 ast_string_field_set(iaxs[callno], secret, user->secret);
8101 res = 0;
8102 user = user_unref(user);
8103 } else {
8104 /* user was not found, but we should still fake an AUTHREQ.
8105 * Set authmethods to the last known authmethod used by the system
8106 * Set a fake secret, it's not looked at, just required to attempt authentication.
8107 * Set authrej so the AUTHREP is rejected without even looking at its contents */
8109 ast_string_field_set(iaxs[callno], secret, "badsecret");
8110 iaxs[callno]->authrej = 1;
8111 if (!ast_strlen_zero(iaxs[callno]->username)) {
8112 /* only send the AUTHREQ if a username was specified. */
8113 res = 0;
8114 }
8115 }
8117 return res;
8118}
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Definition: acl.c:799
@ AST_SENSE_ALLOW
Definition: acl.h:38
@ AST_SENSE_DENY
Definition: acl.h:37
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Definition: main/db.c:427
#define AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:440
#define AST_PRES_NUMBER_NOT_AVAILABLE
Definition: callerid.h:461
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s,...
Definition: callerid.c:1101
static int apply_context(struct iax2_context *con, const char *context)
Definition: chan_iax2.c:7876
#define IAX_SHRINKCALLERID
Definition: chan_iax2.c:528
static int last_authmethod
Definition: chan_iax2.c:348
static int iax2_getpeertrunk(struct ast_sockaddr addr)
Definition: chan_iax2.c:5884
#define DEFAULT_CONTEXT
Definition: chan_iax2.c:320
static char version[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:391
void iax2_codec_pref_convert(struct iax2_codec_pref *pref, char *buf, size_t size, int right)
Shift an audio codec preference list up or down 65 bytes so that it becomes an ASCII string.
Definition: codec_pref.c:44
iax2_format peercapability
Definition: chan_iax2.c:794
struct iax2_codec_pref prefs
Definition: chan_iax2.c:778
struct iax2_codec_pref rprefs
Definition: chan_iax2.c:780
unsigned short adsicpe
Definition: parser.h:44
int calling_ani2
Definition: parser.h:35
char * dnid
Definition: parser.h:45
char * calling_name
Definition: parser.h:31
iax2_format capability
Definition: parser.h:39
char * called_context
Definition: parser.h:36
char * calling_number
Definition: parser.h:29
char * calling_ani
Definition: parser.h:30
int calling_ton
Definition: parser.h:32
int calling_tns
Definition: parser.h:33
char * called_number
Definition: parser.h:28
char * language
Definition: parser.h:42
char * codec_prefs
Definition: parser.h:41
iax2_format format
Definition: parser.h:40
int calling_pres
Definition: parser.h:34
int version
Definition: parser.h:43
char * rdnis
Definition: parser.h:46

References accountcode, chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::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_list_replace(), ast_variable_new, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, buf, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, chan_iax2_pvt::calling_ani2, iax_ies::calling_ani2, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, chan_iax2_pvt::capability, iax_ies::capability, iax_ies::codec_prefs, chan_iax2_pvt::context, voicemailpwcheck::context, DEFAULT_CONTEXT, iax_ies::dnid, chan_iax2_pvt::encmethods, ast_variable::file, iax_ies::format, globalflags, iax2_codec_pref_convert(), iax2_getpeertrunk(), IAX_AUTH_MD5, 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, iaxs, language, iax_ies::language, last_authmethod, LOG_WARNING, mohinterpret, mohsuggest, ast_variable::name, ast_variable::next, NULL, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, chan_iax2_pvt::prefs, iax_ies::rdnis, realtime_user(), chan_iax2_pvt::rprefs, user, user_unref(), iax_ies::username, ast_variable::value, chan_iax2_pvt::vars, version, and iax_ies::version.

Referenced by socket_process_helper().

◆ check_provisioning()

static int check_provisioning ( struct ast_sockaddr addr,
int  sockfd,
char *  si,
unsigned int  ver 
)
static

Definition at line 9741 of file chan_iax2.c.

9742{
9743 unsigned int ourver;
9744 char rsi[80];
9745 snprintf(rsi, sizeof(rsi), "si-%s", si);
9746 if (iax_provision_version(&ourver, rsi, 1))
9747 return 0;
9748 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
9749 if (ourver != ver)
9750 iax2_provision(addr, sockfd, NULL, rsi, 1);
9751 return 0;
9752}
static int iax2_provision(struct ast_sockaddr *end, int sockfd, const char *dest, const char *template, int force)
Definition: chan_iax2.c:12365
int iax_provision_version(unsigned int *signature, const char *template, int force)
Definition: provision.c:258

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

Referenced by socket_process_helper().

◆ check_srcaddr()

static int check_srcaddr ( struct ast_sockaddr addr)
static

Check if address can be used as packet source.

Return values
0address available
1address unavailable
-1error

Definition at line 12843 of file chan_iax2.c.

12844{
12845 int sd;
12846
12847 sd = socket(addr->ss.ss_family, SOCK_DGRAM, 0);
12848 if (sd < 0) {
12849 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12850 return -1;
12851 }
12852
12853 if (ast_bind(sd, addr) < 0) {
12854 ast_debug(1, "Can't bind: %s\n", strerror(errno));
12855 close(sd);
12856 return 1;
12857 }
12858
12859 close(sd);
12860 return 0;
12861}
int errno
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition: netsock2.c:590

References ast_bind(), ast_debug, ast_log, errno, LOG_ERROR, and ast_sockaddr::ss.

Referenced by peer_set_srcaddr().

◆ cleanup_thread_list()

static void cleanup_thread_list ( void *  head)
static

Definition at line 14743 of file chan_iax2.c.

14744{
14745 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14746 struct iax2_thread_list *list_head = head;
14747 struct iax2_thread *thread;
14748
14749 AST_LIST_LOCK(list_head);
14750 while ((thread = AST_LIST_REMOVE_HEAD(list_head, list))) {
14751 pthread_t thread_id = thread->threadid;
14752
14753 thread->stop = 1;
14754 signal_condition(&thread->lock, &thread->cond);
14755
14756 AST_LIST_UNLOCK(list_head);
14757 pthread_join(thread_id, NULL);
14758 AST_LIST_LOCK(list_head);
14759 }
14760 AST_LIST_UNLOCK(list_head);
14761}
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
struct iax2_thread::@127 list

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

Referenced by __unload_module().

◆ codec_choose_from_prefs()

static struct ast_format * codec_choose_from_prefs ( struct iax2_codec_pref pref,
struct ast_format_cap cap 
)
static

Definition at line 1894 of file chan_iax2.c.

1895{
1896 int x;
1897 struct ast_format *found_format = NULL;
1898
1899 for (x = 0; x < ARRAY_LEN(pref->order); ++x) {
1900 struct ast_format *pref_format;
1901 uint64_t pref_bitfield;
1902
1903 pref_bitfield = iax2_codec_pref_order_value_to_format_bitfield(pref->order[x]);
1904 if (!pref_bitfield) {
1905 break;
1906 }
1907
1908 pref_format = ast_format_compatibility_bitfield2format(pref_bitfield);
1909 if (!pref_format) {
1910 /* The bitfield is not associated with any format. */
1911 continue;
1912 }
1913 found_format = ast_format_cap_get_compatible_format(cap, pref_format);
1914 if (found_format) {
1915 break;
1916 }
1917 }
1918
1919 if (found_format && (ast_format_get_type(found_format) == AST_MEDIA_TYPE_AUDIO)) {
1920 return found_format;
1921 }
1922
1923 ast_debug(4, "Could not find preferred codec - Returning zero codec.\n");
1924 ao2_cleanup(found_format);
1925 return NULL;
1926}
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
uint64_t iax2_codec_pref_order_value_to_format_bitfield(int order_value)
Convert an iax2_codec_pref order value into a format bitfield.
Definition: codec_pref.c:367
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
struct ast_format * ast_format_cap_get_compatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if input ast_format is within the capabilities of the ast_format_cap object then return the comp...
Definition: format_cap.c:546
char order[IAX2_CODEC_PREF_SIZE]
Definition: codec_pref.h:36

References ao2_cleanup, ARRAY_LEN, ast_debug, ast_format_cap_get_compatible_format(), ast_format_compatibility_bitfield2format(), ast_format_get_type(), AST_MEDIA_TYPE_AUDIO, iax2_codec_pref_order_value_to_format_bitfield(), NULL, and iax2_codec_pref::order.

Referenced by iax2_codec_choose().

◆ complete_dpreply()

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

Definition at line 8744 of file chan_iax2.c.

8745{
8746 char exten[256] = "";
8747 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
8748 struct iax2_dpcache *dp = NULL;
8749
8750 if (ies->called_number)
8751 ast_copy_string(exten, ies->called_number, sizeof(exten));
8752
8753 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
8755 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
8757 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
8759
8760 if (ies->refresh)
8761 expiry = ies->refresh;
8764
8767 if (strcmp(dp->exten, exten))
8768 continue;
8770 dp->callno = 0;
8771 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
8772 if (dp->flags & CACHE_FLAG_PENDING) {
8773 dp->flags &= ~CACHE_FLAG_PENDING;
8774 dp->flags |= status;
8775 dp->flags |= matchmore;
8776 }
8777 /* Wake up waiters */
8778 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
8779 if (dp->waiters[x] > -1) {
8780 if (write(dp->waiters[x], "asdf", 4) < 0) {
8781 }
8782 }
8783 }
8784 }
8787
8788 return 0;
8789}
static int iaxdefaultdpcache
Definition: chan_iax2.c:350
#define IAX_DPSTATUS_CANEXIST
Definition: iax2.h:218
#define IAX_DPSTATUS_NONEXISTENT
Definition: iax2.h:219
#define IAX_DPSTATUS_MATCHMORE
Definition: iax2.h:221
#define IAX_DPSTATUS_EXISTS
Definition: iax2.h:217
static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Definition: pbx_lua.c:1386
struct iax2_dpcache::@125 peer_list
int waiters[256]
Definition: chan_iax2.c:1075
struct timeval expiry
Definition: chan_iax2.c:1072
char exten[AST_MAX_EXTENSION]
Definition: chan_iax2.c:1070
unsigned short callno
Definition: chan_iax2.c:1074
struct timeval orig
Definition: chan_iax2.c:1071
unsigned short dpstatus
Definition: parser.h:54
unsigned short refresh
Definition: parser.h:53

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

Referenced by socket_process_helper().

◆ complete_iax2_peers()

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

Definition at line 3938 of file chan_iax2.c.

3939{
3940 int which = 0;
3941 struct iax2_peer *peer;
3942 char *res = NULL;
3943 int wordlen = strlen(word);
3944 struct ao2_iterator i;
3945
3946 i = ao2_iterator_init(peers, 0);
3947 while ((peer = ao2_iterator_next(&i))) {
3948 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
3949 && (!flags || ast_test_flag64(peer, flags))) {
3950 res = ast_strdup(peer->name);
3951 peer_unref(peer);
3952 break;
3953 }
3954 peer_unref(peer);
3955 }
3957
3958 return res;
3959}
short word

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

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

◆ complete_iax2_unregister()

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

Definition at line 7248 of file chan_iax2.c.

7249{
7250 int which = 0;
7251 struct iax2_peer *p = NULL;
7252 char *res = NULL;
7253 int wordlen = strlen(word);
7254
7255 /* 0 - iax2; 1 - unregister; 2 - <peername> */
7256 if (pos == 2) {
7257 struct ao2_iterator i = ao2_iterator_init(peers, 0);
7258 while ((p = ao2_iterator_next(&i))) {
7259 if (!strncasecmp(p->name, word, wordlen) &&
7260 ++which > state && p->expire > -1) {
7261 res = ast_strdup(p->name);
7262 peer_unref(p);
7263 break;
7264 }
7265 peer_unref(p);
7266 }
7268 }
7269
7270 return res;
7271}

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

Referenced by handle_cli_iax2_unregister().

◆ complete_transfer()

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

Definition at line 8791 of file chan_iax2.c.

8792{
8793 int peercallno = 0;
8794 struct chan_iax2_pvt *pvt = iaxs[callno];
8795 struct iax_frame *cur;
8796 jb_frame frame;
8797
8798 if (ies->callno)
8799 peercallno = ies->callno;
8800
8801 if (peercallno < 1) {
8802 ast_log(LOG_WARNING, "Invalid transfer request\n");
8803 return -1;
8804 }
8806 /* since a transfer has taken place, the address will change.
8807 * This must be accounted for in the peercnts table. Remove
8808 * the old address and add the new one */
8810 peercnt_add(&pvt->transfer);
8811 /* now copy over the new address */
8812 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
8813 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
8814 /* Reset sequence numbers */
8815 pvt->oseqno = 0;
8816 pvt->rseqno = 0;
8817 pvt->iseqno = 0;
8818 pvt->aseqno = 0;
8819
8820 if (pvt->peercallno) {
8822 }
8823 pvt->peercallno = peercallno;
8824 /*this is where the transfering call switches hash tables */
8827 pvt->svoiceformat = -1;
8828 pvt->voiceformat = 0;
8829 pvt->svideoformat = -1;
8830 pvt->videoformat = 0;
8831 pvt->transfercallno = 0;
8832 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
8833 memset(&pvt->offset, 0, sizeof(pvt->offset));
8834 /* reset jitterbuffer */
8835 while(jb_getall(pvt->jb,&frame) == JB_OK)
8836 iax2_frame_free(frame.data);
8837 jb_reset(pvt->jb);
8838 pvt->lag = 0;
8839 pvt->last = 0;
8840 pvt->lastsent = 0;
8841 pvt->nextpred = 0;
8844 /* We must cancel any packets that would have been transmitted
8845 because now we're talking to someone new. It's okay, they
8846 were transmitted to someone that didn't care anyway. */
8847 cur->retries = -1;
8848 }
8849 return 0;
8850}
static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:2456
static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:2475
void jb_reset(jitterbuf *jb)
reset jitterbuf
Definition: jitterbuf.c:72
enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout)
unconditionally get frames from jitterbuf until empty
Definition: jitterbuf.c:801
iax2_format svideoformat
Definition: chan_iax2.c:754
unsigned char iseqno
Definition: chan_iax2.c:818
iax2_format videoformat
Definition: chan_iax2.c:750
unsigned char rseqno
Definition: chan_iax2.c:816
unsigned short transfercallno
Definition: chan_iax2.c:896
unsigned char oseqno
Definition: chan_iax2.c:814
unsigned char aseqno
Definition: chan_iax2.c:820
iax2_format svoiceformat
Definition: chan_iax2.c:752
unsigned int last
Definition: chan_iax2.c:758
enum iax_transfer_state transferring
Definition: chan_iax2.c:890
struct iax_frame::@139 list
unsigned short callno
Definition: parser.h:55

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

Referenced by socket_process_helper().

◆ compress_subclass()

static unsigned char compress_subclass ( iax2_format  subclass)
static

Definition at line 1860 of file chan_iax2.c.

1861{
1862 int x;
1863 int power=-1;
1864 /* If it's 64 or smaller, just return it */
1865 if (subclass < IAX_FLAG_SC_LOG)
1866 return subclass;
1867 /* Otherwise find its power */
1868 for (x = 0; x < IAX_MAX_SHIFT; x++) {
1869 if (subclass & (1LL << x)) {
1870 if (power > -1) {
1871 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass);
1872 return 0;
1873 } else
1874 power = x;
1875 }
1876 }
1877 return power | IAX_FLAG_SC_LOG;
1878}
#define IAX_FLAG_SC_LOG
Definition: iax2.h:44
#define IAX_MAX_SHIFT
Definition: iax2.h:46

References ast_log, IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.

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

◆ construct_rr()

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

Definition at line 9754 of file chan_iax2.c.

9755{
9756 jb_info stats;
9757 jb_getinfo(pvt->jb, &stats);
9758
9759 memset(iep, 0, sizeof(*iep));
9760
9762 if(stats.frames_in == 0) stats.frames_in = 1;
9763 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
9765 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
9768}
#define IAX_IE_RR_PKTS
Definition: iax2.h:179
#define IAX_IE_RR_JITTER
Definition: iax2.h:177
#define IAX_IE_RR_DROPPED
Definition: iax2.h:181
#define IAX_IE_RR_OOO
Definition: iax2.h:182
#define IAX_IE_RR_LOSS
Definition: iax2.h:178
#define IAX_IE_RR_DELAY
Definition: iax2.h:180
long frames_in
Definition: jitterbuf.h:79

References jb_info::current, jb_info::frames_dropped, jb_info::frames_in, jb_info::frames_lost, jb_info::frames_ooo, iax_ie_append_int(), iax_ie_append_short(), IAX_IE_RR_DELAY, IAX_IE_RR_DROPPED, IAX_IE_RR_JITTER, IAX_IE_RR_LOSS, IAX_IE_RR_OOO, IAX_IE_RR_PKTS, chan_iax2_pvt::jb, jb_getinfo(), jb_info::jitter, jb_info::losspct, and jb_info::min.

Referenced by socket_process_helper().

◆ create_addr()

static int create_addr ( const char *  peername,
struct ast_channel c,
struct ast_sockaddr addr,
struct create_addr_info cai 
)
static

Definition at line 4666 of file chan_iax2.c.

4667{
4668 struct iax2_peer *peer;
4669 int res = -1;
4670
4672 cai->sockfd = defaultsockfd;
4673 cai->maxtime = 0;
4674
4675 if (!(peer = find_peer(peername, 1))) {
4676 struct ast_sockaddr peer_addr;
4677
4678 peer_addr.ss.ss_family = AST_AF_UNSPEC;
4679 cai->found = 0;
4680 if (ast_get_ip_or_srv(&peer_addr, peername, srvlookup ? "_iax._udp" : NULL)) {
4681 ast_log(LOG_WARNING, "No such host: %s\n", peername);
4682 return -1;
4683 }
4684
4685 if (!ast_sockaddr_port(&peer_addr)) {
4687 }
4688
4689 ast_sockaddr_copy(addr, &peer_addr);
4690 /*
4691 * Use The global iax prefs for unknown peer/user.
4692 * However, move the calling channel's native codec to
4693 * the top of the preference list.
4694 */
4695 cai->prefs = prefs_global;
4696 if (c) {
4697 int i;
4698
4699 for (i = 0; i < ast_format_cap_count(ast_channel_nativeformats(c)); i++) {
4700 struct ast_format *format = ast_format_cap_get_format(
4702 iax2_codec_pref_prepend(&cai->prefs, format,
4704 1);
4705 ao2_ref(format, -1);
4706 }
4707 }
4708 return 0;
4709 }
4710
4711 cai->found = 1;
4712
4713 /* if the peer has no address (current or default), return failure */
4714 if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) {
4715 goto return_unref;
4716 }
4717
4718 /* if the peer is being monitored and is currently unreachable, return failure */
4719 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
4720 goto return_unref;
4721
4723 cai->maxtime = peer->maxms;
4724 cai->capability = peer->capability;
4725 cai->encmethods = peer->encmethods;
4726 cai->authmethods = peer->authmethods;
4727 cai->sockfd = peer->sockfd;
4728 cai->adsi = peer->adsi;
4729 cai->prefs = peer->prefs;
4730 /* Move the calling channel's native codec to the top of the preference list */
4731 if (c) {
4732 int i;
4733
4734 for (i = 0; i < ast_format_cap_count(ast_channel_nativeformats(c)); i++) {
4735 struct ast_format *tmpfmt = ast_format_cap_get_format(
4737 iax2_codec_pref_prepend(&cai->prefs, tmpfmt,
4739 1);
4740 ao2_ref(tmpfmt, -1);
4741 }
4742 }
4743 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
4744 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
4745 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
4746 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
4747 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
4748 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
4749 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
4750 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
4751 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
4752 if (ast_strlen_zero(peer->dbsecret)) {
4753 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
4754 } else {
4755 char *family;
4756 char *key = NULL;
4757
4758 family = ast_strdupa(peer->dbsecret);
4759 key = strchr(family, '/');
4760 if (key)
4761 *key++ = '\0';
4762 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
4763 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
4764 goto return_unref;
4765 }
4766 }
4767
4768 if (!ast_sockaddr_isnull(&peer->addr)) {
4769 ast_sockaddr_copy(addr, &peer->addr);
4770 } else {
4771 ast_sockaddr_copy(addr, &peer->defaddr);
4772 }
4773
4774 res = 0;
4775
4776return_unref:
4777 peer_unref(peer);
4778
4779 return res;
4780}
int ast_get_ip_or_srv(struct ast_sockaddr *addr, const char *hostname, const char *service)
Get the IP address given a hostname and optional service.
Definition: acl.c:896
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
void iax2_codec_pref_prepend(struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing, int only_if_existing)
Prepend an audio codec to a preference list, removing it first if it was already there.
Definition: codec_pref.c:432
unsigned int ast_format_cap_get_format_framing(const struct ast_format_cap *cap, const struct ast_format *format)
Get the framing for a format.
Definition: format_cap.c:443
char outkey[80]
Definition: chan_iax2.c:4656
iax2_format capability
Definition: chan_iax2.c:4645
char username[80]
Definition: chan_iax2.c:4654
char cid_num[80]
Definition: chan_iax2.c:4658
struct iax2_codec_pref prefs
Definition: chan_iax2.c:4647
char timezone[80]
Definition: chan_iax2.c:4657
char secret[80]
Definition: chan_iax2.c:4655
char cid_name[80]
Definition: chan_iax2.c:4659
char context[AST_MAX_CONTEXT]
Definition: chan_iax2.c:4660
char peercontext[AST_MAX_CONTEXT]
Definition: chan_iax2.c:4661
char mohsuggest[MAX_MUSICCLASS]
Definition: chan_iax2.c:4663
char mohinterpret[MAX_MUSICCLASS]
Definition: chan_iax2.c:4662
const ast_string_field peercontext
Definition: chan_iax2.c:599
const ast_string_field mohinterpret
Definition: chan_iax2.c:599
const ast_string_field cid_num
Definition: chan_iax2.c:599
const ast_string_field mohsuggest
Definition: chan_iax2.c:599
const ast_string_field zonetag
Definition: chan_iax2.c:599
const ast_string_field context
Definition: chan_iax2.c:599
const ast_string_field dbsecret
Definition: chan_iax2.c:599
const ast_string_field cid_name
Definition: chan_iax2.c:599
static struct test_val c

References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ao2_ref, AST_AF_UNSPEC, ast_channel_nativeformats(), ast_clear_flag64, ast_copy_flags64, ast_copy_string(), ast_db_get(), ast_format_cap_count(), ast_format_cap_get_format(), ast_format_cap_get_format_framing(), ast_get_ip_or_srv(), ast_log, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_strdupa, ast_strlen_zero(), iax2_peer::authmethods, create_addr_info::authmethods, c, iax2_peer::capability, create_addr_info::capability, iax2_peer::cid_name, create_addr_info::cid_name, iax2_peer::cid_num, create_addr_info::cid_num, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, defaultsockfd, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, iax2_codec_pref_prepend(), IAX_DEFAULT_PORTNO, IAX_FORCE_ENCRYPT, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::mohinterpret, create_addr_info::mohinterpret, iax2_peer::mohsuggest, create_addr_info::mohsuggest, NULL, iax2_peer::outkey, create_addr_info::outkey, peer_unref(), iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs_global, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, srvlookup, ast_sockaddr::ss, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.

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

◆ create_callno_pools()

static int create_callno_pools ( void  )
static

Definition at line 3068 of file chan_iax2.c.

3069{
3070 uint16_t i;
3071
3073
3074 /* We start at 2. 0 and 1 are reserved. */
3075 for (i = 2; i < TRUNK_CALL_START; i++) {
3078 }
3079
3080 for (i = TRUNK_CALL_START; i < IAX_MAX_CALLS; i++) {
3083 }
3084
3087
3089
3090 return 0;
3091}
#define TRUNK_CALL_START
Definition: chan_iax2.c:1222
static struct call_number_pool callno_pool
Definition: chan_iax2.c:966
static struct call_number_pool callno_pool_trunk
Definition: chan_iax2.c:969
#define IAX_MAX_CALLS
Definition: iax2.h:37
size_t available
Definition: chan_iax2.c:959
callno_entry numbers[IAX_MAX_CALLS/2+1]
Definition: chan_iax2.c:960
#define ast_assert(a)
Definition: utils.h:739

References ast_assert, call_number_pool::available, callno_pool, callno_pool_trunk, call_number_pool::capacity, IAX_MAX_CALLS, call_number_pool::numbers, and TRUNK_CALL_START.

Referenced by load_objects().

◆ decode_frame()

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

Definition at line 6523 of file chan_iax2.c.

6524{
6525 int padding;
6526 unsigned char *workspace;
6527
6528 workspace = ast_alloca(*datalen);
6529 memset(f, 0, sizeof(*f));
6530 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
6531 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
6532 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
6533 return -1;
6534 /* Decrypt */
6535 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
6536
6537 padding = 16 + (workspace[15] & 0x0f);
6538 if (iaxdebug)
6539 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02hhx)\n", *datalen, padding, workspace[15]);
6540 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
6541 return -1;
6542
6543 *datalen -= padding;
6544 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
6545 f->frametype = fh->type;
6546 if (f->frametype == AST_FRAME_VIDEO) {
6548 if (!f->subclass.format) {
6550 }
6551 } else if (f->frametype == AST_FRAME_VOICE) {
6553 if (!f->subclass.format) {
6555 }
6556 } else {
6558 }
6559 } else {
6560 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
6561 if (iaxdebug)
6562 ast_debug(5, "Decoding mini with length %d\n", *datalen);
6563 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
6564 return -1;
6565 /* Decrypt */
6566 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
6567 padding = 16 + (workspace[15] & 0x0f);
6568 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
6569 return -1;
6570 *datalen -= padding;
6571 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
6572 }
6573 return 0;
6574}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
static iax2_format uncompress_subclass(unsigned char csub)
Definition: chan_iax2.c:1880
static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
Definition: chan_iax2.c:6475
struct ast_format * ast_format_none
Built-in "null" format.
Definition: format_cache.c:246
#define IAX_FLAG_FULL
Definition: iax2.h:40
unsigned char encdata[0]
Definition: iax2.h:245
unsigned short scallno
Definition: iax2.h:231
unsigned char csub
Definition: iax2.h:237
unsigned char type
Definition: iax2.h:236
unsigned char encdata[0]
Definition: iax2.h:260

References ast_alloca, ast_debug, ast_format_compatibility_bitfield2format(), ast_format_none, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_iax2_full_hdr::csub, ast_iax2_full_enc_hdr::encdata, ast_iax2_mini_enc_hdr::encdata, ast_frame_subclass::format, ast_frame::frametype, IAX_FLAG_FULL, iaxdebug, ast_frame_subclass::integer, memcpy_decrypt(), ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass().

Referenced by decrypt_frame(), and update_packet().

◆ decrypt_frame()

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

Definition at line 6615 of file chan_iax2.c.

6616{
6617 int res=-1;
6618 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
6619 /* Search for possible keys, given secrets */
6620 struct MD5Context md5;
6621 unsigned char digest[16];
6622 char *tmppw, *stringp;
6623
6624 tmppw = ast_strdupa(iaxs[callno]->secret);
6625 stringp = tmppw;
6626 while ((tmppw = strsep(&stringp, ";"))) {
6627 MD5Init(&md5);
6628 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
6629 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
6630 MD5Final(digest, &md5);
6631 build_encryption_keys(digest, iaxs[callno]);
6632 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
6633 if (!res) {
6635 break;
6636 }
6637 }
6638 } else
6639 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
6640 return res;
6641}
static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
Definition: chan_iax2.c:6523

References ast_set_flag64, ast_strdupa, ast_test_flag64, build_encryption_keys(), ast_iax2_mini_enc_hdr::callno, challenge(), decode_frame(), IAX_KEYPOPULATED, iaxs, md5(), MD5Final(), MD5Init(), MD5Update(), and strsep().

Referenced by socket_process_helper().

◆ defer_full_frame()

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

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

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

Definition at line 9884 of file chan_iax2.c.

9885{
9886 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
9887 struct ast_iax2_full_hdr *fh, *cur_fh;
9888
9889 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
9890 return;
9891
9892 pkt_buf->len = from_here->buf_len;
9893 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
9894
9895 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
9896 ast_mutex_lock(&to_here->lock);
9897 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
9898 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
9899 if (fh->oseqno < cur_fh->oseqno) {
9901 break;
9902 }
9903 }
9905
9906 if (!cur_pkt_buf)
9907 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
9908
9909 to_here->iostate = IAX_IOSTATE_READY;
9910 ast_cond_signal(&to_here->cond);
9911
9912 ast_mutex_unlock(&to_here->lock);
9913}
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list entry before the current entry during a traversal.
Definition: linkedlists.h:599
#define ast_cond_signal(cond)
Definition: lock.h:203
unsigned char oseqno
Definition: iax2.h:234
unsigned char buf[1]
Definition: chan_iax2.c:1105
size_t len
Definition: chan_iax2.c:1104
ast_cond_t cond
Definition: chan_iax2.c:1130
unsigned char * buf
Definition: chan_iax2.c:1124
enum iax2_thread_iostate iostate
Definition: chan_iax2.c:1111
ast_mutex_t lock
Definition: chan_iax2.c:1129
struct iax2_thread::@129 full_frames
ssize_t buf_len
Definition: chan_iax2.c:1125

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

Referenced by socket_read().

◆ delete_users()

static void delete_users ( void  )
static

Definition at line 13569 of file chan_iax2.c.

13570{
13571 struct iax2_registry *reg;
13572
13574
13576 while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
13577 if (sched) {
13578 AST_SCHED_DEL(sched, reg->expire);
13579 }
13580 if (reg->callno) {
13581 int callno = reg->callno;
13583 if (iaxs[callno]) {
13584 iaxs[callno]->reg = NULL;
13586 }
13588 }
13589 if (reg->dnsmgr)
13591 ast_free(reg);
13592 }
13594
13596}
@ OBJ_NODATA
Definition: astobj2.h:1044
static int user_delme_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:13560
static int peer_delme_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:13551
void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry)
Free a DNS manager entry.
Definition: dnsmgr.c:136

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

Referenced by __unload_module(), and set_config_destroy().

◆ dp_lookup()

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

Definition at line 9680 of file chan_iax2.c.

9681{
9682 unsigned short dpstatus = 0;
9683 struct iax_ie_data ied1;
9684 int mm;
9685
9686 memset(&ied1, 0, sizeof(ied1));
9687 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
9688 /* Must be started */
9689 if (ast_exists_extension(NULL, context, callednum, 1, callerid)) {
9690 dpstatus = IAX_DPSTATUS_EXISTS;
9691 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
9692 dpstatus = IAX_DPSTATUS_CANEXIST;
9693 } else {
9694 dpstatus = IAX_DPSTATUS_NONEXISTENT;
9695 }
9696 if (ast_ignore_pattern(context, callednum))
9697 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
9698 if (mm)
9699 dpstatus |= IAX_DPSTATUS_MATCHMORE;
9700 if (!skiplock)
9701 ast_mutex_lock(&iaxsl[callno]);
9702 if (iaxs[callno]) {
9703 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
9704 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
9706 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
9707 }
9708 if (!skiplock)
9709 ast_mutex_unlock(&iaxsl[callno]);
9710}
@ IAX_COMMAND_DPREP
Definition: iax2.h:79
#define IAX_IE_DPSTATUS
Definition: iax2.h:150
#define IAX_DPSTATUS_IGNOREPAT
Definition: iax2.h:220
#define IAX_IE_REFRESH
Definition: iax2.h:149
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4175
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:4190
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
Definition: pbx.c:6879
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch)
Definition: pbx.c:4195

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

Referenced by dp_lookup_thread(), and socket_process_helper().

◆ dp_lookup_thread()

static void * dp_lookup_thread ( void *  data)
static

Definition at line 9712 of file chan_iax2.c.

9713{
9714 /* Look up for dpreq */
9715 struct dpreq_data *dpr = data;
9716 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
9717 if (dpr->callerid)
9718 ast_free(dpr->callerid);
9719 ast_free(dpr);
9720 return NULL;
9721}
static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
Definition: chan_iax2.c:9680
char context[AST_MAX_EXTENSION]
Definition: chan_iax2.c:9675
char callednum[AST_MAX_EXTENSION]
Definition: chan_iax2.c:9676
char * callerid
Definition: chan_iax2.c:9677

References ast_free, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, dp_lookup(), and NULL.

Referenced by spawn_dp_lookup().

◆ encmethods_to_str()

static void encmethods_to_str ( int  e,
struct ast_str **  buf 
)
static

Definition at line 1797 of file chan_iax2.c.

1798{
1799 ast_str_set(buf, 0, "(");
1800 if (e & IAX_ENCRYPT_AES128) {
1801 ast_str_append(buf, 0, "aes128");
1802 }
1803 if (e & IAX_ENCRYPT_KEYROTATE) {
1804 ast_str_append(buf, 0, ",keyrotate");
1805 }
1806 if (ast_str_strlen(*buf) > 1) {
1807 ast_str_append(buf, 0, ")");
1808 } else {
1809 ast_str_set(buf, 0, "No");
1810 }
1811}
#define IAX_ENCRYPT_AES128
Definition: iax2.h:201
#define IAX_ENCRYPT_KEYROTATE
Definition: iax2.h:202
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730

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

Referenced by _iax2_show_peers_one(), and handle_cli_iax2_show_peer().

◆ encrypt_frame()

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

Definition at line 6576 of file chan_iax2.c.

6577{
6578 int padding;
6579 unsigned char *workspace;
6580 workspace = ast_alloca(*datalen + 32);
6581 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
6582 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
6583 if (iaxdebug)
6584 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
6585 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
6586 padding = 16 + (padding & 0xf);
6587 memcpy(workspace, poo, padding);
6588 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
6589 workspace[15] &= 0xf0;
6590 workspace[15] |= (padding & 0xf);
6591 if (iaxdebug)
6592 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02hhx)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
6593 *datalen += padding;
6594 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
6595 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
6596 memcpy(poo, workspace + *datalen - 32, 32);
6597 } else {
6598 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
6599 if (iaxdebug)
6600 ast_debug(5, "Encoding mini frame with length %d\n", *datalen);
6601 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
6602 padding = 16 + (padding & 0xf);
6603 memcpy(workspace, poo, padding);
6604 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
6605 workspace[15] &= 0xf0;
6606 workspace[15] |= (padding & 0x0f);
6607 *datalen += padding;
6608 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
6609 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
6610 memcpy(poo, workspace + *datalen - 32, 32);
6611 }
6612 return 0;
6613}
static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
Definition: chan_iax2.c:6499

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

Referenced by iax2_send(), and update_packet().

◆ expire_registry()

static int expire_registry ( const void *  data)
static

Definition at line 9081 of file chan_iax2.c.

9082{
9083#ifdef SCHED_MULTITHREADED
9085#endif
9086 __expire_registry(data);
9087 return 0;
9088}
static void __expire_registry(const void *data)
Definition: chan_iax2.c:9040

References __expire_registry(), and schedule_action.

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

◆ find_cache()

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

Definition at line 14307 of file chan_iax2.c.

14308{
14309 struct iax2_dpcache *dp = NULL;
14310 struct timeval now = ast_tvnow();
14311 int x, com[2], timeout, doabort, callno;
14312
14313 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
14314 if (ast_tvcmp(now, dp->expiry) > 0) {
14315 AST_LIST_REMOVE_CURRENT(cache_list);
14316 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
14317 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
14318 else
14319 ast_free(dp);
14320 continue;
14321 }
14322 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
14323 break;
14324 }
14326
14327 if (!dp) {
14328 /* No matching entry. Create a new one. */
14329 /* First, can we make a callno? */
14330 if ((callno = cache_get_callno_locked(data)) < 0) {
14331 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
14332 return NULL;
14333 }
14334 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
14335 ast_mutex_unlock(&iaxsl[callno]);
14336 return NULL;
14337 }
14338 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
14339 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
14340 dp->expiry = ast_tvnow();
14341 dp->orig = dp->expiry;
14342 /* Expires in 30 mins by default */
14343 dp->expiry.tv_sec += iaxdefaultdpcache;
14345 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
14346 dp->waiters[x] = -1;
14347 /* Insert into the lists */
14348 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
14349 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
14350 /* Send the request if we're already up */
14351 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
14352 iax2_dprequest(dp, callno);
14353 ast_mutex_unlock(&iaxsl[callno]);
14354 }
14355
14356 /* By here we must have a dp */
14357 if (dp->flags & CACHE_FLAG_PENDING) {
14358 int res;
14359 struct pollfd pfd;
14360 /* Okay, here it starts to get nasty. We need a pipe now to wait
14361 for a reply to come back so long as it's pending */
14362 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
14363 /* Find an empty slot */
14364 if (dp->waiters[x] < 0)
14365 break;
14366 }
14367 if (x >= ARRAY_LEN(dp->waiters)) {
14368 ast_log(LOG_WARNING, "No more waiter positions available\n");
14369 return NULL;
14370 }
14371 if (pipe(com)) {
14372 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
14373 return NULL;
14374 }
14375 dp->waiters[x] = com[1];
14376 /* Okay, now we wait */
14377 timeout = iaxdefaulttimeout * 1000;
14378 /* Temporarily unlock */
14380 doabort = 0;
14381
14382 /* chan is in autoservice here, so do NOT service it here! */
14383 pfd.fd = com[0];
14384 pfd.events = POLLIN;
14385 pfd.revents = 0;
14386 /* Wait for pipe activity... if the channel hangs up, we'll catch it on the way out. */
14387 res = ast_poll(&pfd, 1, timeout);
14388 if (res < 0) {
14389 ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
14390 return NULL;
14391 } else if (!pfd.revents) {
14392 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
14393 }
14394
14395 if (chan && ast_check_hangup(chan)) {
14396 doabort = 1;
14397 }
14398
14400 dp->waiters[x] = -1;
14401 close(com[1]);
14402 close(com[0]);
14403 if (doabort) {
14404 /* Don't interpret anything, just abort. */
14405 return NULL;
14406 }
14407 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
14408 /* Now to do non-independent analysis the results of our wait */
14409 if (dp->flags & CACHE_FLAG_PENDING) {
14410 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer
14411 pending. Don't let it take as long to timeout. */
14412 dp->flags &= ~CACHE_FLAG_PENDING;
14414 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded
14415 systems without leaving it unavailable once the server comes back online */
14416 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
14417 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
14418 if (dp->waiters[x] > -1) {
14419 if (write(dp->waiters[x], "asdf", 4) < 0) {
14420 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
14421 }
14422 }
14423 }
14424 }
14425 }
14426 /* Our caller will obtain the rest */
14427 }
14428 return dp;
14429}
static int iaxdefaulttimeout
Definition: chan_iax2.c:352
static int cache_get_callno_locked(const char *data)
Definition: chan_iax2.c:14234
static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
Definition: chan_iax2.c:9503
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
char peercontext[AST_MAX_CONTEXT]
Definition: chan_iax2.c:1069
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compress two struct timeval instances returning -1, 0, 1 if the first arg is smaller,...
Definition: time.h:137

References ARRAY_LEN, ast_calloc, ast_check_hangup(), ast_copy_string(), ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log, ast_mutex_unlock, ast_poll, ast_test_flag, ast_tvcmp(), ast_tvnow(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, errno, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dprequest(), IAX_STATE_STARTED, iaxdefaultdpcache, iaxdefaulttimeout, iaxs, iaxsl, LOG_WARNING, NULL, iax2_dpcache::orig, iax2_dpcache::peercontext, and iax2_dpcache::waiters.

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

◆ find_callno()

static int find_callno ( unsigned short  callno,
unsigned short  dcallno,
struct ast_sockaddr addr,
int  new,
int  sockfd,
int  full_frame 
)
static

Definition at line 3281 of file chan_iax2.c.

3281 {
3282 return __find_callno(callno, dcallno, addr, new, sockfd, 0, full_frame);
3283}
static int __find_callno(unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, int new, int sockfd, int return_locked, int check_dcallno)
Definition: chan_iax2.c:3155

References __find_callno(), chan_iax2_pvt::addr, chan_iax2_pvt::callno, and chan_iax2_pvt::sockfd.

Referenced by iax2_poke_peer(), and socket_process_helper().

◆ find_callno_locked()

static int find_callno_locked ( unsigned short  callno,
unsigned short  dcallno,
struct ast_sockaddr addr,
int  new,
int  sockfd,
int  full_frame 
)
static

Definition at line 3285 of file chan_iax2.c.

3285 {
3286
3287 return __find_callno(callno, dcallno, addr, new, sockfd, 1, full_frame);
3288}

References __find_callno(), chan_iax2_pvt::addr, chan_iax2_pvt::callno, and chan_iax2_pvt::sockfd.

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

◆ find_idle_thread()

static struct iax2_thread * find_idle_thread ( void  )
static

Definition at line 1632 of file chan_iax2.c.

1633{
1634 struct iax2_thread *thread = NULL;
1635
1636 /* Pop the head of the idle list off */
1640
1641 /* If we popped a thread off the idle list, just return it */
1642 if (thread) {
1643 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
1644 return thread;
1645 }
1646
1647 /* Pop the head of the dynamic list off */
1651
1652 /* If we popped a thread off the dynamic list, just return it */
1653 if (thread) {
1654 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
1655 return thread;
1656 }
1657
1658 /* If we can't create a new dynamic thread for any reason, return no thread at all */
1660 return NULL;
1661
1662 /* Set default values */
1666
1667 /* Initialize lock and condition */
1668 ast_mutex_init(&thread->lock);
1669 ast_cond_init(&thread->cond, NULL);
1670 ast_mutex_init(&thread->init_lock);
1671 ast_cond_init(&thread->init_cond, NULL);
1672 ast_mutex_lock(&thread->init_lock);
1673
1674 /* Create thread and send it on it's way */
1676 ast_cond_destroy(&thread->cond);
1677 ast_mutex_destroy(&thread->lock);
1678 ast_mutex_unlock(&thread->init_lock);
1679 ast_cond_destroy(&thread->init_cond);
1680 ast_mutex_destroy(&thread->init_lock);
1682 return NULL;
1683 }
1684
1685 /* this thread is not processing a full frame (since it is idle),
1686 so ensure that the field for the full frame call number is empty */
1687 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
1688
1689 /* Wait for the thread to be ready before returning it to the caller */
1690 ast_cond_wait(&thread->init_cond, &thread->init_lock);
1691
1692 /* Done with init_lock */
1693 ast_mutex_unlock(&thread->init_lock);
1694
1695 return thread;
1696}
static int iaxdynamicthreadcount
Definition: chan_iax2.c:722
static void * iax2_process_thread(void *data)
Definition: chan_iax2.c:12158
static int iaxdynamicthreadnum
Definition: chan_iax2.c:723
static int iaxmaxthreadcount
Definition: chan_iax2.c:721
#define ast_cond_destroy(cond)
Definition: lock.h:202
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205
#define ast_cond_init(cond, attr)
Definition: lock.h:201
#define ast_mutex_init(pmutex)
Definition: lock.h:186
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:592

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

Referenced by __schedule_action(), and socket_read().

◆ find_peer()

static struct iax2_peer * find_peer ( const char *  name,
int  realtime 
)
static
Note
This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno, so do not call it with a pvt lock held.

Definition at line 2056 of file chan_iax2.c.

2057{
2058 struct iax2_peer *peer = NULL;
2059
2060 peer = ao2_find(peers, name, OBJ_KEY);
2061
2062 /* Now go for realtime if applicable */
2063 if (!peer && realtime) {
2064 peer = realtime_peer(name, NULL);
2065 }
2066 return peer;
2067}

References ao2_find, name, NULL, OBJ_KEY, and realtime_peer().

Referenced by ast_iax2_new(), calltoken_required(), create_addr(), function_iaxpeer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), handle_cli_iax2_show_peer(), handle_cli_iax2_unregister(), iax2_devicestate(), register_verify(), registry_authrequest(), requirecalltoken_mark_auto(), and update_registry().

◆ find_tpeer()

static struct iax2_trunk_peer * find_tpeer ( struct ast_sockaddr addr,
int  fd 
)
static

Definition at line 6324 of file chan_iax2.c.

6325{
6326 struct iax2_trunk_peer *tpeer = NULL;
6327
6328 /* Finds and locks trunk peer */
6330
6331 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
6332 if (!ast_sockaddr_cmp(&tpeer->addr, addr)) {
6333 ast_mutex_lock(&tpeer->lock);
6334 break;
6335 }
6336 }
6337
6338 if (!tpeer) {
6339 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
6340 ast_mutex_init(&tpeer->lock);
6341 tpeer->lastsent = 9999;
6342 ast_sockaddr_copy(&tpeer->addr, addr);
6343 tpeer->trunkact = ast_tvnow();
6344 ast_mutex_lock(&tpeer->lock);
6345 tpeer->sockfd = fd;
6346
6347#ifdef SO_NO_CHECK
6348 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
6349#endif
6350 ast_debug(1, "Created trunk peer for '%s'\n", ast_sockaddr_stringify(&tpeer->addr));
6352 }
6353 }
6354
6356
6357 return tpeer;
6358}
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
struct ast_sockaddr addr
Definition: chan_iax2.c:643
struct iax2_trunk_peer::@120 list
ast_mutex_t lock
Definition: chan_iax2.c:641

References iax2_trunk_peer::addr, ast_calloc, ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_init, ast_mutex_lock, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_tvnow(), iax2_trunk_peer::lastsent, iax2_trunk_peer::list, iax2_trunk_peer::lock, NULL, iax2_trunk_peer::sockfd, and iax2_trunk_peer::trunkact.

Referenced by iax2_trunk_queue(), and socket_process_meta().

◆ find_user()

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

Definition at line 2081 of file chan_iax2.c.

2082{
2083 return ao2_find(users, name, OBJ_KEY);
2084}

References ao2_find, name, and OBJ_KEY.

Referenced by calltoken_required(), handle_cli_iax2_prune_realtime(), and requirecalltoken_mark_auto().

◆ firmware_show_callback()

static int firmware_show_callback ( struct ast_iax2_firmware_header header,
void *  user_data 
)
static

Definition at line 7305 of file chan_iax2.c.

7307{
7308 int *fd = user_data;
7309
7310 ast_cli(*fd, "%-15.15s %-15d %-15d\n",
7311 header->devname,
7312 ntohs(header->version),
7313 (int) ntohl(header->datalen));
7314
7315 return 0;
7316}

References ast_cli().

Referenced by handle_cli_iax2_show_firmware().

◆ fix_peerts()

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

Definition at line 6134 of file chan_iax2.c.

6135{
6136 long ms; /* NOT unsigned */
6137 if (ast_tvzero(iaxs[callno]->rxcore)) {
6138 /* Initialize rxcore time if appropriate */
6139 iaxs[callno]->rxcore = ast_tvnow();
6140 /* Round to nearest 20ms so traces look pretty */
6141 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
6142 }
6143 /* Calculate difference between trunk and channel */
6144 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
6145 /* Return as the sum of trunk time and the difference between trunk and real time */
6146 return ms + ts;
6147}

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

Referenced by socket_process_meta().

◆ free_context()

static void free_context ( struct iax2_context con)
static

Definition at line 12616 of file chan_iax2.c.

12617{
12618 struct iax2_context *conl;
12619 while(con) {
12620 conl = con;
12621 con = con->next;
12622 ast_free(conl);
12623 }
12624}

References ast_free, and iax2_context::next.

Referenced by build_user(), and user_destructor().

◆ free_signaling_queue_entry()

static void free_signaling_queue_entry ( struct signaling_queue_entry s)
static

Definition at line 2195 of file chan_iax2.c.

2196{
2197 if (s->f.datalen) {
2198 ast_free(s->f.data.ptr);
2199 }
2200 ast_free(s);
2201}
struct ast_frame f
Definition: chan_iax2.c:941

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

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

◆ function_iaxpeer()

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

Definition at line 14552 of file chan_iax2.c.

14553{
14554 struct iax2_peer *peer;
14555 char *peername, *colname;
14556
14557 peername = ast_strdupa(data);
14558
14559 /* if our channel, return the IP address of the endpoint of current channel */
14560 if (!strcmp(peername,"CURRENTCHANNEL")) {
14561 unsigned short callno;
14562 if (!chan || ast_channel_tech(chan) != &iax2_tech) {
14563 return -1;
14564 }
14567 return 0;
14568 }
14569
14570 if ((colname = strchr(peername, ',')))
14571 *colname++ = '\0';
14572 else
14573 colname = "ip";
14574
14575 if (!(peer = find_peer(peername, 1)))
14576 return -1;
14577
14578 if (!strcasecmp(colname, "ip")) {
14580 } else if (!strcasecmp(colname, "status")) {
14581 peer_status(peer, buf, len);
14582 } else if (!strcasecmp(colname, "mailbox")) {
14583 ast_copy_string(buf, peer->mailbox, len);
14584 } else if (!strcasecmp(colname, "context")) {
14585 ast_copy_string(buf, peer->context, len);
14586 } else if (!strcasecmp(colname, "expire")) {
14587 snprintf(buf, len, "%d", peer->expire);
14588 } else if (!strcasecmp(colname, "dynamic")) {
14589 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
14590 } else if (!strcasecmp(colname, "callerid_name")) {
14592 } else if (!strcasecmp(colname, "callerid_num")) {
14593 ast_copy_string(buf, peer->cid_num, len);
14594 } else if (!strcasecmp(colname, "codecs")) {
14595 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
14596
14597 iax2_getformatname_multiple(peer->capability, &codec_buf);
14598 ast_copy_string(buf, ast_str_buffer(codec_buf), len);
14599 } else if (!strncasecmp(colname, "codec[", 6)) {
14600 char *codecnum, *ptr;
14601 struct ast_format *tmpfmt;
14602
14603 /* skip over "codec" to the '[' */
14604 codecnum = colname + 5;
14605 *codecnum = '\0';
14606 codecnum++;
14607 if ((ptr = strchr(codecnum, ']'))) {
14608 *ptr = '\0';
14609 }
14610 if((iax2_codec_pref_index(&peer->prefs, atoi(codecnum), &tmpfmt))) {
14612 } else {
14613 buf[0] = '\0';
14614 }
14615 } else {
14616 buf[0] = '\0';
14617 }
14618
14619 peer_unref(peer);
14620
14621 return 0;
14622}
static const char * iax2_getformatname_multiple(iax2_format format, struct ast_str **codec_buf)
Definition: chan_iax2.c:1962
struct ast_format * iax2_codec_pref_index(struct iax2_codec_pref *pref, int idx, struct ast_format **result)
Codec located at a particular place in the preference index.
Definition: codec_pref.c:77
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324

References iax2_peer::addr, ast_channel_tech(), ast_channel_tech_pvt(), ast_copy_string(), AST_FORMAT_CAP_NAMES_LEN, ast_format_get_name(), ast_sockaddr_isnull(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_strdupa, ast_test_flag64, buf, iax2_peer::callno, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), iax2_codec_pref_index(), iax2_getformatname_multiple(), iax2_tech, IAX_DYNAMIC, iaxs, len(), iax2_peer::mailbox, peer_status(), peer_unref(), iax2_peer::prefs, and PTR_TO_CALLNO.

◆ get_auth_methods()

static int get_auth_methods ( const char *  value)
static

Definition at line 12825 of file chan_iax2.c.

12826{
12827 int methods = 0;
12828 if (strstr(value, "rsa"))
12830 if (strstr(value, "md5"))
12832 if (strstr(value, "plaintext"))
12834 return methods;
12835}
static struct @450 methods[]

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, methods, and value.

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

◆ get_encrypt_methods()

static int get_encrypt_methods ( const char *  s)
static

Definition at line 1813 of file chan_iax2.c.

1814{
1815 int e;
1816 if (!strcasecmp(s, "aes128"))
1818 else if (ast_true(s))
1820 else
1821 e = 0;
1822 return e;
1823}

References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.

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

◆ get_from_jb()

static int get_from_jb ( const void *  p)
static

Definition at line 4261 of file chan_iax2.c.

4262{
4263#ifdef SCHED_MULTITHREADED
4264 if (schedule_action(__get_from_jb, data))
4265#endif
4266 __get_from_jb(data);
4267 return 0;
4268}
static void __get_from_jb(const void *p)
Definition: chan_iax2.c:4172

References __get_from_jb(), ast_frame::data, and schedule_action.

Referenced by update_jbsched().

◆ get_unused_callno()

static int get_unused_callno ( enum callno_type  type,
int  validated,
callno_entry entry 
)
static

Definition at line 2952 of file chan_iax2.c.

2953{
2954 struct call_number_pool *pool = NULL;
2955 callno_entry swap;
2956 size_t choice;
2957
2958 switch (type) {
2959 case CALLNO_TYPE_NORMAL:
2960 pool = &callno_pool;
2961 break;
2962 case CALLNO_TYPE_TRUNK:
2963 pool = &callno_pool_trunk;
2964 break;
2965 default:
2966 ast_assert(0);
2967 break;
2968 }
2969
2970 /* If we fail, make sure this has a defined value */
2971 *entry = 0;
2972
2973 /* We lock here primarily to ensure thread safety of the
2974 * total_nonval_callno_used check and increment */
2976
2977 /* Bail out if we don't have any available call numbers */
2978 if (!pool->available) {
2979 ast_log(LOG_WARNING, "Out of call numbers\n");
2981 return 1;
2982 }
2983
2984 /* Only a certain number of non-validated call numbers should be allocated.
2985 * If there ever is an attack, this separates the calltoken validating users
2986 * from the non-calltoken validating users. */
2989 "NON-CallToken callnumber limit is reached. Current: %d Max: %d\n",
2993 return 1;
2994 }
2995
2996 /* We use a modified Fisher-Yates-Durstenfeld Shuffle to maintain a list of
2997 * available call numbers. The array of call numbers begins as an ordered
2998 * list from 1 -> n, and we keep a running tally of how many remain unclaimed
2999 * - let's call that x. When a call number is needed we pick a random index
3000 * into the array between 0 and x and use that as our call number. In a
3001 * typical FYD shuffle, we would swap the value that we are extracting with
3002 * the number at x, but in our case we swap and don't touch the value at x
3003 * because it is effectively invisible. We rely on the rest of the IAX2 core
3004 * to return the number to us at some point. Finally, we decrement x by 1
3005 * which establishes our new unused range.
3006 *
3007 * When numbers are returned to the pool, we put them just past x and bump x
3008 * by 1 so that this number is now available for re-use. */
3009
3010 choice = ast_random() % pool->available;
3011
3012 *entry = pool->numbers[choice];
3013 swap = pool->numbers[pool->available - 1];
3014
3015 pool->numbers[choice] = swap;
3016 pool->available--;
3017
3018 if (validated) {
3020 } else {
3022 }
3023
3025
3026 return 0;
3027}
static uint16_t global_maxcallno_nonval
Definition: chan_iax2.c:1021
static ast_mutex_t callno_pool_lock
Definition: chan_iax2.c:963
#define CALLNO_ENTRY_SET_VALIDATED(a)
Definition: chan_iax2.c:953
static uint16_t total_nonval_callno_used
Definition: chan_iax2.c:1023

References ast_assert, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_random(), call_number_pool::available, CALLNO_ENTRY_SET_VALIDATED, callno_pool, callno_pool_lock, callno_pool_trunk, CALLNO_TYPE_NORMAL, CALLNO_TYPE_TRUNK, global_maxcallno_nonval, LOG_WARNING, NULL, call_number_pool::numbers, total_nonval_callno_used, and type.

Referenced by __find_callno(), and make_trunk().

◆ handle_call_token()

static int handle_call_token ( struct ast_iax2_full_hdr fh,
struct iax_ies ies,
struct ast_sockaddr addr,
int  fd 
)
static

Definition at line 4990 of file chan_iax2.c.

4992{
4993#define CALLTOKEN_HASH_FORMAT "%s%u%d" /* address + port + ts + randomcalldata */
4994#define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */
4995 struct ast_str *buf = ast_str_alloca(256);
4996 time_t t = time(NULL);
4997 char hash[41]; /* 40 char sha1 hash */
4998 int subclass = uncompress_subclass(fh->csub);
4999
5000 /* ----- Case 1 ----- */
5001 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */
5002 struct iax_ie_data ied = {
5003 .buf = { 0 },
5004 .pos = 0,
5005 };
5006
5007 /* create the hash with their address data and our timestamp */
5010
5011 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
5013 send_apathetic_reply(1, ntohs(fh->scallno), addr, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
5014
5015 return 1;
5016
5017 /* ----- Case 2 ----- */
5018 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */
5019 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */
5020 char *rec_ts = NULL; /* received timestamp */
5021 unsigned int rec_time; /* received time_t */
5022
5023 /* split the timestamp from the hash data */
5024 rec_hash = strchr((char *) ies->calltokendata, '?');
5025 if (rec_hash) {
5026 *rec_hash++ = '\0';
5027 rec_ts = (char *) ies->calltokendata;
5028 }
5029
5030 /* check that we have valid data before we do any comparisons */
5031 if (!rec_hash || !rec_ts) {
5032 goto reject;
5033 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
5034 goto reject;
5035 }
5036
5037 /* create a hash with their address and the _TOKEN'S_ timestamp */
5040
5041 /* compare hashes and then check timestamp delay */
5042 if (strcmp(hash, rec_hash)) {
5043 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_sockaddr_stringify(addr));
5044 goto reject; /* received hash does not match ours, reject */
5045 } else if ((t < rec_time) || ((t - rec_time) >= max_calltoken_delay)) {
5046 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_sockaddr_stringify(addr));
5047 goto reject; /* too much delay, reject */
5048 }
5049
5050 /* at this point the call token is valid, returning 0
5051 * will allow socket_process to continue as usual */
5052 requirecalltoken_mark_auto(ies->username, subclass);
5053 return 0;
5054
5055 /* ----- Case 3 ----- */
5056 } else { /* calltokens are not supported for this client, how do we respond? */
5057 if (calltoken_required(addr, ies->username, subclass)) {
5058 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenoptional list or setting user %s requirecalltoken=no\n", ast_sockaddr_stringify(addr), S_OR(ies->username, "guest"));
5059 goto reject;
5060 }
5061 return 0; /* calltoken is not required for this addr, so permit it. */
5062 }
5063
5064reject:
5065 /* received frame has failed calltoken inspection, send apathetic reject messages */
5066 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
5067 send_apathetic_reply(1, ntohs(fh->scallno), addr, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
5068 } else {
5069 send_apathetic_reply(1, ntohs(fh->scallno), addr, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
5070 }
5071
5072 return 1;
5073}
static int randomcalltokendata
Definition: chan_iax2.c:984
static time_t max_calltoken_delay
Definition: chan_iax2.c:986
#define CALLTOKEN_IE_FORMAT
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)
Definition: chan_iax2.c:4830
#define CALLTOKEN_HASH_FORMAT
static void requirecalltoken_mark_auto(const char *name, int subclass)
Definition: chan_iax2.c:4950
@ IAX_COMMAND_REGREL
Definition: iax2.h:73
@ IAX_COMMAND_CALLTOKEN
Definition: iax2.h:119
@ IAX_COMMAND_REGREQ
Definition: iax2.h:65
unsigned int ts
Definition: iax2.h:233
unsigned char iseqno
Definition: iax2.h:235
unsigned char * calltokendata
Definition: parser.h:85
unsigned char calltoken
Definition: parser.h:84
void ast_sha1_hash(char *output, const char *input)
Produces SHA1 hash based on input string.
Definition: utils.c:266

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

Referenced by socket_process_helper().

◆ handle_cli_iax2_provision()

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

Definition at line 12446 of file chan_iax2.c.

12447{
12448 int force = 0;
12449 int res;
12450
12451 switch (cmd) {
12452 case CLI_INIT:
12453 e->command = "iax2 provision";
12454 e->usage =
12455 "Usage: iax2 provision <host> <template> [forced]\n"
12456 " Provisions the given peer or IP address using a template\n"
12457 " matching either 'template' or '*' if the template is not\n"
12458 " found. If 'forced' is specified, even empty provisioning\n"
12459 " fields will be provisioned as empty fields.\n";
12460 return NULL;
12461 case CLI_GENERATE:
12462 if (a->pos == 3)
12463 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
12464 return NULL;
12465 }
12466
12467 if (a->argc < 4)
12468 return CLI_SHOWUSAGE;
12469 if (a->argc > 4) {
12470 if (!strcasecmp(a->argv[4], "forced"))
12471 force = 1;
12472 else
12473 return CLI_SHOWUSAGE;
12474 }
12475 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
12476 if (res < 0)
12477 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
12478 else if (res < 1)
12479 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
12480 else
12481 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
12482 return CLI_SUCCESS;
12483}
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
char * iax_prov_complete_template(const char *line, const char *word, int pos, int state)
Definition: provision.c:179
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static struct test_val a

References a, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_provision(), iax_prov_complete_template(), NULL, and ast_cli_entry::usage.

◆ handle_cli_iax2_prune_realtime()

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

Definition at line 3687 of file chan_iax2.c.

3688{
3689 struct iax2_peer *peer = NULL;
3690 struct iax2_user *user = NULL;
3691 static const char * const choices[] = { "all", NULL };
3692 char *cmplt;
3693
3694 switch (cmd) {
3695 case CLI_INIT:
3696 e->command = "iax2 prune realtime";
3697 e->usage =
3698 "Usage: iax2 prune realtime [<peername>|all]\n"
3699 " Prunes object(s) from the cache\n";
3700 return NULL;
3701 case CLI_GENERATE:
3702 if (a->pos == 3) {
3703 cmplt = ast_cli_complete(a->word, choices, a->n);
3704 if (!cmplt)
3705 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
3706 return cmplt;
3707 }
3708 return NULL;
3709 }
3710 if (a->argc != 4)
3711 return CLI_SHOWUSAGE;
3712 if (!strcmp(a->argv[3], "all")) {
3713 prune_users();
3714 prune_peers();
3715 ast_cli(a->fd, "Cache flushed successfully.\n");
3716 return CLI_SUCCESS;
3717 }
3718 peer = find_peer(a->argv[3], 0);
3719 user = find_user(a->argv[3]);
3720 if (peer || user) {
3721 if (peer) {
3725 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
3726 } else {
3727 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
3728 }
3729 peer_unref(peer);
3730 }
3731 if (user) {
3734 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
3735 } else {
3736 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
3737 }
3740 }
3741 } else {
3742 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
3743 }
3744
3745 return CLI_SUCCESS;
3746}
static char * complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags)
Definition: chan_iax2.c:3938
static void prune_peers(void)
Definition: chan_iax2.c:13614
static void prune_users(void)
Definition: chan_iax2.c:13598
static int expire_registry(const void *data)
Definition: chan_iax2.c:9081
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: main/cli.c:1841

References a, ao2_unlink, ast_cli(), ast_cli_complete(), ast_set_flag64, ast_test_flag64, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), expire_registry(), find_peer(), find_user(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, NULL, peer_ref(), peer_unref(), prune_peers(), prune_users(), ast_cli_entry::usage, and user_unref().

◆ handle_cli_iax2_reload()

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

Definition at line 14211 of file chan_iax2.c.

14212{
14213 switch (cmd) {
14214 case CLI_INIT:
14215 e->command = "iax2 reload";
14216 e->usage =
14217 "Usage: iax2 reload\n"
14218 " Reloads IAX configuration from iax.conf\n";
14219 return NULL;
14220 case CLI_GENERATE:
14221 return NULL;
14222 }
14223
14224 reload_config(0);
14225
14226 return CLI_SUCCESS;
14227}

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

◆ handle_cli_iax2_set_debug()

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

Definition at line 7684 of file chan_iax2.c.

7685{
7686 switch (cmd) {
7687 case CLI_INIT:
7688 e->command = "iax2 set debug {on|off|peer}";
7689 e->usage =
7690 "Usage: iax2 set debug {on|off|peer peername}\n"
7691 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
7692 return NULL;
7693 case CLI_GENERATE:
7694 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
7695 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
7696 return NULL;
7697 }
7698
7699 if (a->argc < e->args || a->argc > e->args + 1)
7700 return CLI_SHOWUSAGE;
7701
7702 if (!strcasecmp(a->argv[3], "peer")) {
7703 struct iax2_peer *peer;
7704
7705 if (a->argc != e->args + 1)
7706 return CLI_SHOWUSAGE;
7707
7708 peer = find_peer(a->argv[4], 1);
7709
7710 if (!peer) {
7711 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
7712 return CLI_FAILURE;
7713 }
7714
7716
7717 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_port(&debugaddr));
7718
7719 ao2_ref(peer, -1);
7720 } else if (!strncasecmp(a->argv[3], "on", 2)) {
7721 iaxdebug = 1;
7722 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
7723 } else {
7724 iaxdebug = 0;
7725 memset(&debugaddr, 0, sizeof(debugaddr));
7726 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
7727 }
7728 return CLI_SUCCESS;
7729}
static struct ast_sockaddr debugaddr
Definition: chan_iax2.c:1225
#define CLI_FAILURE
Definition: cli.h:46
int args
This gets set in ast_cli_register()
Definition: cli.h:185

References a, iax2_peer::addr, ao2_ref, ast_cli_entry::args, ast_cli(), ast_sockaddr_copy(), ast_sockaddr_stringify_port(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), debugaddr, find_peer(), iaxdebug, NULL, and ast_cli_entry::usage.

◆ handle_cli_iax2_set_debug_jb()

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

Definition at line 7757 of file chan_iax2.c.

7758{
7759 switch (cmd) {
7760 case CLI_INIT:
7761 e->command = "iax2 set debug jb {on|off}";
7762 e->usage =
7763 "Usage: iax2 set debug jb {on|off}\n"
7764 " Enables/Disables jitterbuffer debugging information\n";
7765 return NULL;
7766 case CLI_GENERATE:
7767 return NULL;
7768 }
7769
7770 if (a->argc != e->args)
7771 return CLI_SHOWUSAGE;
7772
7773 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
7775 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
7776 } else {
7778 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
7779 }
7780 return CLI_SUCCESS;
7781}
static void jb_error_output(const char *fmt,...)
Definition: chan_iax2.c:1256
static void jb_debug_output(const char *fmt,...)
Definition: chan_iax2.c:1280
static void jb_warning_output(const char *fmt,...)
Definition: chan_iax2.c:1268
void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg)
Definition: jitterbuf.c:55

References a, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), NULL, and ast_cli_entry::usage.

◆ handle_cli_iax2_set_debug_trunk()

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

Definition at line 7731 of file chan_iax2.c.

7732{
7733 switch (cmd) {
7734 case CLI_INIT:
7735 e->command = "iax2 set debug trunk {on|off}";
7736 e->usage =
7737 "Usage: iax2 set debug trunk {on|off}\n"
7738 " Enables/Disables debugging of IAX trunking\n";
7739 return NULL;
7740 case CLI_GENERATE:
7741 return NULL;
7742 }
7743
7744 if (a->argc != e->args)
7745 return CLI_SHOWUSAGE;
7746
7747 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
7748 iaxtrunkdebug = 1;
7749 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
7750 } else {
7751 iaxtrunkdebug = 0;
7752 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
7753 }
7754 return CLI_SUCCESS;
7755}
static int iaxtrunkdebug
Definition: chan_iax2.c:463

References a, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iaxtrunkdebug, NULL, and ast_cli_entry::usage.

◆ handle_cli_iax2_set_mtu()

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

Set trunk MTU from CLI.

Definition at line 4007 of file chan_iax2.c.

4008{
4009 int mtuv;
4010
4011 switch (cmd) {
4012 case CLI_INIT:
4013 e->command = "iax2 set mtu";
4014 e->usage =
4015 "Usage: iax2 set mtu <value>\n"
4016 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
4017 " zero to disable. Disabling means that the operating system\n"
4018 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
4019 " packet exceeds the UDP payload size. This is substantially\n"
4020 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
4021 " greater for G.711 samples.\n";
4022 return NULL;
4023 case CLI_GENERATE:
4024 return NULL;
4025 }
4026
4027 if (a->argc != 4)
4028 return CLI_SHOWUSAGE;
4029 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
4030 mtuv = MAX_TRUNK_MTU;
4031 else
4032 mtuv = atoi(a->argv[3]);
4033
4034 if (mtuv == 0) {
4035 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
4037 return CLI_SUCCESS;
4038 }
4039 if (mtuv < 172 || mtuv > 4000) {
4040 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
4041 return CLI_SHOWUSAGE;
4042 }
4043 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
4044 global_max_trunk_mtu = mtuv;
4045 return CLI_SUCCESS;
4046}
#define MAX_TRUNK_MTU
Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516...
Definition: chan_iax2.c:315
static int global_max_trunk_mtu
Definition: chan_iax2.c:317

References a, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, global_max_trunk_mtu, MAX_TRUNK_MTU, NULL, and ast_cli_entry::usage.

◆ handle_cli_iax2_show_cache()

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

Definition at line 4048 of file chan_iax2.c.

4049{
4050 struct iax2_dpcache *dp = NULL;
4051 char tmp[1024], *pc = NULL;
4052 int s, x, y;
4053 struct timeval now = ast_tvnow();
4054
4055 switch (cmd) {
4056 case CLI_INIT:
4057 e->command = "iax2 show cache";
4058 e->usage =
4059 "Usage: iax2 show cache\n"
4060 " Display currently cached IAX Dialplan results.\n";
4061 return NULL;
4062 case CLI_GENERATE:
4063 return NULL;
4064 }
4065
4067
4068 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
4069
4070 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
4071 s = dp->expiry.tv_sec - now.tv_sec;
4072 tmp[0] = '\0';
4073 if (dp->flags & CACHE_FLAG_EXISTS)
4074 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
4075 if (dp->flags & CACHE_FLAG_NONEXISTENT)
4076 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
4077 if (dp->flags & CACHE_FLAG_CANEXIST)
4078 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
4079 if (dp->flags & CACHE_FLAG_PENDING)
4080 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
4081 if (dp->flags & CACHE_FLAG_TIMEOUT)
4082 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
4083 if (dp->flags & CACHE_FLAG_TRANSMITTED)
4084 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
4085 if (dp->flags & CACHE_FLAG_MATCHMORE)
4086 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
4087 if (dp->flags & CACHE_FLAG_UNKNOWN)
4088 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
4089 /* Trim trailing pipe */
4090 if (!ast_strlen_zero(tmp)) {
4091 tmp[strlen(tmp) - 1] = '\0';
4092 } else {
4093 ast_copy_string(tmp, "(none)", sizeof(tmp));
4094 }
4095 y = 0;
4096 pc = strchr(dp->peercontext, '@');
4097 if (!pc) {
4098 pc = dp->peercontext;
4099 } else {
4100 pc++;
4101 }
4102 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
4103 if (dp->waiters[x] > -1)
4104 y++;
4105 }
4106 if (s > 0) {
4107 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
4108 } else {
4109 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
4110 }
4111 }
4112
4114
4115 return CLI_SUCCESS;
4116}

References a, ARRAY_LEN, ast_cli(), ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_tvnow(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, CACHE_FLAG_TRANSMITTED, CACHE_FLAG_UNKNOWN, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, NULL, iax2_dpcache::peercontext, tmp(), ast_cli_entry::usage, and iax2_dpcache::waiters.

◆ handle_cli_iax2_show_callno_limits()

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

Definition at line 2883 of file chan_iax2.c.

2884{
2885 struct ao2_iterator i;
2886 struct peercnt *peercnt;
2887 struct ast_sockaddr addr;
2888 int found = 0;
2889
2890 switch (cmd) {
2891 case CLI_INIT:
2892 e->command = "iax2 show callnumber usage";
2893 e->usage =
2894 "Usage: iax2 show callnumber usage [IP address]\n"
2895 " Shows current IP addresses which are consuming iax2 call numbers\n";
2896 return NULL;
2897 case CLI_GENERATE:
2898 return NULL;
2899 case CLI_HANDLER:
2900 if (a->argc < 4 || a->argc > 5)
2901 return CLI_SHOWUSAGE;
2902
2903 if (a->argc == 4) {
2904 ast_cli(a->fd, "%-45s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
2905 }
2906
2908 while ((peercnt = ao2_iterator_next(&i))) {
2909 ast_sockaddr_copy(&addr, &peercnt->addr);
2910
2911 if (a->argc == 5) {
2912 if (!strcasecmp(a->argv[4], ast_sockaddr_stringify(&addr))) {
2913 ast_cli(a->fd, "%-45s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
2914 ast_cli(a->fd, "%-45s %-12d %-12d\n", ast_sockaddr_stringify(&addr), peercnt->cur, peercnt->limit);
2915 ao2_ref(peercnt, -1);
2916 found = 1;
2917 break;
2918 }
2919 } else {
2920 ast_cli(a->fd, "%-45s %-12d %-12d\n", ast_sockaddr_stringify(&addr), peercnt->cur, peercnt->limit);
2921 }
2922 ao2_ref(peercnt, -1);
2923 }
2925
2926 if (a->argc == 4) {
2927 size_t pool_avail = callno_pool.available;
2928 size_t trunk_pool_avail = callno_pool_trunk.available;
2929
2930 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
2931 "Non-CallToken Validated Callno Used: %d\n",
2934
2935 ast_cli(a->fd, "Total Available Callno: %zu\n"
2936 "Regular Callno Available: %zu\n"
2937 "Trunk Callno Available: %zu\n",
2938 pool_avail + trunk_pool_avail,
2939 pool_avail,
2940 trunk_pool_avail);
2941 } else if (a->argc == 5 && !found) {
2942 ast_cli(a->fd, "No call number table entries for %s found\n", a->argv[4] );
2943 }
2944
2945
2946 return CLI_SUCCESS;
2947 default:
2948 return NULL;
2949 }
2950}
@ CLI_HANDLER
Definition: cli.h:154
struct ast_sockaddr addr
Definition: chan_iax2.c:1029
uint16_t limit
Definition: chan_iax2.c:1033
uint16_t cur
Definition: chan_iax2.c:1031

References a, peercnt::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli(), ast_sockaddr_copy(), ast_sockaddr_stringify(), call_number_pool::available, callno_pool, callno_pool_trunk, CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, peercnt::cur, global_maxcallno_nonval, peercnt::limit, NULL, peercnts, total_nonval_callno_used, and ast_cli_entry::usage.

◆ handle_cli_iax2_show_channels()

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

Definition at line 7511 of file chan_iax2.c.

7512{
7513#define FORMAT2 "%-20.20s %-40.40s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
7514#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"
7515#define FORMATB "%-20.20s %-40.40s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
7516 int x;
7517 int numchans = 0;
7518 char first_message[10] = { 0, };
7519 char last_message[10] = { 0, };
7520
7521 switch (cmd) {
7522 case CLI_INIT:
7523 e->command = "iax2 show channels";
7524 e->usage =
7525 "Usage: iax2 show channels\n"
7526 " Lists all currently active IAX channels.\n";
7527 return NULL;
7528 case CLI_GENERATE:
7529 return NULL;
7530 }
7531
7532 if (a->argc != 3)
7533 return CLI_SHOWUSAGE;
7534 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
7535 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
7536 ast_mutex_lock(&iaxsl[x]);
7537 if (iaxs[x]) {
7538 int lag, jitter, localdelay;
7539 jb_info jbinfo;
7541 jb_getinfo(iaxs[x]->jb, &jbinfo);
7542 jitter = jbinfo.jitter;
7543 localdelay = jbinfo.current - jbinfo.min;
7544 } else {
7545 jitter = -1;
7546 localdelay = 0;
7547 }
7548
7549 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
7550 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
7551 lag = iaxs[x]->remote_rr.delay;
7552 ast_cli(a->fd, FORMAT,
7553 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
7555 S_OR(iaxs[x]->username, "(None)"),
7556 iaxs[x]->callno, iaxs[x]->peercallno,
7557 iaxs[x]->oseqno, iaxs[x]->iseqno,
7558 lag,
7559 jitter,
7560 localdelay,
7561 iax2_getformatname(iaxs[x]->voiceformat),
7562 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7563 first_message,
7564 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7565 last_message);
7566 numchans++;
7567 }
7569 }
7570 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
7571 return CLI_SUCCESS;
7572#undef FORMAT
7573#undef FORMAT2
7574#undef FORMATB
7575}
#define FORMAT
const char * iax2_getformatname(iax2_format format)
iax2 wrapper function for ast_getformatname
Definition: chan_iax2.c:1950
#define FORMAT2

References a, iax2_registry::addr, ARRAY_LEN, ast_channel_name(), ast_cli(), ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_stringify_addr(), ast_test_flag64, iax2_registry::callno, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, jb_info::current, iax_rr::delay, FORMAT, FORMAT2, iax2_getformatname(), iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, MARK_IAX_SUBCLASS_TX, jb_info::min, NULL, chan_iax2_pvt::owner, chan_iax2_pvt::remote_rr, S_OR, ast_cli_entry::usage, and iax2_registry::username.

◆ handle_cli_iax2_show_firmware()

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

Definition at line 7318 of file chan_iax2.c.

7319{
7320 switch (cmd) {
7321 case CLI_INIT:
7322 e->command = "iax2 show firmware";
7323 e->usage =
7324 "Usage: iax2 show firmware\n"
7325 " Lists all known IAX firmware images.\n";
7326 return NULL;
7327 case CLI_GENERATE:
7328 return NULL;
7329 }
7330
7331 if (a->argc != 3 && a->argc != 4)
7332 return CLI_SHOWUSAGE;
7333
7334 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
7335
7337 a->argc == 3 ? NULL : a->argv[3],
7339 (void *) &a->fd);
7340
7341 return CLI_SUCCESS;
7342}
static int firmware_show_callback(struct ast_iax2_firmware_header *header, void *user_data)
Definition: chan_iax2.c:7305
void iax_firmware_traverse(const char *filter, int(*callback)(struct ast_iax2_firmware_header *header, void *data), void *data)
Definition: firmware.c:321

References a, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, firmware_show_callback(), iax_firmware_traverse(), NULL, and ast_cli_entry::usage.

◆ handle_cli_iax2_show_netstats()

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

Definition at line 7661 of file chan_iax2.c.

7662{
7663 int numchans = 0;
7664
7665 switch (cmd) {
7666 case CLI_INIT:
7667 e->command = "iax2 show netstats";
7668 e->usage =
7669 "Usage: iax2 show netstats\n"
7670 " Lists network status for all currently active IAX channels.\n";
7671 return NULL;
7672 case CLI_GENERATE:
7673 return NULL;
7674 }
7675 if (a->argc != 3)
7676 return CLI_SHOWUSAGE;
7677 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
7678 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
7679 numchans = ast_cli_netstats(NULL, a->fd, 1);
7680 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
7681 return CLI_SUCCESS;
7682}
static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
Definition: chan_iax2.c:7577

References a, ast_cli(), ast_cli_netstats(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, and ast_cli_entry::usage.

◆ handle_cli_iax2_show_peer()

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

Show one peer in detail.

Definition at line 3862 of file chan_iax2.c.

3863{
3864 char status[64];
3865 char cbuf[256];
3866 struct iax2_peer *peer;
3867 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
3868 struct ast_str *encmethods = ast_str_alloca(256);
3869 int load_realtime = 0;
3870
3871 switch (cmd) {
3872 case CLI_INIT:
3873 e->command = "iax2 show peer";
3874 e->usage =
3875 "Usage: iax2 show peer <name>\n"
3876 " Display details on specific IAX peer\n";
3877 return NULL;
3878 case CLI_GENERATE:
3879 if (a->pos == 3)
3880 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
3881 return NULL;
3882 }
3883
3884 if (a->argc < 4)
3885 return CLI_SHOWUSAGE;
3886
3887 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
3888
3889 peer = find_peer(a->argv[3], load_realtime);
3890 if (peer) {
3891 char *str_addr, *str_defaddr;
3892 char *str_port, *str_defport;
3893
3894 str_addr = ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr));
3895 str_port = ast_strdupa(ast_sockaddr_stringify_port(&peer->addr));
3896 str_defaddr = ast_strdupa(ast_sockaddr_stringify_addr(&peer->defaddr));
3897 str_defport = ast_strdupa(ast_sockaddr_stringify_port(&peer->defaddr));
3898
3899 encmethods_to_str(peer->encmethods, &encmethods);
3900 ast_cli(a->fd, "\n\n");
3901 ast_cli(a->fd, " * Name : %s\n", peer->name);
3902 ast_cli(a->fd, " Description : %s\n", peer->description);
3903 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
3904 ast_cli(a->fd, " Context : %s\n", peer->context);
3905 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
3906 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
3907 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
3908 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
3909 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
3910 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
3911 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
3912 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
3913 ast_cli(a->fd, " Expire : %d\n", peer->expire);
3914 ast_cli(a->fd, " ACL : %s\n", (ast_acl_list_is_empty(peer->acl) ? "No" : "Yes"));
3915 ast_cli(a->fd, " Addr->IP : %s Port %s\n", str_addr ? str_addr : "(Unspecified)", str_port);
3916 ast_cli(a->fd, " Defaddr->IP : %s Port %s\n", str_defaddr, str_defport);
3917 ast_cli(a->fd, " Username : %s\n", peer->username);
3918 ast_cli(a->fd, " Codecs : %s\n", iax2_getformatname_multiple(peer->capability, &codec_buf));
3919
3920 if (iax2_codec_pref_string(&peer->prefs, cbuf, sizeof(cbuf)) < 0) {
3921 strcpy(cbuf, "Error"); /* Safe */
3922 }
3923 ast_cli(a->fd, " Codec Order : %s\n", cbuf);
3924
3925 peer_status(peer, status, sizeof(status));
3926 ast_cli(a->fd, " Status : %s\n", status);
3927 ast_cli(a->fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
3928 ast_cli(a->fd, "\n");
3929 peer_unref(peer);
3930 } else {
3931 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
3932 ast_cli(a->fd, "\n");
3933 }
3934
3935 return CLI_SUCCESS;
3936}
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
Definition: acl.c:540
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition: callerid.c:1273
int iax2_codec_pref_string(struct iax2_codec_pref *pref, char *buf, size_t size)
Dump audio codec preference list into a string.
Definition: codec_pref.c:178
const ast_string_field parkinglot
Definition: chan_iax2.c:599

References a, iax2_peer::acl, iax2_peer::addr, ast_acl_list_is_empty(), ast_callerid_merge(), ast_cli(), AST_FORMAT_CAP_NAMES_LEN, ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_str_alloca, ast_str_buffer(), ast_strdupa, ast_strlen_zero(), ast_test_flag64, CALLTOKEN_AUTO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), iax2_peer::context, iax2_peer::defaddr, iax2_peer::description, iax2_peer::encmethods, encmethods_to_str(), iax2_peer::expire, find_peer(), iax2_codec_pref_string(), iax2_getformatname_multiple(), IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mailbox, iax2_peer::maxcallno, iax2_peer::name, NULL, iax2_peer::parkinglot, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, iax2_peer::secret, iax2_peer::smoothing, status, ast_cli_entry::usage, and iax2_peer::username.

◆ handle_cli_iax2_show_peers()

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

Definition at line 7273 of file chan_iax2.c.

7274{
7275 switch (cmd) {
7276 case CLI_INIT:
7277 e->command = "iax2 show peers";
7278 e->usage =
7279 "Usage: iax2 show peers [registered] [like <pattern>]\n"
7280 " Lists all known IAX2 peers.\n"
7281 " Optional 'registered' argument lists only peers with known addresses.\n"
7282 " Optional regular expression pattern is used to filter the peer list.\n";
7283 return NULL;
7284 case CLI_GENERATE:
7285 return NULL;
7286 }
7287
7288 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
7289 case RESULT_SHOWUSAGE:
7290 return CLI_SHOWUSAGE;
7291 case RESULT_FAILURE:
7292 return CLI_FAILURE;
7293 default:
7294 return CLI_SUCCESS;
7295 }
7296}
static int __iax2_show_peers(int fd, int *total, struct mansession *s, const int argc, const char *const argv[])
Definition: chan_iax2.c:7046
#define RESULT_FAILURE
Definition: cli.h:42

References __iax2_show_peers(), a, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, RESULT_FAILURE, RESULT_SHOWUSAGE, and ast_cli_entry::usage.

◆ handle_cli_iax2_show_registry()

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

Definition at line 7428 of file chan_iax2.c.

7429{
7430#define FORMAT2 "%-45.45s %-6.6s %-10.10s %-45.45s %8.8s %s\n"
7431#define FORMAT "%-45.45s %-6.6s %-10.10s %-45.45s %8d %s\n"
7432
7433 struct iax2_registry *reg = NULL;
7434 char host[80];
7435 char perceived[80];
7436 int counter = 0;
7437
7438 switch (cmd) {
7439 case CLI_INIT:
7440 e->command = "iax2 show registry";
7441 e->usage =
7442 "Usage: iax2 show registry\n"
7443 " Lists all registration requests and status.\n";
7444 return NULL;
7445 case CLI_GENERATE:
7446 return NULL;
7447 }
7448 if (a->argc != 3)
7449 return CLI_SHOWUSAGE;
7450 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
7453 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
7454
7455 snprintf(perceived, sizeof(perceived), "%s", ast_sockaddr_isnull(&reg->us) ? "<Unregistered>" : ast_sockaddr_stringify(&reg->us));
7456
7457 ast_cli(a->fd, FORMAT, host,
7458 (reg->dnsmgr) ? "Y" : "N",
7459 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
7460 counter++;
7461 }
7463 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
7464 return CLI_SUCCESS;
7465#undef FORMAT
7466#undef FORMAT2
7467}
static char * regstate2str(int regstate)
Definition: chan_iax2.c:7406
char username[80]
Definition: chan_iax2.c:687

References a, iax2_registry::addr, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_isnull(), ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_registry::dnsmgr, FORMAT, FORMAT2, NULL, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), iax2_registry::us, ast_cli_entry::usage, and iax2_registry::username.

◆ handle_cli_iax2_show_stats()

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

Definition at line 3961 of file chan_iax2.c.

3962{
3963 struct iax_frame *cur;
3964 int cnt = 0, dead = 0, final = 0, i = 0;
3965
3966 switch (cmd) {
3967 case CLI_INIT:
3968 e->command = "iax2 show stats";
3969 e->usage =
3970 "Usage: iax2 show stats\n"
3971 " Display statistics on IAX channel driver.\n";
3972 return NULL;
3973 case CLI_GENERATE:
3974 return NULL;
3975 }
3976
3977 if (a->argc != 3)
3978 return CLI_SHOWUSAGE;
3979
3980 for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
3981 ast_mutex_lock(&iaxsl[i]);
3983 if (cur->retries < 0)
3984 dead++;
3985 if (cur->final)
3986 final++;
3987 cnt++;
3988 }
3990 }
3991
3992 ast_cli(a->fd, " IAX Statistics\n");
3993 ast_cli(a->fd, "---------------------\n");
3994 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
3995 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
3997 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
3998
4002
4003 return CLI_SUCCESS;
4004}
static int trunk_untimed
Definition: chan_iax2.c:318
static int trunk_maxmtu
Definition: chan_iax2.c:318
static int trunk_nmaxmtu
Definition: chan_iax2.c:318
static int trunk_timed
Definition: chan_iax2.c:318
int iax_get_iframes(void)
Definition: parser.c:1350
int iax_get_oframes(void)
Definition: parser.c:1351
int iax_get_frames(void)
Definition: parser.c:1349

References a, ARRAY_LEN, ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax_frame::final, frame_queue, global_max_trunk_mtu, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxsl, iax_frame::list, NULL, iax_frame::retries, trunk_maxmtu, trunk_nmaxmtu, trunk_timed, trunk_untimed, and ast_cli_entry::usage.

◆ handle_cli_iax2_show_threads()

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

Definition at line 7138 of file chan_iax2.c.

7139{
7140 struct iax2_thread *thread = NULL;
7141 time_t t;
7142 int threadcount = 0, dynamiccount = 0;
7143 char type;
7144
7145 switch (cmd) {
7146 case CLI_INIT:
7147 e->command = "iax2 show threads";
7148 e->usage =
7149 "Usage: iax2 show threads\n"
7150 " Lists status of IAX helper threads\n";
7151 return NULL;
7152 case CLI_GENERATE:
7153 return NULL;
7154 }
7155 if (a->argc != 3)
7156 return CLI_SHOWUSAGE;
7157
7158 ast_cli(a->fd, "IAX2 Thread Information\n");
7159 time(&t);
7160 ast_cli(a->fd, "Idle Threads:\n");
7163#ifdef DEBUG_SCHED_MULTITHREAD
7164 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d, func='%s'\n",
7165 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
7166#else
7167 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d\n",
7168 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
7169#endif
7170 threadcount++;
7171 }
7173 ast_cli(a->fd, "Active Threads:\n");
7176 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
7177 type = 'D';
7178 else
7179 type = 'P';
7180#ifdef DEBUG_SCHED_MULTITHREAD
7181 ast_cli(a->fd, "Thread %c%d: state=%u, update=%d, actions=%d, func='%s'\n",
7182 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
7183#else
7184 ast_cli(a->fd, "Thread %c%d: state=%u, update=%d, actions=%d\n",
7185 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
7186#endif
7187 threadcount++;
7188 }
7190 ast_cli(a->fd, "Dynamic Threads:\n");
7193#ifdef DEBUG_SCHED_MULTITHREAD
7194 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d, func='%s'\n",
7195 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
7196#else
7197 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d\n",
7198 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
7199#endif
7200 dynamiccount++;
7201 }
7203 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
7204 return CLI_SUCCESS;
7205}
static int iaxthreadcount
Definition: chan_iax2.c:720

References a, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, IAX_THREAD_TYPE_DYNAMIC, iaxthreadcount, iax2_thread::list, NULL, thread, type, and ast_cli_entry::usage.

◆ handle_cli_iax2_show_users()

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

Definition at line 6857 of file chan_iax2.c.

6858{
6859 regex_t regexbuf;
6860 int havepattern = 0;
6861
6862#define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
6863#define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
6864
6865 struct iax2_user *user = NULL;
6866 char auth[90];
6867 char *pstr = "";
6868 struct ao2_iterator i;
6869
6870 switch (cmd) {
6871 case CLI_INIT:
6872 e->command = "iax2 show users [like]";
6873 e->usage =
6874 "Usage: iax2 show users [like <pattern>]\n"
6875 " Lists all known IAX2 users.\n"
6876 " Optional regular expression pattern is used to filter the user list.\n";
6877 return NULL;
6878 case CLI_GENERATE:
6879 return NULL;
6880 }
6881
6882 switch (a->argc) {
6883 case 5:
6884 if (!strcasecmp(a->argv[3], "like")) {
6885 if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
6886 return CLI_SHOWUSAGE;
6887 havepattern = 1;
6888 } else
6889 return CLI_SHOWUSAGE;
6890 case 3:
6891 break;
6892 default:
6893 return CLI_SHOWUSAGE;
6894 }
6895
6896 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
6897 i = ao2_iterator_init(users, 0);
6898 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
6899 if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
6900 continue;
6901
6902 if (!ast_strlen_zero(user->secret)) {
6903 ast_copy_string(auth,user->secret, sizeof(auth));
6904 } else if (!ast_strlen_zero(user->inkeys)) {
6905 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
6906 } else
6907 ast_copy_string(auth, "-no secret-", sizeof(auth));
6908
6910 pstr = "REQ Only";
6912 pstr = "Disabled";
6913 else
6914 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
6915
6916 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
6917 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
6918 ast_acl_list_is_empty(user->acl) ? "No" : "Yes", pstr);
6919 }
6921
6922 if (havepattern)
6923 regfree(&regexbuf);
6924
6925 return CLI_SUCCESS;
6926#undef FORMAT
6927#undef FORMAT2
6928}

References a, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_acl_list_is_empty(), ast_cli(), ast_copy_string(), ast_strlen_zero(), ast_test_flag64, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, DEFAULT_CONTEXT, FORMAT, FORMAT2, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, NULL, ast_cli_entry::usage, and user_unref().

◆ handle_cli_iax2_test_losspct()

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

Definition at line 3748 of file chan_iax2.c.

3749{
3750 switch (cmd) {
3751 case CLI_INIT:
3752 e->command = "iax2 test losspct";
3753 e->usage =
3754 "Usage: iax2 test losspct <percentage>\n"
3755 " For testing, throws away <percentage> percent of incoming packets\n";
3756 return NULL;
3757 case CLI_GENERATE:
3758 return NULL;
3759 }
3760 if (a->argc != 4)
3761 return CLI_SHOWUSAGE;
3762
3763 test_losspct = atoi(a->argv[3]);
3764
3765 return CLI_SUCCESS;
3766}
static int test_losspct
Definition: chan_iax2.c:465

References a, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, test_losspct, and ast_cli_entry::usage.

◆ handle_cli_iax2_unregister()

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

Definition at line 7207 of file chan_iax2.c.

7208{
7209 struct iax2_peer *p;
7210
7211 switch (cmd) {
7212 case CLI_INIT:
7213 e->command = "iax2 unregister";
7214 e->usage =
7215 "Usage: iax2 unregister <peername>\n"
7216 " Unregister (force expiration) an IAX2 peer from the registry.\n";
7217 return NULL;
7218 case CLI_GENERATE:
7219 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
7220 }
7221
7222 if (a->argc != 3)
7223 return CLI_SHOWUSAGE;
7224
7225 p = find_peer(a->argv[2], 1);
7226 if (p) {
7227 if (p->expire > -1) {
7228 struct iax2_peer *peer;
7229
7230 peer = ao2_find(peers, a->argv[2], OBJ_KEY);
7231 if (peer) {
7232 expire_registry(peer_ref(peer)); /* will release its own reference when done */
7233 peer_unref(peer); /* ref from ao2_find() */
7234 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
7235 } else {
7236 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
7237 }
7238 } else {
7239 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
7240 }
7241 peer_unref(p);
7242 } else {
7243 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
7244 }
7245 return CLI_SUCCESS;
7246}
static char * complete_iax2_unregister(const char *line, const char *word, int pos, int state)
Definition: chan_iax2.c:7248

References a, ao2_find, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_unregister(), iax2_peer::expire, expire_registry(), find_peer(), NULL, OBJ_KEY, peer_ref(), peer_unref(), and ast_cli_entry::usage.

◆ handle_deferred_full_frames()

static void handle_deferred_full_frames ( struct iax2_thread thread)
static

Handle any deferred full frames for this thread.

Definition at line 9854 of file chan_iax2.c.

9855{
9856 struct iax2_pkt_buf *pkt_buf;
9857
9858 ast_mutex_lock(&thread->lock);
9859
9860 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
9861 ast_mutex_unlock(&thread->lock);
9862
9863 thread->buf = pkt_buf->buf;
9864 thread->buf_len = pkt_buf->len;
9865 thread->buf_size = pkt_buf->len + 1;
9866
9868
9869 thread->buf = NULL;
9870 ast_free(pkt_buf);
9871
9872 ast_mutex_lock(&thread->lock);
9873 }
9874
9875 ast_mutex_unlock(&thread->lock);
9876}
static int socket_process(struct iax2_thread *thread)
Definition: chan_iax2.c:12136

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

Referenced by iax2_process_thread().

◆ handle_error()

static int handle_error ( void  )
static

Definition at line 3402 of file chan_iax2.c.

3403{
3404 /* XXX Ideally we should figure out why an error occurred and then abort those
3405 rather than continuing to try. Unfortunately, the published interface does
3406 not seem to work XXX */
3407#if 0
3408 struct sockaddr_in *sin;
3409 int res;
3410 struct msghdr m;
3411 struct sock_extended_err e;
3412 m.msg_name = NULL;
3413 m.msg_namelen = 0;
3414 m.msg_iov = NULL;
3415 m.msg_control = &e;
3416 m.msg_controllen = sizeof(e);
3417 m.msg_flags = 0;
3418 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
3419 if (res < 0)
3420 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
3421 else {
3422 if (m.msg_controllen) {
3423 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
3424 if (sin)
3425 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
3426 else
3427 ast_log(LOG_WARNING, "No address detected??\n");
3428 } else {
3429 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
3430 }
3431 }
3432#endif
3433 return 0;
3434}
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:928
static int netsocket
Definition: pbx_dundi.c:186

References ast_inet_ntoa(), ast_log, errno, LOG_WARNING, netsocket, and NULL.

Referenced by send_packet(), socket_read(), and transmit_trunk().

◆ iax2_ack_registry()

static int iax2_ack_registry ( struct iax_ies ies,
struct ast_sockaddr addr,
int  callno 
)
static

Acknowledgment received for OUR registration.

Definition at line 8858 of file chan_iax2.c.

8859{
8860 struct iax2_registry *reg;
8861 /* Start pessimistic */
8862 char peer[256] = "";
8863 char msgstatus[60];
8864 int refresh = 60;
8865 char ourip[256] = "<Unspecified>";
8866 struct ast_sockaddr oldus;
8867 struct ast_sockaddr us;
8868 int oldmsgs;
8869
8870 if (!ast_sockaddr_isnull(&ies->apparent_addr)) {
8871 ast_sockaddr_copy(&us, &ies->apparent_addr);
8872 }
8873 if (ies->username) {
8874 ast_copy_string(peer, ies->username, sizeof(peer));
8875 }
8876 if (ies->refresh) {
8877 refresh = ies->refresh;
8878 }
8879 if (ies->calling_number) {
8880 /* We don't do anything with it really, but maybe we should */
8881 }
8882 reg = iaxs[callno]->reg;
8883 if (!reg) {
8884 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
8885 return -1;
8886 }
8887 ast_sockaddr_copy(&oldus, &reg->us);
8888 oldmsgs = reg->messages;
8889 if (ast_sockaddr_cmp(&reg->addr, addr)) {
8890 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_sockaddr_stringify(addr));
8891 return -1;
8892 }
8893 ast_sockaddr_copy(&reg->us, &us);
8894 if (ies->msgcount >= 0) {
8895 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */
8896 }
8897 /* always refresh the registration at the interval requested by the server
8898 we are registering to
8899 */
8900 reg->refresh = refresh;
8902 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
8903 if (ast_sockaddr_cmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
8904
8905 if (reg->messages > 255) {
8906 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
8907 } else if (reg->messages > 1) {
8908 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
8909 } else if (reg->messages > 0) {
8910 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
8911 } else {
8912 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
8913 }
8914
8915 snprintf(ourip, sizeof(ourip), "%s", ast_sockaddr_stringify(&reg->us));
8916
8917 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_sockaddr_stringify(addr), ourip, msgstatus);
8918 iax2_publish_registry(reg->username, ast_sockaddr_stringify(addr), "Registered", NULL);
8919 }
8921 return 0;
8922}
static void iax2_publish_registry(const char *username, const char *domain, const char *status, const char *cause)
Definition: chan_iax2.c:8852
static int iax2_do_register_s(const void *data)
Definition: chan_iax2.c:8701
#define ast_verb(level,...)
unsigned int refresh
struct ast_sockaddr apparent_addr
Definition: parser.h:52
int msgcount
Definition: parser.h:59

References iax2_registry::addr, iax_ies::apparent_addr, ast_copy_string(), ast_log, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_verb, iax_ies::calling_number, iax2_registry::expire, iax2_do_register_s(), iax2_publish_registry(), iax2_sched_replace(), iaxs, LOG_WARNING, iax2_registry::messages, iax_ies::msgcount, NULL, iax2_registry::refresh, iax_ies::refresh, refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, iax2_registry::us, iax2_registry::username, and iax_ies::username.

Referenced by socket_process_helper().

◆ iax2_allow_new()

static int attribute_pure iax2_allow_new ( int  frametype,
int  subclass,
int  inbound 
)
inlinestatic

Definition at line 3132 of file chan_iax2.c.

3133{
3134 if (frametype != AST_FRAME_IAX) {
3135 return 0;
3136 }
3137 switch (subclass) {
3138 case IAX_COMMAND_NEW:
3139 case IAX_COMMAND_REGREQ:
3141 case IAX_COMMAND_REGREL:
3142 return 1;
3143 case IAX_COMMAND_POKE:
3144 if (!inbound) {
3145 return 1;
3146 }
3147 break;
3148 }
3149 return 0;
3150}
@ IAX_COMMAND_FWDOWNL
Definition: iax2.h:111
@ IAX_COMMAND_POKE
Definition: iax2.h:99

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

Referenced by resend_with_token(), and socket_process_helper().

◆ iax2_answer()

static int iax2_answer ( struct ast_channel c)
static

Definition at line 5804 of file chan_iax2.c.

5805{
5806 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5807 ast_debug(1, "Answering IAX2 call\n");
5809}
static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int)
Definition: chan_iax2.c:7842
@ AST_CONTROL_ANSWER

References ast_channel_tech_pvt(), AST_CONTROL_ANSWER, ast_debug, AST_FRAME_CONTROL, c, NULL, PTR_TO_CALLNO, and send_command_locked().

◆ iax2_append_register()

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

Definition at line 8924 of file chan_iax2.c.

8926{
8927 struct iax2_registry *reg;
8928
8929 if (!(reg = ast_calloc(1, sizeof(*reg) + strlen(hostname) + 1))) {
8930 return -1;
8931 }
8932
8933 reg->addr.ss.ss_family = AST_AF_UNSPEC;
8934 if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
8935 ast_free(reg);
8936 return -1;
8937 }
8938
8939 ast_copy_string(reg->username, username, sizeof(reg->username));
8940 strcpy(reg->hostname, hostname); /* Note: This is safe */
8941
8942 if (secret) {
8943 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
8944 }
8945
8946 reg->expire = -1;
8948
8949 reg->port = ast_sockaddr_port(&reg->addr);
8950
8951 if (!porta && !reg->port) {
8952 reg->port = IAX_DEFAULT_PORTNO;
8953 } else if (porta) {
8954 sscanf(porta, "%5d", &reg->port);
8955 }
8956
8957 ast_sockaddr_set_port(&reg->addr, reg->port);
8958
8962
8963 return 0;
8964}
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
static char hostname[MAXHOSTNAMELEN]
Definition: logger.c:119
char secret[80]
Definition: chan_iax2.c:688

References iax2_registry::addr, AST_AF_UNSPEC, ast_calloc, ast_copy_string(), ast_dnsmgr_lookup(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_sockaddr_port, ast_sockaddr_set_port, iax2_registry::dnsmgr, iax2_registry::expire, iax2_registry::hostname, hostname, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, NULL, iax2_registry::port, iax2_registry::refresh, iax2_registry::secret, srvlookup, ast_sockaddr::ss, and iax2_registry::username.

Referenced by iax2_register().

◆ iax2_call()

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

Definition at line 5152 of file chan_iax2.c.

5153{
5154 struct ast_sockaddr addr;
5155 char *l=NULL, *n=NULL, *tmpstr;
5156 struct iax_ie_data ied;
5157 char *defaultrdest = "s";
5158 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5159 struct parsed_dial_string pds;
5160 struct create_addr_info cai;
5161 struct ast_var_t *var;
5163 const char* osp_token_ptr;
5164 unsigned int osp_token_length;
5165 unsigned char osp_block_index;
5166 unsigned int osp_block_length;
5167 unsigned char osp_buffer[256];
5168 char encoded_prefs[32];
5169 iax2_format iax2_tmpfmt;
5170
5172 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", ast_channel_name(c));
5173 return -1;
5174 }
5175
5176 memset(&cai, 0, sizeof(cai));
5177 cai.encmethods = iax2_encryption;
5178 cai.authmethods = iax2_authmethods;
5179
5180 memset(&pds, 0, sizeof(pds));
5181 tmpstr = ast_strdupa(dest);
5182 parse_dial_string(tmpstr, &pds);
5183
5184 if (ast_strlen_zero(pds.peer)) {
5185 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
5186 return -1;
5187 }
5188 if (!pds.exten) {
5189 pds.exten = defaultrdest;
5190 }
5191 if (create_addr(pds.peer, c, &addr, &cai)) {
5192 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
5193 return -1;
5194 }
5195
5198 if (!cai.encmethods) {
5199 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
5201 return -1;
5202 }
5203 if (((cai.authmethods & IAX_AUTH_RSA) || (cai.authmethods & IAX_AUTH_MD5) || (cai.authmethods & IAX_AUTH_PLAINTEXT)) &&
5204 ast_strlen_zero(cai.secret) && ast_strlen_zero(pds.password)) {
5205 ast_log(LOG_WARNING, "Call terminated. Encryption forced but no secret provided\n");
5206 return -1;
5207 }
5208 }
5209
5210 if (!pds.username && !ast_strlen_zero(cai.username))
5211 pds.username = cai.username;
5212 if (!pds.password && !ast_strlen_zero(cai.secret))
5213 pds.password = cai.secret;
5214 if (!pds.key && !ast_strlen_zero(cai.outkey))
5215 pds.key = cai.outkey;
5216 if (!pds.context && !ast_strlen_zero(cai.peercontext))
5217 pds.context = cai.peercontext;
5218
5219 /* Keep track of the context for outgoing calls too */
5220 ast_channel_context_set(c, cai.context);
5221
5222 if (pds.port) {
5223 int bindport;
5224 if (ast_parse_arg(pds.port, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535)) {
5225 ast_sockaddr_set_port(&addr, bindport);
5226 }
5227 }
5228
5231
5232 /* Now build request */
5233 memset(&ied, 0, sizeof(ied));
5234
5235 /* On new call, first IE MUST be IAX version of caller */
5237 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
5238 if (pds.options && strchr(pds.options, 'a')) {
5239 /* Request auto answer */
5241 }
5242
5243 /* WARNING: this breaks down at 190 bits! */
5244 iax2_codec_pref_convert(&cai.prefs, encoded_prefs, sizeof(encoded_prefs), 1);
5245 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, encoded_prefs);
5246
5247 if (l) {
5251 } else if (n) {
5254 } else {
5256 }
5257
5259 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, ast_channel_dialed(c)->transit_network_select);
5261
5262 if (n)
5264 if (ast_test_flag64(iaxs[callno], IAX_SENDANI)
5265 && ast_channel_connected(c)->ani.number.valid
5266 && ast_channel_connected(c)->ani.number.str) {
5268 }
5269
5274 }
5275 if (ast_channel_redirecting(c)->from.number.valid
5276 && !ast_strlen_zero(ast_channel_redirecting(c)->from.number.str)) {
5277 iax_ie_append_str(&ied, IAX_IE_RDNIS, ast_channel_redirecting(c)->from.number.str);
5278 }
5279
5280 if (pds.context)
5281 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
5282
5283 if (pds.username)
5284 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
5285
5286 if (cai.encmethods)
5287 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
5288
5289 ast_mutex_lock(&iaxsl[callno]);
5290
5293
5294 if (pds.username)
5295 ast_string_field_set(iaxs[callno], username, pds.username);
5296
5297 iaxs[callno]->encmethods = cai.encmethods;
5298
5299 iaxs[callno]->adsi = cai.adsi;
5300
5301 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
5302 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
5303
5304 if (pds.key)
5305 ast_string_field_set(iaxs[callno], outkey, pds.key);
5306 if (pds.password)
5307 ast_string_field_set(iaxs[callno], secret, pds.password);
5308
5310 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) iax2_tmpfmt);
5311 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, iax2_tmpfmt);
5312
5313 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
5314 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
5316 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
5317
5318 if (iaxs[callno]->maxtime) {
5319 /* Initialize pingtime and auto-congest time */
5320 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
5321 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
5322 } else if (autokill) {
5323 iaxs[callno]->pingtime = autokill / 2;
5325 }
5326
5327 /* Check if there is an OSP token */
5328 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
5329 if (!ast_strlen_zero(osp_token_ptr)) {
5330 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
5331 osp_block_index = 0;
5332 while (osp_token_length > 0) {
5333 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
5334 osp_buffer[0] = osp_block_index;
5335 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
5336 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
5337 osp_block_index++;
5338 osp_token_ptr += osp_block_length;
5339 osp_token_length -= osp_block_length;
5340 }
5341 } else
5342 ast_log(LOG_WARNING, "OSP token is too long\n");
5343 } else if (iaxdebug)
5344 ast_debug(1, "OSP token is undefined\n");
5345
5346 /* send the command using the appropriate socket for this peer */
5347 iaxs[callno]->sockfd = cai.sockfd;
5348
5349 /* Add remote vars */
5350 if (variablestore) {
5351 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
5352 ast_debug(1, "Found an IAX variable store on this channel\n");
5353 AST_LIST_LOCK(variablelist);
5354 AST_LIST_TRAVERSE(variablelist, var, entries) {
5355 char tmp[256];
5356 int i;
5357 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
5358 /* Automatically divide the value up into sized chunks */
5359 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
5360 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
5362 }
5363 }
5364 AST_LIST_UNLOCK(variablelist);
5365 }
5366
5367 /* Transmit the string in a "NEW" request */
5368 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
5369 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
5370
5371 ast_mutex_unlock(&iaxsl[callno]);
5373
5374 return 0;
5375}
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:130
static int autokill
Definition: chan_iax2.c:346
static int auto_congest(const void *data)
Definition: chan_iax2.c:4795
static unsigned int iax2_datetime(const char *tz)
Definition: chan_iax2.c:4804
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1821
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
ast_channel_adsicpe
Definition: channel.h:868
const char * ast_channel_language(const struct ast_channel *chan)
uint64_t iax2_format_compatibility_cap2bitfield(const struct ast_format_cap *cap)
Convert a format capabilities structure to a bitfield.
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_RINGING
Definition: channelstate.h:41
@ AST_STATE_RESERVED
Definition: channelstate.h:37
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7386
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
#define IAX_MAX_OSPBLOCK_SIZE
Definition: iax2.h:192
#define IAX_IE_DNID
Definition: iax2.h:143
#define IAX_IE_CALLINGANI2
Definition: iax2.h:190
#define IAX_IE_DATETIME
Definition: iax2.h:161
#define IAX_IE_CALLING_NUMBER
Definition: iax2.h:132
#define IAX_IE_CALLING_ANI
Definition: iax2.h:133
#define IAX_IE_CALLINGTNS
Definition: iax2.h:170
int64_t iax2_format
Definition: iax2.h:224
#define IAX_IE_FORMAT2
Definition: iax2.h:188
#define IAX_IE_CAPABILITY2
Definition: iax2.h:187
#define IAX_IE_CALLING_NAME
Definition: iax2.h:134
#define IAX_IE_ADSICPE
Definition: iax2.h:142
#define IAX_IE_VARIABLE
Definition: iax2.h:183
#define IAX_IE_OSPTOKEN
Definition: iax2.h:184
#define IAX_IE_LANGUAGE
Definition: iax2.h:140
#define IAX_MAX_OSPTOKEN_SIZE
Definition: iax2.h:194
#define IAX_IE_RDNIS
Definition: iax2.h:158
#define IAX_IE_CODEC_PREFS
Definition: iax2.h:175
#define IAX_IE_AUTOANSWER
Definition: iax2.h:155
#define IAX_IE_CALLINGPRES
Definition: iax2.h:168
#define IAX_IE_CALLINGTON
Definition: iax2.h:169
int iax_ie_append(struct iax_ie_data *ied, unsigned char ie)
Definition: parser.c:780
int iax_ie_append_versioned_uint64(struct iax_ie_data *ied, unsigned char ie, unsigned char version, uint64_t value)
Definition: parser.c:746
int iax_ie_append_raw(struct iax_ie_data *ied, unsigned char ie, const void *data, int datalen)
Definition: parser.c:726
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_party_id id
Connected party ID.
Definition: channel.h:458
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:279
char * str
Subscriber name (Malloced)
Definition: channel.h:264
Number structure.
Definition: app_followme.c:154

References add_empty_calltoken_ie(), chan_iax2_pvt::adsi, create_addr_info::adsi, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, ast_channel_connected(), ast_channel_context(), ast_channel_context_set(), ast_channel_datastore_find(), ast_channel_dialed(), ast_channel_hangupcause_set(), ast_channel_language(), ast_channel_name(), ast_channel_nativeformats(), ast_channel_redirecting(), ast_channel_tech_pvt(), ast_debug, AST_FRAME_IAX, AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_parse_arg(), ast_party_id_presentation(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), ast_sockaddr_set_port, AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_name(), ast_var_value(), create_addr_info::authmethods, auto_congest(), autokill, iax_ie_data::buf, c, CALLNO_TO_PTR, create_addr_info::context, parsed_dial_string::context, voicemailpwcheck::context, create_addr(), ast_datastore::data, chan_iax2_pvt::encmethods, create_addr_info::encmethods, parsed_dial_string::exten, iax2_authmethods, iax2_codec_pref_convert(), iax2_datetime(), iax2_encryption, iax2_format_compatibility_cap2bitfield(), iax2_sched_add(), iax2_variable_datastore_info, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_COMMAND_NEW, IAX_FORCE_ENCRYPT, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_raw(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGANI2, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CAPABILITY2, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_LANGUAGE, IAX_IE_OSPTOKEN, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VARIABLE, IAX_IE_VERSION, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPTOKEN_SIZE, IAX_PROTO_VERSION, IAX_SENDANI, iaxdebug, iaxs, iaxsl, ast_party_connected_line::id, chan_iax2_pvt::initid, parsed_dial_string::key, LOG_WARNING, chan_iax2_pvt::maxtime, mohinterpret, create_addr_info::mohinterpret, mohsuggest, create_addr_info::mohsuggest, ast_party_id::name, NULL, ast_party_id::number, parsed_dial_string::options, create_addr_info::outkey, parse_dial_string(), PARSE_IN_RANGE, PARSE_UINT32, parsed_dial_string::password, pbx_builtin_getvar_helper(), parsed_dial_string::peer, create_addr_info::peercontext, chan_iax2_pvt::pingtime, parsed_dial_string::port, iax_ie_data::pos, create_addr_info::prefs, PTR_TO_CALLNO, create_addr_info::secret, send_command(), chan_iax2_pvt::sockfd, create_addr_info::sockfd, ast_party_name::str, ast_party_number::str, create_addr_info::timezone, tmp(), create_addr_info::username, parsed_dial_string::username, ast_party_name::valid, ast_party_number::valid, and var.

◆ iax2_canmatch()

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

part of the IAX2 dial plan switch interface

Definition at line 14455 of file chan_iax2.c.

14456{
14457 int res = 0;
14458 struct iax2_dpcache *dp = NULL;
14459#if 0
14460 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14461#endif
14462 if ((priority != 1) && (priority != 2))
14463 return 0;
14464
14466 if ((dp = find_cache(chan, data, context, exten, priority))) {
14467 if (dp->flags & CACHE_FLAG_CANEXIST)
14468 res = 1;
14469 } else {
14470 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14471 }
14473
14474 return res;
14475}
static int priority
static struct iax2_dpcache * find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
Definition: chan_iax2.c:14307

References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, CACHE_FLAG_CANEXIST, voicemailpwcheck::context, iax2_dpcache::exten, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, NULL, and priority.

◆ iax2_codec_choose()

static iax2_format iax2_codec_choose ( struct iax2_codec_pref pref,
iax2_format  formats 
)
static

Definition at line 1928 of file chan_iax2.c.

1929{
1930 struct ast_format_cap *cap;
1931 struct ast_format *tmpfmt;
1932 iax2_format format = 0;
1933
1936 tmpfmt = codec_choose_from_prefs(pref, cap);
1937 if (!tmpfmt) {
1938 ao2_ref(cap, -1);
1939 return 0;
1940 }
1941
1943 ao2_ref(tmpfmt, -1);
1944 ao2_ref(cap, -1);
1945 }
1946
1947 return format;
1948}
static struct ast_format * codec_choose_from_prefs(struct iax2_codec_pref *pref, struct ast_format_cap *cap)
Definition: chan_iax2.c:1894
int iax2_format_compatibility_bitfield2cap(uint64_t bitfield, struct ast_format_cap *cap)
Convert a bitfield to a format capabilities structure.
uint64_t ast_format_compatibility_format2bitfield(const struct ast_format *format)
Convert a format structure to its respective bitfield.
Definition: file.c:69

References ao2_ref, ast_format_cap_alloc, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_compatibility_format2bitfield(), codec_choose_from_prefs(), and iax2_format_compatibility_bitfield2cap().

Referenced by socket_process_helper().

◆ iax2_datetime()

static unsigned int iax2_datetime ( const char *  tz)
static

Definition at line 4804 of file chan_iax2.c.

4805{
4806 struct timeval t = ast_tvnow();
4807 struct ast_tm tm;
4808 unsigned int tmp;
4809 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
4810 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */
4811 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */
4812 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */
4813 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */
4814 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */
4815 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
4816 return tmp;
4817}
static char * tz
Definition: cdr_pgsql.c:71
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739

References ast_localtime(), ast_strlen_zero(), ast_tvnow(), NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_year, tmp(), and tz.

Referenced by iax2_call(), and update_registry().

◆ iax2_delete_from_sched()

static int iax2_delete_from_sched ( const void *  data)
static

Definition at line 2124 of file chan_iax2.c.

2125{
2126 int sched_id = (int)(long)data;
2127
2129
2130 return 0;
2131}
Scheduler ID holder.
Definition: sched.c:70

References AST_SCHED_DEL.

Referenced by iax2_destroy_helper().

◆ iax2_destroy()

static void iax2_destroy ( int  callno)
static

Definition at line 3506 of file chan_iax2.c.

3507{
3508 struct chan_iax2_pvt *pvt = NULL;
3509 struct ast_channel *owner = NULL;
3510
3511retry:
3512 if ((pvt = iaxs[callno])) {
3513#if 0
3514 /* iax2_destroy_helper gets called from this function later on. When
3515 * called twice, we get the (previously) familiar FRACK! errors in
3516 * devmode, from the scheduler. An alternative to this approach is to
3517 * reset the scheduler entries to -1 when they're deleted in
3518 * iax2_destroy_helper(). That approach was previously decided to be
3519 * "wrong" because "the memory is going to be deallocated anyway. Why
3520 * should we be resetting those values?" */
3522#endif
3523 }
3524
3525 owner = pvt ? pvt->owner : NULL;
3526
3527 if (owner) {
3528 if (ast_channel_trylock(owner)) {
3529 ast_debug(3, "Avoiding IAX destroy deadlock\n");
3530 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
3531 goto retry;
3532 }
3533 }
3534
3535 if (!owner) {
3536 iaxs[callno] = NULL;
3537 }
3538
3539 if (pvt) {
3540 if (!owner) {
3541 pvt->owner = NULL;
3542 } else {
3543 /* If there's an owner, prod it to give up */
3544 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
3545 * because we already hold the owner channel lock. */
3546 ast_queue_hangup(owner);
3547 }
3548
3549 if (pvt->peercallno) {
3551 }
3552
3553 if (pvt->transfercallno) {
3555 }
3556
3557 if (!owner) {
3558 ao2_ref(pvt, -1);
3559 pvt = NULL;
3560 }
3561 }
3562
3563 if (owner) {
3564 ast_channel_unlock(owner);
3565 }
3566}
static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:2135
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1150
#define ast_channel_trylock(chan)
Definition: channel.h:2924
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:479

References ao2_ref, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_queue_hangup(), DEADLOCK_AVOIDANCE, iax2_destroy_helper(), iaxs, iaxsl, NULL, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), remove_by_transfercallno(), and chan_iax2_pvt::transfercallno.

Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), scheduled_destroy(), and socket_process_helper().

◆ iax2_destroy_helper()

static void iax2_destroy_helper ( struct chan_iax2_pvt pvt)
static
Note
Assumes the lock on the pvt is already held, when iax2_destroy_helper() is called.

Definition at line 2135 of file chan_iax2.c.

2136{
2137 /* Decrement AUTHREQ count if needed */
2138 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) {
2139 struct iax2_user *user;
2140
2142 if (user) {
2143 ast_atomic_fetchadd_int(&user->curauthreq, -1);
2145 }
2146
2148 }
2149
2150
2151 /* Mark call destroy initiated flag. */
2152 pvt->destroy_initiated = 1;
2153
2154 /*
2155 * Schedule deleting the scheduled (but didn't run yet) PINGs or LAGRQs.
2156 * Already running tasks will be terminated because of destroy_initiated.
2157 *
2158 * Don't call AST_SCHED_DEL from this thread for pingid and lagid because
2159 * it leads to a deadlock between the scheduler thread callback locking
2160 * the callno mutex and this thread which holds the callno mutex one or
2161 * more times. It is better to have another thread delete the scheduled
2162 * callbacks which doesn't lock the callno mutex.
2163 */
2164 iax2_sched_add(sched, 0, iax2_delete_from_sched, (void*)(long)pvt->pingid);
2165 iax2_sched_add(sched, 0, iax2_delete_from_sched, (void*)(long)pvt->lagid);
2166
2167 pvt->pingid = -1;
2168 pvt->lagid = -1;
2169
2170 AST_SCHED_DEL(sched, pvt->autoid);
2171 AST_SCHED_DEL(sched, pvt->authid);
2172 AST_SCHED_DEL(sched, pvt->initid);
2173 AST_SCHED_DEL(sched, pvt->jbid);
2175}
static int iax2_delete_from_sched(const void *data)
Definition: chan_iax2.c:2124
int destroy_initiated
Definition: chan_iax2.c:931

References ao2_find, ast_atomic_fetchadd_int(), ast_clear_flag64, AST_SCHED_DEL, ast_test_flag64, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::destroy_initiated, iax2_delete_from_sched(), iax2_sched_add(), IAX_MAXAUTHREQ, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, OBJ_KEY, chan_iax2_pvt::pingid, user, user_unref(), and chan_iax2_pvt::username.

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

◆ iax2_devicestate()

static int iax2_devicestate ( const char *  data)
static

Part of the device state notification system —.

Definition at line 14665 of file chan_iax2.c.

14666{
14667 struct parsed_dial_string pds;
14668 char *tmp = ast_strdupa(data);
14669 struct iax2_peer *p;
14670 int res = AST_DEVICE_INVALID;
14671
14672 memset(&pds, 0, sizeof(pds));
14673 parse_dial_string(tmp, &pds);
14674
14675 if (ast_strlen_zero(pds.peer)) {
14676 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
14677 return res;
14678 }
14679
14680 ast_debug(3, "Checking device state for device %s\n", pds.peer);
14681
14682 /* SLD: FIXME: second call to find_peer during registration */
14683 if (!(p = find_peer(pds.peer, 1)))
14684 return res;
14685
14687
14688 ast_debug(3, "Found peer. What's device state of %s? addr=%s, defaddr=%s maxms=%d, lastms=%d\n",
14690
14691 if (((!ast_sockaddr_isnull(&p->addr)) || (!ast_sockaddr_isnull(&p->defaddr))) &&
14692 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
14693 /* Peer is registered, or have default IP address
14694 and a valid registration */
14695 if (p->historicms == 0 || p->historicms <= p->maxms)
14696 /* let the core figure out whether it is in use or not */
14697 res = AST_DEVICE_UNKNOWN;
14698 }
14699
14700 peer_unref(p);
14701
14702 return res;
14703}
@ AST_DEVICE_UNKNOWN
Definition: devicestate.h:53
@ AST_DEVICE_INVALID
Definition: devicestate.h:57
int historicms
Definition: chan_iax2.c:626

References iax2_peer::addr, ast_debug, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_strdupa, ast_strlen_zero(), iax2_peer::defaddr, find_peer(), iax2_peer::historicms, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, parse_dial_string(), parsed_dial_string::peer, peer_unref(), and tmp().

◆ iax2_digit_begin()

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

◆ iax2_digit_end()

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

◆ iax2_do_register()

static int iax2_do_register ( struct iax2_registry reg)
static

Definition at line 12304 of file chan_iax2.c.

12305{
12306 struct iax_ie_data ied;
12307 if (iaxdebug)
12308 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
12309
12310 if (reg->dnsmgr &&
12311 ((reg->regstate == REG_STATE_TIMEOUT) || ast_sockaddr_isnull(&reg->addr))) {
12312 /* Maybe the IP has changed, force DNS refresh */
12314 }
12315
12316 /*
12317 * if IP has Changed, free allocated call to create a new one with new IP
12318 * call has the pointer to IP and must be updated to the new one
12319 */
12320 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
12321 int callno = reg->callno;
12322 ast_mutex_lock(&iaxsl[callno]);
12323 iax2_destroy(callno);
12324 ast_mutex_unlock(&iaxsl[callno]);
12325 reg->callno = 0;
12326 }
12327 if (ast_sockaddr_isnull(&reg->addr)) {
12328 if (iaxdebug)
12329 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
12330 /* Setup the next registration attempt */
12332 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
12333 return -1;
12334 }
12335 if (!ast_sockaddr_port(&reg->addr) && reg->port) {
12336 ast_sockaddr_set_port(&reg->addr, reg->port);
12337 }
12338
12339 if (!reg->callno) {
12340
12341 ast_debug(3, "Allocate call number\n");
12342
12343 reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
12344 if (reg->callno < 1) {
12345 ast_log(LOG_WARNING, "Unable to create call for registration\n");
12346 return -1;
12347 } else
12348 ast_debug(3, "Registration created on call %d\n", reg->callno);
12349 iaxs[reg->callno]->reg = reg;
12351 }
12352 /* Setup the next registration a little early */
12354 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
12355 /* Send the request */
12356 memset(&ied, 0, sizeof(ied));
12359 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */
12360 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
12362 return 0;
12363}
int ast_dnsmgr_changed(struct ast_dnsmgr_entry *entry)
Check is see if a dnsmgr entry has changed.
Definition: dnsmgr.c:247

References add_empty_calltoken_ie(), iax2_registry::addr, ast_debug, ast_dnsmgr_changed(), ast_dnsmgr_refresh(), AST_FRAME_IAX, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, iax_ie_data::buf, iax2_registry::callno, defaultsockfd, iax2_registry::dnsmgr, iax2_registry::expire, find_callno_locked(), iax2_destroy(), iax2_do_register_s(), iax2_sched_replace(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxdebug, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, iax2_registry::port, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, send_command(), and iax2_registry::username.

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

◆ iax2_do_register_s()

static int iax2_do_register_s ( const void *  data)
static

Definition at line 8701 of file chan_iax2.c.

8702{
8703#ifdef SCHED_MULTITHREADED
8705#endif
8707 return 0;
8708}
static void __iax2_do_register_s(const void *data)
Definition: chan_iax2.c:8683

References __iax2_do_register_s(), and schedule_action.

Referenced by iax2_ack_registry(), and iax2_do_register().

◆ iax2_dprequest()

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

Definition at line 9503 of file chan_iax2.c.

9504{
9505 struct iax_ie_data ied;
9506 /* Auto-hangup with 30 seconds of inactivity */
9507 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
9508 sched, 30000, auto_hangup, (void *)(long)callno);
9509 memset(&ied, 0, sizeof(ied));
9511 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
9513}
static int auto_hangup(const void *data)
Definition: chan_iax2.c:9488
@ IAX_COMMAND_DPREQ
Definition: iax2.h:77

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

Referenced by find_cache(), and socket_process_helper().

◆ iax2_dup_variable_datastore()

static void * iax2_dup_variable_datastore ( void *  old)
static

Definition at line 1575 of file chan_iax2.c.

1576{
1577 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
1578 struct ast_var_t *oldvar, *newvar;
1579
1580 newlist = ast_calloc(sizeof(*newlist), 1);
1581 if (!newlist) {
1582 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
1583 return NULL;
1584 }
1585
1586 AST_LIST_HEAD_INIT(newlist);
1587 AST_LIST_LOCK(oldlist);
1588 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
1589 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
1590 if (newvar)
1591 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
1592 else
1593 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
1594 }
1595 AST_LIST_UNLOCK(oldlist);
1596 return newlist;
1597}

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

◆ iax2_exec()

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

Execute IAX2 dialplan switch.

Definition at line 14501 of file chan_iax2.c.

14502{
14503 char odata[256];
14504 char req[sizeof(odata) + AST_MAX_CONTEXT + AST_MAX_EXTENSION + sizeof("IAX2//@")];
14505 char *ncontext;
14506 struct iax2_dpcache *dp = NULL;
14507 struct ast_app *dial = NULL;
14508#if 0
14509 ast_log(LOG_NOTICE, "iax2_exec: con: %s, exten: %s, pri: %d, cid: %s, data: %s, newstack: %d\n", context, exten, priority, callerid ? callerid : "<unknown>", data, newstack);
14510#endif
14511 if (priority == 2) {
14512 /* Indicate status, can be overridden in dialplan */
14513 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
14514 if (dialstatus) {
14515 dial = pbx_findapp(dialstatus);
14516 if (dial)
14517 pbx_exec(chan, dial, "");
14518 }
14519 return -1;
14520 } else if (priority != 1)
14521 return -1;
14522
14524 if ((dp = find_cache(chan, data, context, exten, priority))) {
14525 if (dp->flags & CACHE_FLAG_EXISTS) {
14526 ast_copy_string(odata, data, sizeof(odata));
14527 ncontext = strchr(odata, '/');
14528 if (ncontext) {
14529 *ncontext = '\0';
14530 ncontext++;
14531 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
14532 } else {
14533 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
14534 }
14535 ast_verb(3, "Executing Dial('%s')\n", req);
14536 } else {
14538 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
14539 return -1;
14540 }
14541 }
14543
14544 if ((dial = pbx_findapp("Dial")))
14545 return pbx_exec(chan, dial, req);
14546 else
14547 ast_log(LOG_WARNING, "No dial application registered\n");
14548
14549 return -1;
14550}
#define AST_MAX_CONTEXT
Definition: channel.h:135
#define AST_MAX_EXTENSION
Definition: channel.h:134
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165
ast_app: A registered application
Definition: pbx_app.c:45

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_verb, CACHE_FLAG_EXISTS, voicemailpwcheck::context, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, NULL, pbx_builtin_getvar_helper(), pbx_exec(), pbx_findapp(), and priority.

◆ iax2_exists()

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

Part of the IAX2 switch interface.

Definition at line 14432 of file chan_iax2.c.

14433{
14434 int res = 0;
14435 struct iax2_dpcache *dp = NULL;
14436#if 0
14437 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14438#endif
14439 if ((priority != 1) && (priority != 2))
14440 return 0;
14441
14443 if ((dp = find_cache(chan, data, context, exten, priority))) {
14444 if (dp->flags & CACHE_FLAG_EXISTS)
14445 res = 1;
14446 } else {
14447 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14448 }
14450
14451 return res;
14452}

References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, CACHE_FLAG_EXISTS, voicemailpwcheck::context, iax2_dpcache::exten, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, NULL, and priority.

◆ iax2_fixup()

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

Definition at line 4401 of file chan_iax2.c.

4402{
4403 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(newchan));
4404 ast_mutex_lock(&iaxsl[callno]);
4405 if (iaxs[callno])
4406 iaxs[callno]->owner = newchan;
4407 else
4408 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
4409 ast_mutex_unlock(&iaxsl[callno]);
4410 return 0;
4411}

References ast_channel_tech_pvt(), ast_log, ast_mutex_lock, ast_mutex_unlock, iax_frame::callno, iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, and PTR_TO_CALLNO.

◆ iax2_frame_free()

static void iax2_frame_free ( struct iax_frame fr)
static

Definition at line 2177 of file chan_iax2.c.

2178{
2180 iax_frame_free(fr);
2181}
void iax_frame_free(struct iax_frame *fr)
Definition: parser.c:1295

References AST_SCHED_DEL, iax_frame_free(), and iax_frame::retrans.

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

◆ iax2_free_variable_datastore()

static void iax2_free_variable_datastore ( void *  old)
static

Definition at line 1599 of file chan_iax2.c.

1600{
1601 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
1602 struct ast_var_t *oldvar;
1603
1604 AST_LIST_LOCK(oldlist);
1605 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
1606 ast_free(oldvar);
1607 }
1608 AST_LIST_UNLOCK(oldlist);
1609 AST_LIST_HEAD_DESTROY(oldlist);
1610 ast_free(oldlist);
1611}
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:653

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

◆ iax2_getformatname()

const char * iax2_getformatname ( iax2_format  format)

iax2 wrapper function for ast_getformatname

Definition at line 1950 of file chan_iax2.c.

1951{
1952 struct ast_format *tmpfmt;
1953
1955 if (!tmpfmt) {
1956 return "Unknown";
1957 }
1958
1959 return ast_format_get_name(tmpfmt);
1960}

References ast_format_compatibility_bitfield2format(), and ast_format_get_name().

Referenced by dump_versioned_codec(), handle_cli_iax2_show_channels(), iax_show_provisioning(), and socket_process_helper().

◆ iax2_getformatname_multiple()

static const char * iax2_getformatname_multiple ( iax2_format  format,
struct ast_str **  codec_buf 
)
static

Definition at line 1962 of file chan_iax2.c.

1963{
1965
1966 if (!cap) {
1967 return "(Nothing)";
1968 }
1970 ast_format_cap_get_names(cap, codec_buf);
1971 ao2_ref(cap, -1);
1972
1973 return ast_str_buffer(*codec_buf);
1974}
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:734

References ao2_ref, ast_format_cap_alloc, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_names(), ast_str_buffer(), and iax2_format_compatibility_bitfield2cap().

Referenced by function_iaxpeer(), handle_cli_iax2_show_peer(), and socket_process_helper().

◆ iax2_getpeername()

static int iax2_getpeername ( struct ast_sockaddr  addr,
char *  host,
int  len 
)
static

Definition at line 2092 of file chan_iax2.c.

2093{
2094 struct iax2_peer *peer = NULL;
2095 int res = 0;
2096 struct ao2_iterator i;
2097
2098 i = ao2_iterator_init(peers, 0);
2099 while ((peer = ao2_iterator_next(&i))) {
2100
2101 if (!ast_sockaddr_cmp(&peer->addr, &addr)) {
2102 ast_copy_string(host, peer->name, len);
2103 peer_unref(peer);
2104 res = 1;
2105 break;
2106 }
2107 peer_unref(peer);
2108 }
2110
2111 if (!peer) {
2112 peer = realtime_peer(NULL, &addr);
2113 if (peer) {
2114 ast_copy_string(host, peer->name, len);
2115 peer_unref(peer);
2116 res = 1;
2117 }
2118 }
2119
2120 return res;
2121}

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), ast_sockaddr_cmp(), len(), iax2_peer::name, NULL, peer_unref(), and realtime_peer().

Referenced by __find_callno().

◆ iax2_getpeertrunk()

static int iax2_getpeertrunk ( struct ast_sockaddr  addr)
static

Definition at line 5884 of file chan_iax2.c.

5885{
5886 struct iax2_peer *peer;
5887 int res = 0;
5888 struct ao2_iterator i;
5889
5890 i = ao2_iterator_init(peers, 0);
5891 while ((peer = ao2_iterator_next(&i))) {
5892
5893 if (!ast_sockaddr_cmp(&peer->addr, &addr)) {
5894 res = ast_test_flag64(peer, IAX_TRUNK);
5895 peer_unref(peer);
5896 break;
5897 }
5898 peer_unref(peer);
5899 }
5901
5902 return res;
5903}

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_sockaddr_cmp(), ast_test_flag64, IAX_TRUNK, and peer_unref().

Referenced by check_access().

◆ iax2_hangup()

static int iax2_hangup ( struct ast_channel c)
static

Definition at line 5377 of file chan_iax2.c.

5378{
5379 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5380 struct iax_ie_data ied;
5381 int alreadygone;
5382 memset(&ied, 0, sizeof(ied));
5383 ast_mutex_lock(&iaxsl[callno]);
5384 if (callno && iaxs[callno]) {
5385 ast_debug(1, "We're hanging up %s now...\n", ast_channel_name(c));
5386 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
5387 /* Send the hangup unless we have had a transmission error or are already gone */
5389 if (!iaxs[callno]->error && !alreadygone) {
5390 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
5391 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
5392 }
5393 if (!iaxs[callno]) {
5394 ast_mutex_unlock(&iaxsl[callno]);
5395 return 0;
5396 }
5397 }
5398 /* Explicitly predestroy it */
5399 iax2_predestroy(callno);
5400 /* If we were already gone to begin with, destroy us now */
5401 if (iaxs[callno] && alreadygone) {
5402 ast_debug(1, "Really destroying %s now...\n", ast_channel_name(c));
5403 iax2_destroy(callno);
5404 } else if (iaxs[callno]) {
5405 if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
5406 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
5407 iax2_destroy(callno);
5408 }
5409 }
5410 } else if (ast_channel_tech_pvt(c)) {
5411 /* If this call no longer exists, but the channel still
5412 * references it we need to set the channel's tech_pvt to null
5413 * to avoid ast_channel_free() trying to free it.
5414 */
5416 }
5417 ast_mutex_unlock(&iaxsl[callno]);
5418 ast_verb(3, "Hungup '%s'\n", ast_channel_name(c));
5419 return 0;
5420}
static int iax2_predestroy(int callno)
Definition: chan_iax2.c:3483
static int scheduled_destroy(const void *vid)
Definition: chan_iax2.c:2183
int ast_channel_hangupcause(const struct ast_channel *chan)
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:567

References ast_channel_hangupcause(), ast_channel_name(), ast_channel_tech_pvt(), ast_channel_tech_pvt_set(), ast_debug, AST_FRAME_IAX, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_sched_add(), ast_test_flag64, ast_verb, iax_ie_data::buf, c, CALLNO_TO_PTR, error(), iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_ERROR, LOG_WARNING, NULL, iax_ie_data::pos, PTR_TO_CALLNO, scheduled_destroy(), and send_command_final().

◆ iax2_indicate()

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

Definition at line 5811 of file chan_iax2.c.

5812{
5813 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5814 struct chan_iax2_pvt *pvt;
5815 int res = 0;
5816
5817 if (iaxdebug)
5818 ast_debug(1, "Indicating condition %d\n", condition);
5819
5821 pvt = iaxs[callno];
5822
5823 if (wait_for_peercallno(pvt)) {
5824 res = -1;
5825 goto done;
5826 }
5827
5828 switch (condition) {
5829 case AST_CONTROL_HOLD:
5830 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
5831 ast_moh_start(c, data, pvt->mohinterpret);
5832 goto done;
5833 }
5834 break;
5835 case AST_CONTROL_UNHOLD:
5836 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
5837 ast_moh_stop(c);
5838 goto done;
5839 }
5840 break;
5844 /* We are not configured to allow sending these updates. */
5845 ast_debug(2, "Callno %d: Config blocked sending control frame %d.\n",
5846 callno, condition);
5847 goto done;
5848 }
5849 break;
5852 res = -1;
5853 goto done;
5854 }
5855
5856 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
5857
5858done:
5860
5861 return res;
5862}
static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:5425
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_HOLD
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_MASQUERADE_NOTIFY
@ AST_CONTROL_PVT_CAUSE_CODE
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7766
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7776
const ast_string_field mohinterpret
Definition: chan_iax2.c:861
int done
Definition: test_amihooks.c:48

References ast_channel_tech_pvt(), AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_MASQUERADE_NOTIFY, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_REDIRECTING, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_CONTROL, ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, c, chan_iax2_pvt::callno, done, IAX_SENDCONNECTEDLINE, iaxdebug, iaxs, iaxsl, chan_iax2_pvt::mohinterpret, PTR_TO_CALLNO, send_command(), and wait_for_peercallno().

◆ iax2_is_control_frame_allowed()

static int iax2_is_control_frame_allowed ( int  subtype)
static

Definition at line 1405 of file chan_iax2.c.

1406{
1407 enum ast_control_frame_type control = subtype;
1408 int is_allowed;
1409
1410 /*
1411 * Note: If we compare the enumeration type, which does not have any
1412 * negative constants, the compiler may optimize this code away.
1413 * Therefore, we must perform an integer comparison here.
1414 */
1415 if (subtype == -1) {
1416 return -1;
1417 }
1418
1419 /* Default to not allowing control frames to pass. */
1420 is_allowed = 0;
1421
1422 /*
1423 * The switch default is not present in order to take advantage
1424 * of the compiler complaining of a missing enum case.
1425 */
1426 switch (control) {
1427 /*
1428 * These control frames make sense to send/receive across the link.
1429 */
1430 case AST_CONTROL_HANGUP:
1431 case AST_CONTROL_RING:
1433 case AST_CONTROL_ANSWER:
1434 case AST_CONTROL_BUSY:
1438 case AST_CONTROL_FLASH:
1439 case AST_CONTROL_WINK:
1440 case AST_CONTROL_OPTION:
1445 case AST_CONTROL_HOLD:
1446 case AST_CONTROL_UNHOLD:
1451 case AST_CONTROL_AOC:
1453 case AST_CONTROL_MCID:
1454 is_allowed = -1;
1455 break;
1456
1457 /*
1458 * These control frames do not make sense to send/receive across the link.
1459 */
1461 /* The control value is deprecated in favor of AST_CONTROL_T38_PARAMETERS. */
1463 /* Across an IAX link the source is still the same. */
1465 /* A success/fail status report from calling ast_transfer() on this machine. */
1466 case AST_CONTROL_CC:
1467 /* The payload contains pointers that are valid for the sending machine only. */
1469 /* Across an IAX link the source is still the same. */
1471 /* The action can only be done by the sending machine. */
1473 /* This frame would cause the call to unexpectedly hangup. */
1475 /* Only meaningful across a bridge on this machine for direct-media exchange. */
1477 /* Intended only for the sending machine's local channel structure. */
1479 /* Intended only for masquerades when calling ast_indicate_data(). */
1481 /* Intended only for internal stream topology manipulation. */
1483 /* Intended only for internal stream topology change notification. */
1490 /* None of these playback stream control frames should go across the link. */
1495 /* None of these media recording control frames should go across the link. */
1496 break;
1497 }
1498 return is_allowed;
1499}
ast_control_frame_type
Internal control frame subtype field values.
@ AST_CONTROL_RING
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_RECORD_CANCEL
@ AST_CONTROL_WINK
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_STREAM_TOPOLOGY_SOURCE_CHANGED
@ AST_CONTROL_OFFHOOK
@ AST_CONTROL_STREAM_RESTART
@ AST_CONTROL_STREAM_SUSPEND
@ AST_CONTROL_RADIO_UNKEY
@ AST_CONTROL_BUSY
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE
@ AST_CONTROL_STREAM_REVERSE
@ AST_CONTROL_PROCEEDING
@ AST_CONTROL_TAKEOFFHOOK
@ AST_CONTROL_MCID
@ AST_CONTROL_T38_PARAMETERS
@ AST_CONTROL_READ_ACTION
@ AST_CONTROL_RECORD_STOP
@ AST_CONTROL_CC
@ AST_CONTROL_RECORD_MUTE
@ AST_CONTROL_RINGING
@ AST_CONTROL_STREAM_STOP
@ AST_CONTROL_RADIO_KEY
@ AST_CONTROL_OPTION
@ AST_CONTROL_STREAM_TOPOLOGY_CHANGED
@ AST_CONTROL_END_OF_Q
@ AST_CONTROL_TRANSFER
@ AST_CONTROL_STREAM_FORWARD
@ AST_CONTROL_FLASH
@ AST_CONTROL_RECORD_SUSPEND
@ AST_CONTROL_AOC
@ AST_CONTROL_SRCCHANGE
@ AST_CONTROL_INCOMPLETE
@ _XXX_AST_CONTROL_T38
@ AST_CONTROL_UPDATE_RTP_PEER

References _XXX_AST_CONTROL_T38, AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_MASQUERADE_NOTIFY, AST_CONTROL_MCID, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_RECORD_CANCEL, AST_CONTROL_RECORD_MUTE, AST_CONTROL_RECORD_STOP, AST_CONTROL_RECORD_SUSPEND, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_STREAM_FORWARD, AST_CONTROL_STREAM_RESTART, AST_CONTROL_STREAM_REVERSE, AST_CONTROL_STREAM_STOP, AST_CONTROL_STREAM_SUSPEND, AST_CONTROL_STREAM_TOPOLOGY_CHANGED, AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE, AST_CONTROL_STREAM_TOPOLOGY_SOURCE_CHANGED, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, and AST_CONTROL_WINK.

Referenced by send_command(), and socket_process_helper().

◆ iax2_key_rotate()

static int iax2_key_rotate ( const void *  vpvt)
static

Definition at line 5539 of file chan_iax2.c.

5540{
5541 int res = 0;
5542 struct chan_iax2_pvt *pvt = (void *) vpvt;
5543 struct MD5Context md5;
5544 char key[17] = "";
5545 struct iax_ie_data ied = {
5546 .pos = 0,
5547 };
5548
5549 ast_mutex_lock(&iaxsl[pvt->callno]);
5550 pvt->keyrotateid = ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
5551
5552 snprintf(key, sizeof(key), "%lX", (unsigned long)ast_random());
5553
5554 MD5Init(&md5);
5555 MD5Update(&md5, (unsigned char *) key, strlen(key));
5556 MD5Final((unsigned char *) key, &md5);
5557
5558 IAX_DEBUGDIGEST("Sending", key);
5559
5560 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
5561
5562 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
5563
5564 build_ecx_key((unsigned char *) key, pvt);
5565
5567
5568 return res;
5569}
static int iax2_key_rotate(const void *vpvt)
Definition: chan_iax2.c:5539
#define IAX_DEBUGDIGEST(msg, key)
Definition: chan_iax2.c:443
@ IAX_COMMAND_RTKEY
Definition: iax2.h:117

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

Referenced by iax2_key_rotate(), and iax2_send().

◆ iax2_lock_callno_unless_destroyed()

static int iax2_lock_callno_unless_destroyed ( int  callno)
static

Acquire the iaxsl[callno] if call exists and not having ongoing hangup.

Parameters
callnoCall number to lock.
Return values
0If call disappeared or has ongoing hangup procedure.
1If call found and mutex is locked.

Definition at line 1745 of file chan_iax2.c.

1746{
1747 ast_mutex_lock(&iaxsl[callno]);
1748
1749 /* We acquired the lock; but the call was already destroyed (we came after full hang up procedures)
1750 * or destroy initiated (in middle of hang up procedure. */
1751 if (!iaxs[callno] || iaxs[callno]->destroy_initiated) {
1752 ast_debug(3, "I wanted to lock callno %d, but it is dead or going to die.\n", callno);
1753 ast_mutex_unlock(&iaxsl[callno]);
1754 return 0;
1755 }
1756
1757 /* Lock acquired, and callno is alive and kicking. */
1758 return 1;
1759}

References ast_debug, ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, iaxs, and iaxsl.

Referenced by __send_lagrq(), and __send_ping().

◆ iax2_lock_owner()

static void iax2_lock_owner ( int  callno)
static

Definition at line 1381 of file chan_iax2.c.

1382{
1383 for (;;) {
1384 if (!iaxs[callno] || !iaxs[callno]->owner) {
1385 /* There is no owner lock to get. */
1386 break;
1387 }
1388 if (!ast_channel_trylock(iaxs[callno]->owner)) {
1389 /* We got the lock */
1390 break;
1391 }
1392 /* Avoid deadlock by pausing and trying again */
1393 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
1394 }
1395}

References ast_channel_trylock, DEADLOCK_AVOIDANCE, iaxs, and iaxsl.

Referenced by iax2_queue_frame(), iax2_queue_hangup(), iax2_queue_hold(), iax2_queue_unhold(), set_hangup_source_and_cause(), and socket_process_helper().

◆ iax2_matchmore()

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

Part of the IAX2 Switch interface.

Definition at line 14478 of file chan_iax2.c.

14479{
14480 int res = 0;
14481 struct iax2_dpcache *dp = NULL;
14482#if 0
14483 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14484#endif
14485 if ((priority != 1) && (priority != 2))
14486 return 0;
14487
14489 if ((dp = find_cache(chan, data, context, exten, priority))) {
14490 if (dp->flags & CACHE_FLAG_MATCHMORE)
14491 res = 1;
14492 } else {
14493 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14494 }
14496
14497 return res;
14498}

References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, CACHE_FLAG_MATCHMORE, voicemailpwcheck::context, iax2_dpcache::exten, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, NULL, and priority.

◆ iax2_parse_allow_disallow()

static int iax2_parse_allow_disallow ( struct iax2_codec_pref pref,
iax2_format formats,
const char *  list,
int  allowing 
)
static

Definition at line 1976 of file chan_iax2.c.

1977{
1978 int res, i;
1979 struct ast_format_cap *cap;
1980
1981 /* We want to add the formats to the cap in the preferred order */
1983 if (!cap || iax2_codec_pref_to_cap(pref, cap)) {
1984 ao2_cleanup(cap);
1985 return 1;
1986 }
1987
1988 res = ast_format_cap_update_by_allow_disallow(cap, list, allowing);
1989
1990 /* Adjust formats bitfield and pref list to match. */
1993
1994 for (i = 0; i < ast_format_cap_count(cap); i++) {
1995 struct ast_format *fmt = ast_format_cap_get_format(cap, i);
1996
1998 ao2_ref(fmt, -1);
1999 }
2000
2001 ao2_ref(cap, -1);
2002
2003 return res;
2004}
void iax2_codec_pref_remove_missing(struct iax2_codec_pref *pref, uint64_t bitfield)
Removes format from the pref list that aren't in the bitfield.
Definition: codec_pref.c:288
void iax2_codec_pref_append(struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing)
Append a audio codec to a preference list, removing it first if it was already there.
Definition: codec_pref.c:420
int iax2_codec_pref_to_cap(struct iax2_codec_pref *pref, struct ast_format_cap *cap)
Convert a preference structure to a capabilities structure.
Definition: codec_pref.c:91
int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
Parse an "allow" or "deny" list and modify a format capabilities structure accordingly.
Definition: format_cap.c:320

References ao2_cleanup, ao2_ref, ast_format_cap_alloc, ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_format(), ast_format_cap_get_format_framing(), ast_format_cap_update_by_allow_disallow(), iax2_codec_pref_append(), iax2_codec_pref_remove_missing(), iax2_codec_pref_to_cap(), and iax2_format_compatibility_cap2bitfield().

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

◆ iax2_poke_noanswer()

static int iax2_poke_noanswer ( const void *  data)
static

Definition at line 12514 of file chan_iax2.c.

12515{
12516 struct iax2_peer *peer = (struct iax2_peer *)data;
12517 peer->pokeexpire = -1;
12518#ifdef SCHED_MULTITHREADED
12520#endif
12522 peer_unref(peer);
12523 return 0;
12524}
static void __iax2_poke_noanswer(const void *data)
Definition: chan_iax2.c:12485

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

Referenced by iax2_poke_peer().

◆ iax2_poke_peer()

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

Definition at line 12535 of file chan_iax2.c.

12536{
12537 int callno;
12538 int poke_timeout;
12539
12540 if (!peer->maxms || (ast_sockaddr_isnull(&peer->addr) && !peer->dnsmgr)) {
12541 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
12542 immediately after clearing things out */
12543 peer->lastms = 0;
12544 peer->historicms = 0;
12545 peer->pokeexpire = -1;
12546 peer->callno = 0;
12547 return 0;
12548 }
12549
12550 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
12551 if ((callno = peer->callno) > 0) {
12552 ast_log(LOG_NOTICE, "Still have a callno...\n");
12553 ast_mutex_lock(&iaxsl[callno]);
12554 iax2_destroy(callno);
12555 ast_mutex_unlock(&iaxsl[callno]);
12556 }
12557 if (heldcall)
12558 ast_mutex_unlock(&iaxsl[heldcall]);
12559 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
12560 if (heldcall)
12561 ast_mutex_lock(&iaxsl[heldcall]);
12562 if (callno < 1) {
12563 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12564 return -1;
12565 }
12566
12567 if (peer->pokeexpire > -1) {
12568 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
12569 peer->pokeexpire = -1;
12570 peer_unref(peer);
12571 }
12572 }
12573
12574 if (peer->lastms < 0){
12575 /* If the host is already unreachable then use time less than the unreachable
12576 * interval. 5/6 is arbitrary multiplier to get value less than
12577 * peer->pokefreqnotok. Value less than peer->pokefreqnotok is used to expire
12578 * current POKE before starting new POKE (which is scheduled after
12579 * peer->pokefreqnotok). */
12580 poke_timeout = peer->pokefreqnotok * 5 / 6;
12581 } else {
12582 /* If the host is reachable, use timeout large enough to allow for multiple
12583 * POKE retries. Limit this value to less than peer->pokefreqok. 5/6 is arbitrary
12584 * multiplier to get value less than peer->pokefreqok. Value less than
12585 * peer->pokefreqok is used to expire current POKE before starting new POKE
12586 * (which is scheduled after peer->pokefreqok). */
12587 poke_timeout = MIN(MAX_RETRY_TIME * 2 + peer->maxms, peer->pokefreqok * 5 / 6);
12588 }
12589
12590 /* Queue up a new task to handle no reply */
12591 peer->pokeexpire = iax2_sched_add(sched, poke_timeout, iax2_poke_noanswer, peer_ref(peer));
12592
12593 if (peer->pokeexpire == -1)
12594 peer_unref(peer);
12595
12596 /* And send the poke */
12597 ast_mutex_lock(&iaxsl[callno]);
12598 if (iaxs[callno]) {
12599 struct iax_ie_data ied = {
12600 .buf = { 0 },
12601 .pos = 0,
12602 };
12603
12604 /* Speed up retransmission times for this qualify call */
12605 iaxs[callno]->pingtime = peer->maxms / 8;
12606 iaxs[callno]->peerpoke = peer;
12607
12608 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
12609 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12610 }
12611 ast_mutex_unlock(&iaxsl[callno]);
12612
12613 return 0;
12614}
static int find_callno(unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, int new, int sockfd, int full_frame)
Definition: chan_iax2.c:3281
static int iax2_poke_noanswer(const void *data)
Definition: chan_iax2.c:12514
struct iax2_peer * peerpoke
Definition: chan_iax2.c:884
#define MIN(a, b)
Definition: utils.h:231

References add_empty_calltoken_ie(), iax2_peer::addr, AST_FRAME_IAX, ast_log, ast_mutex_lock, ast_mutex_unlock, AST_SCHED_DEL, ast_sockaddr_isnull(), iax_ie_data::buf, iax2_peer::callno, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, MAX_RETRY_TIME, iax2_peer::maxms, MIN, iax2_peer::name, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, send_command(), and iax2_peer::sockfd.

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

◆ iax2_poke_peer_cb()

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

Definition at line 12526 of file chan_iax2.c.

12527{
12528 struct iax2_peer *peer = obj;
12529
12530 iax2_poke_peer(peer, 0);
12531
12532 return 0;
12533}

References iax2_poke_peer().

Referenced by load_module().

◆ iax2_poke_peer_s()

static int iax2_poke_peer_s ( const void *  data)
static

Definition at line 9540 of file chan_iax2.c.

9541{
9542 struct iax2_peer *peer = (struct iax2_peer *)data;
9543 peer->pokeexpire = -1;
9544#ifdef SCHED_MULTITHREADED
9546#endif
9547 __iax2_poke_peer_s(data);
9548 return 0;
9549}
static void __iax2_poke_peer_s(const void *data)
Definition: chan_iax2.c:9533

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

Referenced by __iax2_poke_noanswer(), and socket_process_helper().

◆ iax2_predestroy()

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

Definition at line 3483 of file chan_iax2.c.

3484{
3485 struct ast_channel *c = NULL;
3486 struct chan_iax2_pvt *pvt = iaxs[callno];
3487
3488 if (!pvt)
3489 return -1;
3490
3491 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
3494 }
3495
3496 if ((c = pvt->owner)) {
3499 pvt->owner = NULL;
3501 }
3502
3503 return 0;
3504}
static int iax2_queue_hangup(int callno)
Queue a hangup frame on the ast_channel owner.
Definition: chan_iax2.c:3369
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469

References ast_channel_tech_pvt_set(), ast_module_unref, ast_set_flag64, ast_test_flag64, c, chan_iax2_pvt::callno, iax2_destroy_helper(), iax2_queue_hangup(), IAX_ALREADYGONE, iaxs, NULL, chan_iax2_pvt::owner, and ast_module_info::self.

Referenced by iax2_hangup(), and send_command_final().

◆ iax2_process_thread()

static void * iax2_process_thread ( void *  data)
static
Note
For some reason, idle threads are exiting without being removed from an idle list, which is causing memory corruption. Forcibly remove it from the list, if it's there.

Definition at line 12158 of file chan_iax2.c.

12159{
12160 struct iax2_thread *thread = data;
12161 struct timeval wait;
12162 struct timespec ts;
12163 int put_into_idle = 0;
12164 int first_time = 1;
12165 int old_state;
12166
12168
12169 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
12170 pthread_cleanup_push(iax2_process_thread_cleanup, data);
12171
12172 for (;;) {
12173 /* Wait for something to signal us to be awake */
12174 ast_mutex_lock(&thread->lock);
12175
12176 if (thread->stop) {
12177 ast_mutex_unlock(&thread->lock);
12178 break;
12179 }
12180
12181 /* Flag that we're ready to accept signals */
12182 if (first_time) {
12183 signal_condition(&thread->init_lock, &thread->init_cond);
12184 first_time = 0;
12185 }
12186
12187 /* Put into idle list if applicable */
12188 if (put_into_idle) {
12190 }
12191
12192 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
12193 struct iax2_thread *t = NULL;
12194 /* Wait to be signalled or time out */
12195 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
12196 ts.tv_sec = wait.tv_sec;
12197 ts.tv_nsec = wait.tv_usec * 1000;
12198 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
12199 /* This thread was never put back into the available dynamic
12200 * thread list, so just go away. */
12201 if (!put_into_idle || thread->stop) {
12202 ast_mutex_unlock(&thread->lock);
12203 break;
12204 }
12206 /* Account for the case where this thread is acquired *right* after a timeout */
12210 if (t) {
12211 /* This dynamic thread timed out waiting for a task and was
12212 * not acquired immediately after the timeout,
12213 * so it's time to go away. */
12214 ast_mutex_unlock(&thread->lock);
12215 break;
12216 }
12217 /* Someone grabbed our thread *right* after we timed out.
12218 * Wait for them to set us up with something to do and signal
12219 * us to continue. */
12220 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
12221 ts.tv_sec = wait.tv_sec;
12222 ts.tv_nsec = wait.tv_usec * 1000;
12223 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
12224 ast_mutex_unlock(&thread->lock);
12225 break;
12226 }
12227 }
12228 } else {
12229 ast_cond_wait(&thread->cond, &thread->lock);
12230 }
12231
12232 /* Go back into our respective list */
12233 put_into_idle = 1;
12234
12235 ast_mutex_unlock(&thread->lock);
12236
12237 if (thread->stop) {
12238 break;
12239 }
12240
12241 /* See what we need to do */
12242 switch (thread->iostate) {
12243 case IAX_IOSTATE_IDLE:
12244 continue;
12245 case IAX_IOSTATE_READY:
12246 thread->actions++;
12247 thread->iostate = IAX_IOSTATE_PROCESSING;
12250 break;
12252 thread->actions++;
12253 thread->iostate = IAX_IOSTATE_PROCESSING;
12254#ifdef SCHED_MULTITHREADED
12255 thread->schedfunc(thread->scheddata);
12256#endif
12257 break;
12258 default:
12259 break;
12260 }
12261
12262 /* The network thread added us to the active_thread list when we were given
12263 * frames to process, Now that we are done, we must remove ourselves from
12264 * the active list, and return to the idle list */
12268
12269 /* Make sure another frame didn't sneak in there after we thought we were done. */
12271
12272 time(&thread->checktime);
12273 thread->iostate = IAX_IOSTATE_IDLE;
12274#ifdef DEBUG_SCHED_MULTITHREAD
12275 thread->curfunc[0]='\0';
12276#endif
12277 }
12278
12279 /*!
12280 * \note For some reason, idle threads are exiting without being
12281 * removed from an idle list, which is causing memory
12282 * corruption. Forcibly remove it from the list, if it's there.
12283 */
12287
12291
12292 if (!thread->stop) {
12293 /* Nobody asked me to stop so nobody is waiting to join me. */
12294 pthread_detach(pthread_self());
12295 }
12296
12297 /* I am exiting here on my own volition, I need to clean up my own data structures
12298 * Assume that I am no longer in any of the lists (idle, active, or dynamic)
12299 */
12300 pthread_cleanup_pop(1);
12301 return NULL;
12302}
static int iaxactivethreadcount
Definition: chan_iax2.c:724
static void insert_idle_thread(struct iax2_thread *thread)
Definition: chan_iax2.c:1617
static void handle_deferred_full_frames(struct iax2_thread *thread)
Handle any deferred full frames for this thread.
Definition: chan_iax2.c:9854
static void iax2_process_thread_cleanup(void *data)
Definition: chan_iax2.c:12146
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:206

References ast_atomic_fetchadd_int(), ast_cond_timedwait, ast_cond_wait, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), handle_deferred_full_frames(), iax2_process_thread_cleanup(), IAX_IOSTATE_IDLE, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_READY, IAX_IOSTATE_SCHEDREADY, IAX_THREAD_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), iax2_thread::list, NULL, signal_condition(), socket_process(), and thread.

Referenced by find_idle_thread(), and start_network_thread().

◆ iax2_process_thread_cleanup()

static void iax2_process_thread_cleanup ( void *  data)
static

Definition at line 12146 of file chan_iax2.c.

12147{
12148 struct iax2_thread *thread = data;
12149 ast_mutex_destroy(&thread->lock);
12150 ast_cond_destroy(&thread->cond);
12151 ast_mutex_destroy(&thread->init_lock);
12152 ast_cond_destroy(&thread->init_cond);
12154 /* Ignore check_return warning from Coverity for ast_atomic_dec_and_test below */
12156}
int ast_atomic_dec_and_test(volatile int *p)
decrement *p by 1 and return true if the variable has reached 0.
Definition: lock.h:767

References ast_atomic_dec_and_test(), ast_cond_destroy, ast_free, ast_mutex_destroy, iaxactivethreadcount, and thread.

Referenced by iax2_process_thread().

◆ iax2_provision()

static int iax2_provision ( struct ast_sockaddr end,
int  sockfd,
const char *  dest,
const char *  template,
int  force 
)
static

Definition at line 12365 of file chan_iax2.c.

12366{
12367 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
12368 is found for template */
12369 struct iax_ie_data provdata;
12370 struct iax_ie_data ied;
12371 unsigned int sig;
12372 struct ast_sockaddr addr;
12373 int callno;
12374 struct create_addr_info cai;
12375
12376 memset(&cai, 0, sizeof(cai));
12377
12378 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
12379
12380 if (iax_provision_build(&provdata, &sig, template, force)) {
12381 ast_debug(1, "No provisioning found for template '%s'\n", template);
12382 return 0;
12383 }
12384
12385 if (end) {
12386 ast_sockaddr_copy(&addr, end);
12387 cai.sockfd = sockfd;
12388 } else if (create_addr(dest, NULL, &addr, &cai))
12389 return -1;
12390
12391 /* Build the rest of the message */
12392 memset(&ied, 0, sizeof(ied));
12393 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
12394
12395 callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
12396 if (!callno)
12397 return -1;
12398
12399 if (iaxs[callno]) {
12400 /* Schedule autodestruct in case they don't ever give us anything back */
12401 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
12402 sched, 15000, auto_hangup, (void *)(long)callno);
12404 /* Got a call number now, so go ahead and send the provisioning information */
12405 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
12406 }
12407 ast_mutex_unlock(&iaxsl[callno]);
12408
12409 return 1;
12410}
#define IAX_PROVISION
Definition: chan_iax2.c:508
char * end
Definition: eagi_proxy.c:73
@ IAX_COMMAND_PROVISION
Definition: iax2.h:109
#define IAX_IE_PROVISIONING
Definition: iax2.h:159
int iax_provision_build(struct iax_ie_data *provdata, unsigned int *signature, const char *template, int force)
Definition: provision.c:209

References ast_debug, AST_FRAME_IAX, ast_mutex_unlock, ast_set_flag64, ast_sockaddr_copy(), auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), end, find_callno_locked(), iax2_sched_replace(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, NEW_FORCE, NULL, iax_ie_data::pos, send_command(), and create_addr_info::sockfd.

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

◆ iax2_publish_registry()

static void iax2_publish_registry ( const char *  username,
const char *  domain,
const char *  status,
const char *  cause 
)
static

Definition at line 8852 of file chan_iax2.c.

8853{
8854 ast_system_publish_registry("IAX2", username, domain, status, cause);
8855}
void ast_system_publish_registry(const char *channeltype, const char *username, const char *domain, const char *status, const char *cause)
Publish a channel driver outgoing registration message.

References ast_system_publish_registry(), and status.

Referenced by iax2_ack_registry(), and socket_process_helper().

◆ iax2_queryoption()

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

Definition at line 5516 of file chan_iax2.c.

5517{
5518 switch (option) {
5521 {
5522 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5523 ast_mutex_lock(&iaxsl[callno]);
5524 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
5525 ast_mutex_unlock(&iaxsl[callno]);
5526 return 0;
5527 }
5528 default:
5529 return -1;
5530 }
5531}
#define AST_OPTION_SECURE_MEDIA
#define AST_OPTION_SECURE_SIGNALING

References ast_channel_tech_pvt(), ast_mutex_lock, ast_mutex_unlock, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_test_flag64, c, chan_iax2_pvt::callno, IAX_FORCE_ENCRYPT, iaxs, iaxsl, and PTR_TO_CALLNO.

◆ iax2_queue_frame()

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

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

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

Definition at line 3300 of file chan_iax2.c.

3301{
3302 iax2_lock_owner(callno);
3303 if (iaxs[callno] && iaxs[callno]->owner) {
3304 ast_queue_frame(iaxs[callno]->owner, f);
3305 ast_channel_unlock(iaxs[callno]->owner);
3306 }
3307 return 0;
3308}
static void iax2_lock_owner(int callno)
Definition: chan_iax2.c:1381
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition: channel.c:1139

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

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

◆ iax2_queue_hangup()

static int iax2_queue_hangup ( int  callno)
static

Queue a hangup frame on the ast_channel owner.

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

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

Definition at line 3369 of file chan_iax2.c.

3370{
3371 iax2_lock_owner(callno);
3372 if (iaxs[callno] && iaxs[callno]->owner) {
3373 ast_queue_hangup(iaxs[callno]->owner);
3374 ast_channel_unlock(iaxs[callno]->owner);
3375 }
3376 return 0;
3377}

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

Referenced by iax2_predestroy().

◆ iax2_queue_hold()

static int iax2_queue_hold ( int  callno,
const char *  musicclass 
)
static

Queue a hold frame on the ast_channel owner.

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

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

Definition at line 3323 of file chan_iax2.c.

3324{
3325 iax2_lock_owner(callno);
3326 if (iaxs[callno] && iaxs[callno]->owner) {
3327 ast_queue_hold(iaxs[callno]->owner, musicclass);
3328 ast_channel_unlock(iaxs[callno]->owner);
3329 }
3330 return 0;
3331}
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition: channel.c:1191

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

Referenced by socket_process_helper().

◆ iax2_queue_unhold()

static int iax2_queue_unhold ( int  callno)
static

Queue an unhold frame on the ast_channel owner.

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

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

Definition at line 3346 of file chan_iax2.c.

3347{
3348 iax2_lock_owner(callno);
3349 if (iaxs[callno] && iaxs[callno]->owner) {
3350 ast_queue_unhold(iaxs[callno]->owner);
3351 ast_channel_unlock(iaxs[callno]->owner);
3352 }
3353 return 0;
3354}
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1216

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

Referenced by socket_process_helper().

◆ iax2_read()

static struct ast_frame * iax2_read ( struct ast_channel c)
static

Definition at line 5533 of file chan_iax2.c.

5534{
5535 ast_debug(1, "I should never be called!\n");
5536 return &ast_null_frame;
5537}
struct ast_frame ast_null_frame
Definition: main/frame.c:79

References ast_debug, and ast_null_frame.

◆ iax2_register()

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

Definition at line 8966 of file chan_iax2.c.

8967{
8968 char copy[256];
8969 char *username, *hostname, *secret;
8970 char *porta;
8971 char *stringp=NULL;
8972
8973 if (!value)
8974 return -1;
8975
8976 ast_copy_string(copy, value, sizeof(copy));
8977 stringp = copy;
8978 username = strsep(&stringp, "@");
8979 hostname = strsep(&stringp, "@");
8980
8981 if (!hostname) {
8982 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
8983 return -1;
8984 }
8985
8986 stringp = username;
8987 username = strsep(&stringp, ":");
8988 secret = strsep(&stringp, ":");
8989 stringp = hostname;
8990 hostname = strsep(&stringp, ":");
8991 porta = strsep(&stringp, ":");
8992
8993 if (porta && !atoi(porta)) {
8994 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
8995 return -1;
8996 }
8997
8998 return iax2_append_register(hostname, username, secret, porta);
8999}
static int copy(char *infile, char *outfile)
Utility function to copy a file.
static int iax2_append_register(const char *hostname, const char *username, const char *secret, const char *porta)
Definition: chan_iax2.c:8924

References ast_copy_string(), ast_log, copy(), hostname, iax2_append_register(), LOG_WARNING, NULL, iax2_registry::secret, strsep(), iax2_registry::username, and value.

Referenced by set_config().

◆ iax2_request()

static struct ast_channel * iax2_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

Definition at line 12626 of file chan_iax2.c.

12627{
12628 int callno;
12629 int res;
12630 struct ast_sockaddr addr;
12631 struct ast_channel *c;
12632 struct parsed_dial_string pds;
12633 struct create_addr_info cai;
12634 char *tmpstr;
12635 ast_callid callid;
12636
12637 memset(&pds, 0, sizeof(pds));
12638 tmpstr = ast_strdupa(data);
12639 parse_dial_string(tmpstr, &pds);
12640
12642
12643 if (ast_strlen_zero(pds.peer)) {
12644 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
12645 return NULL;
12646 }
12647 memset(&cai, 0, sizeof(cai));
12648 cai.capability = iax2_capability;
12649
12651
12652 /* Populate our address from the given */
12653 if (create_addr(pds.peer, NULL, &addr, &cai)) {
12654 *cause = AST_CAUSE_UNREGISTERED;
12655 return NULL;
12656 }
12657
12658 if (pds.port) {
12659 int bindport;
12660 ast_parse_arg(pds.port, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535);
12661 ast_sockaddr_set_port(&addr, bindport);
12662 }
12663
12664 callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
12665 if (callno < 1) {
12666 ast_log(LOG_WARNING, "Unable to create call\n");
12667 *cause = AST_CAUSE_CONGESTION;
12668 return NULL;
12669 }
12670
12671 /* If this is a trunk, update it now */
12673 if (ast_test_flag64(&cai, IAX_TRUNK)) {
12674 int new_callno;
12675 if ((new_callno = make_trunk(callno, 1)) != -1)
12676 callno = new_callno;
12677 }
12678 iaxs[callno]->maxtime = cai.maxtime;
12679 if (callid) {
12680 iax_pvt_callid_set(callno, callid);
12681 }
12682
12683 if (cai.found) {
12684 ast_string_field_set(iaxs[callno], host, pds.peer);
12685 }
12686
12687 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, &cai.prefs, assignedids,
12688 requestor, cai.found);
12689
12690 ast_mutex_unlock(&iaxsl[callno]);
12691
12692 if (c) {
12693 struct ast_format_cap *joint;
12694 struct ast_format *format;
12695 if (callid) {
12697 ast_channel_callid_set(c, callid);
12699 }
12700
12702 if (!joint) {
12703 ast_hangup(c);
12704 return NULL;
12705 }
12706
12708
12709 /* If there is no joint format find one through translation */
12710 if (!ast_format_cap_count(joint)) {
12711 struct ast_format *best_fmt_cap = NULL;
12712 struct ast_format *best_fmt_native = NULL;
12713
12714 res = ast_translator_best_choice(cap, ast_channel_nativeformats(c), &best_fmt_cap, &best_fmt_native);
12715 if (res < 0) {
12716 struct ast_str *native_cap_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
12718
12719 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12721 ast_format_cap_get_names(cap, &cap_buf),
12723 ast_hangup(c);
12724 ao2_ref(joint, -1);
12725 return NULL;
12726 }
12727 ast_format_cap_append(joint, best_fmt_native, 0);
12728 ao2_ref(best_fmt_cap, -1);
12729 ao2_ref(best_fmt_native, -1);
12730 }
12735
12736 ao2_ref(joint, -1);
12737 ao2_ref(format, -1);
12738 }
12739
12740 return c;
12741}
#define AST_CAUSE_CONGESTION
Definition: causes.h:153
#define AST_CAUSE_UNREGISTERED
Definition: causes.h:154
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)
Create new call, interface with the PBX core.
Definition: chan_iax2.c:5906
static void iax_pvt_callid_set(int callno, ast_callid callid)
Definition: chan_iax2.c:1180
static int make_trunk(unsigned short callno, int locked)
Definition: chan_iax2.c:2380
#define ast_channel_lock(chan)
Definition: channel.h:2922
int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result)
Find the compatible formats between two capabilities structures.
Definition: format_cap.c:628
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Definition: logger.c:2286
int ast_translator_best_choice(struct ast_format_cap *dst_cap, struct ast_format_cap *src_cap, struct ast_format **dst_fmt_out, struct ast_format **src_fmt_out)
Chooses the best translation path.
Definition: translate.c:1402

References ao2_ref, AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_channel_callid_set(), ast_channel_lock, ast_channel_name(), ast_channel_nativeformats(), ast_channel_nativeformats_set(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_unlock, ast_copy_flags64, ast_format_cap_alloc, ast_format_cap_append, ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_compatible(), ast_format_cap_get_format(), ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_hangup(), ast_iax2_new(), ast_log, ast_mutex_unlock, ast_parse_arg(), ast_read_threadstorage_callid(), ast_sockaddr_set_port, AST_STATE_DOWN, ast_str_alloca, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_translator_best_choice(), c, create_addr_info::capability, create_addr(), find_callno_locked(), create_addr_info::found, globalflags, iax2_capability, IAX_NOTRANSFER, iax_pvt_callid_set(), IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, create_addr_info::maxtime, NEW_FORCE, NULL, parse_dial_string(), PARSE_IN_RANGE, PARSE_UINT32, parsed_dial_string::peer, parsed_dial_string::port, create_addr_info::prefs, and create_addr_info::sockfd.

◆ iax2_sched_add()

static int iax2_sched_add ( struct ast_sched_context sched,
int  when,
ast_sched_cb  callback,
const void *  data 
)
static

◆ iax2_sched_replace()

static int iax2_sched_replace ( int  id,
struct ast_sched_context con,
int  when,
ast_sched_cb  callback,
const void *  data 
)
static

Definition at line 1727 of file chan_iax2.c.

1729{
1730 return ast_sched_replace(id, con, when, callback, data);
1731}
int ast_sched_replace(int old_id, struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
replace a scheduler entry
Definition: sched.c:559

References ast_sched_replace().

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

◆ iax2_send()

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

Definition at line 6643 of file chan_iax2.c.

6644{
6645 /* Queue a packet for delivery on a given private structure. Use "ts" for
6646 timestamp, or calculate if ts is 0. Send immediately without retransmission
6647 or delayed, with retransmission */
6648 struct ast_iax2_full_hdr *fh;
6649 struct ast_iax2_mini_hdr *mh;
6650 struct ast_iax2_video_hdr *vh;
6651 struct {
6652 struct iax_frame fr2;
6653 unsigned char buffer[4096];
6654 } frb;
6655 struct iax_frame *fr;
6656 int res;
6657 int sendmini=0;
6658 unsigned int lastsent;
6659 unsigned int fts;
6660
6661 frb.fr2.afdatalen = sizeof(frb.buffer);
6662
6663 if (!pvt) {
6664 ast_log(LOG_WARNING, "No private structure for packet?\n");
6665 return -1;
6666 }
6667
6668 lastsent = pvt->lastsent;
6669
6670 /* Calculate actual timestamp */
6671 fts = calc_timestamp(pvt, ts, f);
6672
6673 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
6674 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we
6675 * increment the "predicted timestamps" for voice, if we're predicting */
6676 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
6677 return 0;
6678#if 0
6680 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
6681 *("=!" + (f->frametype == AST_FRAME_VOICE)),
6682 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
6683 pvt->keyrotateid != -1 ? "" : "no "
6684 );
6685#endif
6686 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
6687 iax2_key_rotate(pvt);
6688 }
6689
6690 if ((ast_test_flag64(pvt, IAX_TRUNK) ||
6691 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
6692 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
6693 /* High two bytes are the same on timestamp, or sending on a trunk */ &&
6695 /* is a voice frame */ &&
6698 /* is the same type */ ) {
6699 /* Force immediate rather than delayed transmission */
6700 now = 1;
6701 /* Mark that mini-style frame is appropriate */
6702 sendmini = 1;
6703 }
6704 if ( f->frametype == AST_FRAME_VIDEO ) {
6705 /*
6706 * If the lower 15 bits of the timestamp roll over, or if
6707 * the video format changed then send a full frame.
6708 * Otherwise send a mini video frame
6709 */
6710 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
6713 ) {
6714 now = 1;
6715 sendmini = 1;
6716 } else {
6717 now = 0;
6718 sendmini = 0;
6719 }
6720 pvt->lastvsent = fts;
6721 }
6722 if (f->frametype == AST_FRAME_IAX) {
6723 /* 0x8000 marks this message as TX:, this bit will be stripped later */
6725 if (!pvt->first_iax_message) {
6727 }
6728 }
6729 /* Allocate an iax_frame */
6730 if (now) {
6731 fr = &frb.fr2;
6732 } else
6734 if (!fr) {
6735 ast_log(LOG_WARNING, "Out of memory\n");
6736 return -1;
6737 }
6738 /* Copy our prospective frame into our immediate or retransmitted wrapper */
6739 iax_frame_wrap(fr, f);
6740
6741 fr->ts = fts;
6742 fr->callno = pvt->callno;
6743 fr->transfer = transfer;
6744 fr->final = final;
6745 fr->encmethods = 0;
6746 if (!sendmini) {
6747 /* We need a full frame */
6748 if (seqno > -1)
6749 fr->oseqno = seqno;
6750 else
6751 fr->oseqno = pvt->oseqno++;
6752 fr->iseqno = pvt->iseqno;
6753 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
6754 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
6755 fh->ts = htonl(fr->ts);
6756 fh->oseqno = fr->oseqno;
6757 if (transfer) {
6758 fh->iseqno = 0;
6759 } else
6760 fh->iseqno = fr->iseqno;
6761 /* Keep track of the last thing we've acknowledged */
6762 if (!transfer)
6763 pvt->aseqno = fr->iseqno;
6764 fh->type = fr->af.frametype & 0xFF;
6765
6766 if (fr->af.frametype == AST_FRAME_VIDEO) {
6768 tmpfmt |= fr->af.subclass.frame_ending ? 0x1LL : 0;
6769 fh->csub = compress_subclass(tmpfmt | ((tmpfmt & 0x1LL) << 6));
6770 } else if (fr->af.frametype == AST_FRAME_VOICE) {
6772 } else {
6774 }
6775
6776 if (transfer) {
6777 fr->dcallno = pvt->transfercallno;
6778 } else
6779 fr->dcallno = pvt->peercallno;
6780 fh->dcallno = htons(fr->dcallno);
6781 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
6782 fr->data = fh;
6783 fr->retries = 0;
6784 /* Retry after 2x the ping time has passed */
6785 fr->retrytime = pvt->pingtime * 2;
6786 if (fr->retrytime < MIN_RETRY_TIME)
6788 if (fr->retrytime > MAX_RETRY_TIME)
6790 /* Acks' don't get retried */
6792 fr->retries = -1;
6793 else if (f->frametype == AST_FRAME_VOICE)
6795 else if (f->frametype == AST_FRAME_VIDEO)
6797 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
6799 if (fr->transfer)
6800 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
6801 else
6802 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
6803 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
6804 fr->encmethods = pvt->encmethods;
6805 fr->ecx = pvt->ecx;
6806 fr->mydcx = pvt->mydcx;
6807 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
6808 } else
6809 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
6810 }
6811
6812 if (now) {
6813 res = send_packet(fr);
6814 } else
6815 res = iax2_transmit(fr);
6816 } else {
6817 if (ast_test_flag64(pvt, IAX_TRUNK)) {
6818 iax2_trunk_queue(pvt, fr);
6819 res = 0;
6820 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
6821 /* Video frame have no sequence number */
6822 fr->oseqno = -1;
6823 fr->iseqno = -1;
6824 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
6825 vh->zeros = 0;
6826 vh->callno = htons(0x8000 | fr->callno);
6827 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.frame_ending ? 0x8000 : 0));
6828 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
6829 fr->data = vh;
6830 fr->retries = -1;
6831 res = send_packet(fr);
6832 } else {
6833 /* Mini-frames have no sequence number */
6834 fr->oseqno = -1;
6835 fr->iseqno = -1;
6836 /* Mini frame will do */
6837 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
6838 mh->callno = htons(fr->callno);
6839 mh->ts = htons(fr->ts & 0xFFFF);
6840 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
6841 fr->data = mh;
6842 fr->retries = -1;
6843 if (pvt->transferring == TRANSFER_MEDIAPASS)
6844 fr->transfer = 1;
6845 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
6847 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
6848 } else
6849 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
6850 }
6851 res = send_packet(fr);
6852 }
6853 }
6854 return res;
6855}
static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
Definition: chan_iax2.c:6360
static unsigned char compress_subclass(iax2_format subclass)
Definition: chan_iax2.c:1860
static int iax2_transmit(struct iax_frame *fr)
Definition: chan_iax2.c:4367
static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
Definition: chan_iax2.c:6576
#define MIN_RETRY_TIME
Definition: chan_iax2.c:704
static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
Definition: chan_iax2.c:6149
static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct ast_sockaddr *addr, int datalen)
Definition: chan_iax2.c:1227
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition: format.h:36
@ IAX_COMMAND_ACK
Definition: iax2.h:55
#define DIRECTION_OUTGRESS
Definition: parser.h:89
struct iax_frame * iax_frame_new(int direction, int datalen, unsigned int cacheable)
Definition: parser.c:1228
void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
Definition: parser.c:1195
unsigned short dcallno
Definition: iax2.h:232
unsigned short callno
Definition: iax2.h:250
unsigned short ts
Definition: iax2.h:251
unsigned short zeros
Definition: iax2.h:271
unsigned short callno
Definition: iax2.h:272
unsigned short ts
Definition: iax2.h:273
unsigned int lastvsent
Definition: chan_iax2.c:762
unsigned char semirand[32]
Definition: parser.h:138
unsigned short dcallno
Definition: parser.h:102
int encmethods
Definition: parser.h:132
int iseqno
Definition: parser.h:128
size_t afdatalen
Definition: parser.h:144
ast_aes_decrypt_key mydcx
Definition: parser.h:136
int datalen
Definition: parser.h:106
ast_aes_encrypt_key ecx
Definition: parser.h:134

References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_compatibility_bitfield2format(), ast_format_compatibility_format2bitfield(), AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log, ast_test_flag64, calc_timestamp(), chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, iax_frame::callno, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, iax_frame::datalen, ast_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, chan_iax2_pvt::ecx, iax_frame::ecx, chan_iax2_pvt::encmethods, iax_frame::encmethods, encrypt_frame(), iax_frame::final, chan_iax2_pvt::first_iax_message, ast_frame_subclass::format, ast_frame_subclass::frame_ending, ast_frame::frametype, iax2_key_rotate(), iax2_transmit(), iax2_trunk_queue(), IAX_CALLENCRYPTED, IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_outputframe(), IAX_TRUNK, ast_frame_subclass::integer, chan_iax2_pvt::iseqno, ast_iax2_full_hdr::iseqno, iax_frame::iseqno, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::last_iax_message, chan_iax2_pvt::lastsent, chan_iax2_pvt::lastvsent, LOG_NOTICE, LOG_WARNING, MARK_IAX_SUBCLASS_TX, MAX_RETRY_TIME, MIN_RETRY_TIME, chan_iax2_pvt::mydcx, iax_frame::mydcx, NULL, chan_iax2_pvt::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, ast_frame::ptr, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, chan_iax2_pvt::semirand, iax_frame::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, transfer(), iax_frame::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_full_hdr::ts, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.

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

◆ iax2_sendhtml()

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

Definition at line 4396 of file chan_iax2.c.

4397{
4398 return send_command_locked(PTR_TO_CALLNO(ast_channel_tech_pvt(c)), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
4399}
@ AST_FRAME_HTML

References ast_channel_tech_pvt(), AST_FRAME_HTML, c, iax_frame::data, iax_frame::datalen, PTR_TO_CALLNO, and send_command_locked().

◆ iax2_sendimage()

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

◆ iax2_sendtext()

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

Definition at line 4384 of file chan_iax2.c.

4385{
4386
4388 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
4389}
char * text
Definition: app_queue.c:1639
@ AST_FRAME_TEXT

References ast_channel_tech_pvt(), AST_FRAME_TEXT, c, PTR_TO_CALLNO, send_command_locked(), and text.

◆ iax2_setoption()

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

Definition at line 5444 of file chan_iax2.c.

5445{
5446 struct ast_option_header *h;
5447 int res;
5448
5449 switch (option) {
5450 case AST_OPTION_TXGAIN:
5451 case AST_OPTION_RXGAIN:
5452 /* these two cannot be sent, because they require a result */
5453 errno = ENOSYS;
5454 return -1;
5455 case AST_OPTION_OPRMODE:
5456 errno = EINVAL;
5457 return -1;
5460 {
5461 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5462 ast_mutex_lock(&iaxsl[callno]);
5463 if ((*(int *) data)) {
5465 } else {
5467 }
5468 ast_mutex_unlock(&iaxsl[callno]);
5469 return 0;
5470 }
5471 /* These options are sent to the other side across the network where
5472 * they will be passed to whatever channel is bridged there. Don't
5473 * do anything silly like pass an option that transmits pointers to
5474 * memory on this machine to a remote machine to use */
5476 case AST_OPTION_TDD:
5481 {
5482 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5483 struct chan_iax2_pvt *pvt;
5484
5486 pvt = iaxs[callno];
5487
5488 if (wait_for_peercallno(pvt)) {
5490 return -1;
5491 }
5492
5494
5495 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
5496 return -1;
5497 }
5498
5499 h->flag = AST_OPTION_FLAG_REQUEST;
5500 h->option = htons(option);
5501 memcpy(h->data, data, datalen);
5503 AST_CONTROL_OPTION, 0, (unsigned char *) h,
5504 datalen + sizeof(*h), -1);
5505 ast_free(h);
5506 return res;
5507 }
5508 default:
5509 return -1;
5510 }
5511
5512 /* Just in case someone does a break instead of a return */
5513 return -1;
5514}
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define AST_OPTION_RELAXDTMF
#define AST_OPTION_TONE_VERIFY
#define AST_OPTION_RXGAIN
#define AST_OPTION_DIGIT_DETECT
#define AST_OPTION_OPRMODE
#define AST_OPTION_TDD
#define AST_OPTION_FLAG_REQUEST
#define AST_OPTION_FAX_DETECT
#define AST_OPTION_TXGAIN
#define AST_OPTION_AUDIO_MODE

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

◆ iax2_transfer()

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

Definition at line 5864 of file chan_iax2.c.

5865{
5866 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5867 struct iax_ie_data ied = { "", };
5868 char tmp[256], *context;
5870 ast_copy_string(tmp, dest, sizeof(tmp));
5871 context = strchr(tmp, '@');
5872 if (context) {
5873 *context = '\0';
5874 context++;
5875 }
5877 if (context)
5879 ast_debug(1, "Transferring '%s' to '%s'\n", ast_channel_name(c), dest);
5881 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
5882}
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1238
@ IAX_COMMAND_TRANSFER
Definition: iax2.h:107
ast_control_transfer
@ AST_TRANSFER_SUCCESS

References ast_channel_name(), ast_channel_tech_pvt(), AST_CONTROL_TRANSFER, ast_copy_string(), ast_debug, AST_FRAME_IAX, ast_queue_control_data(), AST_TRANSFER_SUCCESS, iax_ie_data::buf, c, chan_iax2_pvt::callno, voicemailpwcheck::context, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, iax_ie_data::pos, PTR_TO_CALLNO, send_command_locked(), and tmp().

◆ iax2_transmit()

static int iax2_transmit ( struct iax_frame fr)
static

Definition at line 4367 of file chan_iax2.c.

4368{
4369 fr->sentyet = 0;
4370
4372}
static int transmit_frame(void *data)
Definition: chan_iax2.c:4340
unsigned int sentyet
Definition: parser.h:116
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.

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

Referenced by iax2_send().

◆ iax2_trunk_expired()

static int iax2_trunk_expired ( struct iax2_trunk_peer tpeer,
struct timeval *  now 
)
inlinestatic

Definition at line 9594 of file chan_iax2.c.

9595{
9596 /* Drop when trunk is about 5 seconds idle */
9597 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
9598 return 1;
9599 return 0;
9600}

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

◆ iax2_trunk_queue()

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

Definition at line 6360 of file chan_iax2.c.

6361{
6362 struct ast_frame *f;
6363 struct iax2_trunk_peer *tpeer;
6364 void *tmp, *ptr;
6365 struct timeval now;
6366 struct ast_iax2_meta_trunk_entry *met;
6367 struct ast_iax2_meta_trunk_mini *mtm;
6368
6369 f = &fr->af;
6370 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
6371 if (tpeer) {
6372
6373 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
6374 /* Need to reallocate space */
6375 if (tpeer->trunkdataalloc < trunkmaxsize) {
6377 ast_mutex_unlock(&tpeer->lock);
6378 return -1;
6379 }
6380
6382 tpeer->trunkdata = tmp;
6383 ast_debug(1, "Expanded trunk '%s' to %u bytes\n", ast_sockaddr_stringify(&tpeer->addr), tpeer->trunkdataalloc);
6384 } else {
6385 ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s\n", ast_sockaddr_stringify(&tpeer->addr));
6386 ast_mutex_unlock(&tpeer->lock);
6387 return -1;
6388 }
6389 }
6390
6391 /* Append to meta frame */
6392 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
6394 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
6395 mtm->len = htons(f->datalen);
6396 mtm->mini.callno = htons(pvt->callno);
6397 mtm->mini.ts = htons(0xffff & fr->ts);
6398 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
6399 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
6400 } else {
6401 met = (struct ast_iax2_meta_trunk_entry *)ptr;
6402 /* Store call number and length in meta header */
6403 met->callno = htons(pvt->callno);
6404 met->len = htons(f->datalen);
6405 /* Advance pointers/decrease length past trunk entry header */
6406 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
6407 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
6408 }
6409 /* Copy actual trunk data */
6410 memcpy(ptr, f->data.ptr, f->datalen);
6411 tpeer->trunkdatalen += f->datalen;
6412
6413 tpeer->calls++;
6414
6415 /* track the largest mtu we actually have sent */
6416 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
6417 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
6418
6419 /* if we have enough for a full MTU, ship it now without waiting */
6420 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
6421 now = ast_tvnow();
6422 send_trunk(tpeer, &now);
6423 trunk_untimed ++;
6424 }
6425
6426 ast_mutex_unlock(&tpeer->lock);
6427 }
6428 return 0;
6429}
#define ast_realloc(p, len)
A wrapper for realloc()
Definition: astmm.h:226
#define IAX_TRUNKTIMESTAMPS
Definition: chan_iax2.c:519
static struct iax2_trunk_peer * find_tpeer(struct ast_sockaddr *addr, int fd)
Definition: chan_iax2.c:6324
static int trunkmaxsize
Definition: chan_iax2.c:343
#define IAX2_TRUNK_PREFACE
Definition: chan_iax2.c:638
#define DEFAULT_TRUNKDATA
Definition: chan_iax2.c:710
static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
Definition: chan_iax2.c:9551
Definition: iax2.h:282
unsigned short callno
Definition: iax2.h:283
unsigned short len
Definition: iax2.h:284
unsigned short len
Definition: iax2.h:289
struct ast_iax2_mini_hdr mini
Definition: iax2.h:290
unsigned int trunkdataalloc
Definition: chan_iax2.c:652
unsigned int trunkdatalen
Definition: chan_iax2.c:651
unsigned char * trunkdata
Definition: chan_iax2.c:650

References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_debug, ast_log, ast_mutex_unlock, ast_realloc, ast_sockaddr_stringify(), ast_test_flag64, ast_tvnow(), chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, ast_iax2_meta_trunk_entry::callno, iax2_trunk_peer::calls, ast_frame::data, ast_frame::datalen, DEFAULT_TRUNKDATA, find_tpeer(), global_max_trunk_mtu, globalflags, IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, ast_frame::ptr, send_trunk(), chan_iax2_pvt::sockfd, tmp(), trunk_maxmtu, trunk_untimed, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, trunkmaxsize, ast_iax2_mini_hdr::ts, and iax_frame::ts.

Referenced by iax2_send().

◆ iax2_vnak()

static int iax2_vnak ( int  callno)
static

Definition at line 9515 of file chan_iax2.c.

9516{
9517 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
9518}
static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
Definition: chan_iax2.c:7866
@ IAX_COMMAND_VNAK
Definition: iax2.h:75

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

Referenced by socket_process_helper(), and socket_process_meta().

◆ iax2_write()

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

Definition at line 7783 of file chan_iax2.c.

7784{
7785 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
7786 int res = -1;
7787 ast_mutex_lock(&iaxsl[callno]);
7788 if (iaxs[callno]) {
7789 /* If there's an outstanding error, return failure now */
7790 if (!iaxs[callno]->error) {
7791 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
7792 res = 0;
7793 /* Don't waste bandwidth sending null frames */
7794 else if (f->frametype == AST_FRAME_NULL)
7795 res = 0;
7796 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
7797 res = 0;
7798 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
7799 res = 0;
7800 else
7801 /* Simple, just queue for transmission */
7802 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
7803 } else {
7804 ast_debug(1, "Write error: %s\n", strerror(errno));
7805 }
7806 }
7807 /* If it's already gone, just return */
7808 ast_mutex_unlock(&iaxsl[callno]);
7809 return res;
7810}
#define IAX_QUELCH
Definition: chan_iax2.c:509
@ AST_FRAME_NULL

References ast_channel_tech_pvt(), ast_debug, AST_FRAME_NULL, AST_FRAME_VOICE, ast_mutex_lock, ast_mutex_unlock, ast_test_flag, ast_test_flag64, c, iax2_peer::callno, errno, error(), ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, and PTR_TO_CALLNO.

◆ iax_debug_output()

static void iax_debug_output ( const char *  data)
static

Definition at line 1245 of file chan_iax2.c.

1246{
1247 if (iaxdebug)
1248 ast_verbose("%s", data);
1249}
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2206

References ast_verbose(), and iaxdebug.

Referenced by load_module().

◆ iax_error_output()

static void iax_error_output ( const char *  data)
static

Definition at line 1251 of file chan_iax2.c.

1252{
1253 ast_log(LOG_WARNING, "%s", data);
1254}

References ast_log, and LOG_WARNING.

Referenced by load_module().

◆ iax_outputframe()

static void iax_outputframe ( struct iax_frame f,
struct ast_iax2_full_hdr fhi,
int  rx,
struct ast_sockaddr addr,
int  datalen 
)
static

Definition at line 1227 of file chan_iax2.c.

1228{
1229 if (iaxdebug ||
1230 (addr && !ast_sockaddr_isnull(&debugaddr) &&
1233 !ast_sockaddr_cmp_addr(&debugaddr, addr))) {
1234
1235 if (iaxdebug) {
1236 iax_showframe(f, fhi, rx, addr, datalen);
1237 } else {
1238 iaxdebug = 1;
1239 iax_showframe(f, fhi, rx, addr, datalen);
1240 iaxdebug = 0;
1241 }
1242 }
1243}
void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct ast_sockaddr *addr, int datalen)
Definition: parser.c:595

References ast_sockaddr_cmp_addr(), ast_sockaddr_isnull(), ast_sockaddr_port, debugaddr, iax_showframe(), and iaxdebug.

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

◆ iax_pvt_callid_get()

static ast_callid iax_pvt_callid_get ( int  callno)
static

Definition at line 1175 of file chan_iax2.c.

1176{
1177 return iaxs[callno]->callid;
1178}
ast_callid callid
Definition: chan_iax2.c:746

References chan_iax2_pvt::callid, chan_iax2_pvt::callno, and iaxs.

Referenced by socket_process_helper().

◆ iax_pvt_callid_new()

static void iax_pvt_callid_new ( int  callno)
static

Definition at line 1185 of file chan_iax2.c.

1186{
1187 ast_callid callid = ast_create_callid();
1188 char buffer[AST_CALLID_BUFFER_LENGTH];
1189 ast_callid_strnprint(buffer, sizeof(buffer), callid);
1190 iax_pvt_callid_set(callno, callid);
1191}
void ast_callid_strnprint(char *buffer, size_t buffer_size, ast_callid callid)
copy a string representation of the callid into a target string
Definition: logger.c:2276
#define AST_CALLID_BUFFER_LENGTH
ast_callid ast_create_callid(void)
factory function to create a new uniquely identifying callid.
Definition: logger.c:2281

References AST_CALLID_BUFFER_LENGTH, ast_callid_strnprint(), ast_create_callid(), chan_iax2_pvt::callid, chan_iax2_pvt::callno, and iax_pvt_callid_set().

Referenced by socket_process_helper().

◆ iax_pvt_callid_set()

static void iax_pvt_callid_set ( int  callno,
ast_callid  callid 
)
static

Definition at line 1180 of file chan_iax2.c.

1181{
1182 iaxs[callno]->callid = callid;
1183}

References chan_iax2_pvt::callid, chan_iax2_pvt::callno, and iaxs.

Referenced by iax2_request(), and iax_pvt_callid_new().

◆ iaxfrdup2()

static struct iax_frame * iaxfrdup2 ( struct iax_frame fr)
static

Definition at line 2333 of file chan_iax2.c.

2334{
2336 if (new) {
2337 size_t afdatalen = new->afdatalen;
2338 memcpy(new, fr, sizeof(*new));
2339 iax_frame_wrap(new, &fr->af);
2340 new->afdatalen = afdatalen;
2341 new->data = NULL;
2342 new->datalen = 0;
2343 new->direction = DIRECTION_INGRESS;
2344 new->retrans = -1;
2345 }
2346 return new;
2347}
#define DIRECTION_INGRESS
Definition: parser.h:88
unsigned int cacheable
Definition: parser.h:124

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

Referenced by socket_process_helper(), and socket_process_meta().

◆ insert_idle_thread()

static void insert_idle_thread ( struct iax2_thread thread)
static

Definition at line 1617 of file chan_iax2.c.

1618{
1619 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
1623 } else {
1627 }
1628
1629 return;
1630}

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_THREAD_TYPE_DYNAMIC, and thread.

Referenced by iax2_process_thread().

◆ invalid_key()

static int invalid_key ( ast_aes_decrypt_key ecx)
static

Definition at line 6443 of file chan_iax2.c.

6444{
6445#ifdef HAVE_OPENSSL
6446 int i;
6447 for (i = 0; i < 60; i++) {
6448 if (ecx->raw[i]) {
6449 return 0; /* stop if we encounter anything non-zero */
6450 }
6451 }
6452 /* if ast_aes_encrypt or ast_aes_decrypt is called, then we'll crash when calling AES_encrypt or AES_decrypt */
6453 return -1;
6454#else
6455 return 0; /* Can't verify, but doesn't matter anyways */
6456#endif
6457}
unsigned char raw[AST_CRYPTO_AES_BLOCKSIZE/8]
Definition: crypto.h:40

References aes_key::raw.

Referenced by authenticate_reply().

◆ jb_debug_output()

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

Definition at line 1280 of file chan_iax2.c.

1281{
1282 va_list args;
1283 char buf[1024];
1284
1285 va_start(args, fmt);
1286 vsnprintf(buf, sizeof(buf), fmt, args);
1287 va_end(args);
1288
1289 ast_verbose("%s", buf);
1290}

References args, ast_verbose(), and buf.

Referenced by handle_cli_iax2_set_debug_jb().

◆ jb_error_output()

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

Definition at line 1256 of file chan_iax2.c.

1257{
1258 va_list args;
1259 char buf[1024];
1260
1261 va_start(args, fmt);
1262 vsnprintf(buf, sizeof(buf), fmt, args);
1263 va_end(args);
1264
1265 ast_log(LOG_ERROR, "%s", buf);
1266}

References args, ast_log, buf, and LOG_ERROR.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

◆ jb_warning_output()

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

Definition at line 1268 of file chan_iax2.c.

1269{
1270 va_list args;
1271 char buf[1024];
1272
1273 va_start(args, fmt);
1274 vsnprintf(buf, sizeof(buf), fmt, args);
1275 va_end(args);
1276
1277 ast_log(LOG_WARNING, "%s", buf);
1278}

References args, ast_log, buf, and LOG_WARNING.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

◆ load_module()

static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 14990 of file chan_iax2.c.

14991{
14992 static const char config[] = "iax.conf";
14993 int x = 0;
14994 struct iax2_registry *reg = NULL;
14995
14998 }
15000
15001 if (load_objects()) {
15005 }
15006
15007 memset(iaxs, 0, sizeof(iaxs));
15008
15009 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
15010 ast_mutex_init(&iaxsl[x]);
15011 }
15012
15013 if (!(sched = ast_sched_context_create())) {
15014 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
15018 }
15019
15024 sched = NULL;
15026 }
15027
15028 if (!(io = io_context_create())) {
15029 ast_log(LOG_ERROR, "Failed to create I/O context\n");
15033 sched = NULL;
15035 }
15036
15037 if (!(netsock = ast_netsock_list_alloc())) {
15038 ast_log(LOG_ERROR, "Failed to create netsock list\n");
15043 sched = NULL;
15045 }
15047
15049 if (!outsock) {
15050 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
15055 sched = NULL;
15057 }
15059
15061
15065
15066 if ((timer = ast_timer_open())) {
15068 }
15069
15070 if (set_config(config, 0, 0) == -1) {
15071 if (timer) {
15073 timer = NULL;
15074 }
15077 }
15078
15080
15082
15085
15090
15092 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
15095 }
15096
15098 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
15099 }
15100
15101 if (start_network_thread()) {
15102 ast_log(LOG_ERROR, "Unable to start network thread\n");
15105 } else {
15106 ast_verb(2, "IAX Ready and Listening\n");
15107 }
15108
15111 iax2_do_register(reg);
15113
15116
15117
15120
15121 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
15122
15124
15126}
static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
callback to display iax peers in manager
Definition: chan_iax2.c:7345
static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:12526
static void iax_error_output(const char *data)
Definition: chan_iax2.c:1251
static struct ast_custom_function iaxvar_function
Definition: chan_iax2.c:10198
static int __unload_module(void)
Definition: chan_iax2.c:14763
static struct ast_custom_function iaxpeer_function
Definition: chan_iax2.c:14624
static int load_objects(void)
Definition: chan_iax2.c:14897
static void iax_debug_output(const char *data)
Definition: chan_iax2.c:1245
static int set_config(const char *config_file, int reload, int forced)
Load configuration.
Definition: chan_iax2.c:13646
static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
Definition: chan_iax2.c:7298
static void network_change_stasis_subscribe(void)
Definition: chan_iax2.c:1501
static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
Definition: chan_iax2.c:7469
static int trunkfreq
Definition: chan_iax2.c:342
static struct io_context * io
Definition: chan_iax2.c:456
static int peer_set_sock_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:14851
static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
callback to display iax peers in manager format
Definition: chan_iax2.c:7367
static int start_network_thread(void)
Definition: chan_iax2.c:12768
static const char config[]
Definition: chan_ooh323.c:111
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
@ AST_MEDIA_TYPE_UNKNOWN
Definition: codec.h:31
#define SENTINEL
Definition: compiler.h:87
void iax_firmware_reload(void)
Definition: firmware.c:206
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition: format_cap.c:216
static int iax2_prov_app(struct ast_channel *chan, const char *data)
Definition: chan_iax2.c:12417
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
Definition: main/config.c:3549
struct io_context * io_context_create(void)
Creates a context Create a context for I/O operations Basically mallocs an IO structure and sets up s...
Definition: io.c:81
void io_context_destroy(struct io_context *ioc)
Destroys a context.
Definition: io.c:107
#define EVENT_FLAG_REPORTING
Definition: manager.h:84
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626
struct ast_netsock_list * ast_netsock_list_alloc(void)
Definition: netsock.c:72
int ast_netsock_init(struct ast_netsock_list *list)
Definition: netsock.c:77
void iax_set_output(void(*output)(const char *data))
void iax_set_error(void(*output)(const char *data))
int ast_register_switch(struct ast_switch *sw)
Register an alternative dialplan switch.
Definition: pbx_switch.c:58
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1558
int iax_provision_reload(int reload)
Definition: provision.c:526
int ast_sched_start_thread(struct ast_sched_context *con)
Start a thread for processing scheduler entries.
Definition: sched.c:197
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:238
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
Definition: timing.c:166
struct ast_timer * ast_timer_open(void)
Open a timer.
Definition: timing.c:122

References __unload_module(), ao2_callback, ao2_ref, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple, ast_custom_function_register, ast_format_cap_alloc, ast_format_cap_append_by_type(), AST_FORMAT_CAP_FLAG_DEFAULT, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_manager_register_xml, AST_MEDIA_TYPE_UNKNOWN, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_mutex_init, ast_netsock_init(), ast_netsock_list_alloc(), ast_random(), ast_realtime_require_field(), ast_register_application_xml, ast_register_switch(), ast_sched_context_create(), ast_sched_context_destroy(), ast_sched_start_thread(), ast_timer_close(), ast_timer_open(), ast_timer_set_rate(), ast_verb, ast_channel_tech::capabilities, cli_iax2, config, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), iax_firmware_reload(), iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxs, iaxsl, iaxvar_function, io, io_context_create(), io_context_destroy(), jb_error_output(), jb_setoutput(), jb_warning_output(), load_objects(), LOG_ERROR, manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), netsock, network_change_stasis_subscribe(), NULL, outsock, papp, peer_set_sock_cb(), randomcalltokendata, RQ_CHAR, RQ_UINTEGER2, SENTINEL, set_config(), start_network_thread(), timer, and trunkfreq.

◆ load_objects()

static int load_objects ( void  )
static

Definition at line 14897 of file chan_iax2.c.

14898{
14901
14904 if (!peers) {
14905 goto container_fail;
14906 }
14907
14910 if (!users) {
14911 goto container_fail;
14912 }
14913
14916 if (!iax_peercallno_pvts) {
14917 goto container_fail;
14918 }
14919
14923 goto container_fail;
14924 }
14925
14928 if (!peercnts) {
14929 goto container_fail;
14930 }
14931
14934 if (!callno_limits) {
14935 goto container_fail;
14936 }
14937
14940 if (!calltoken_ignores) {
14941 goto container_fail;
14942 }
14943
14944 if (create_callno_pools()) {
14945 goto container_fail;
14946 }
14947
14949 if (!transmit_processor) {
14950 goto container_fail;
14951 }
14952
14953 return 0;
14954
14955container_fail:
14956 if (peers) {
14957 ao2_ref(peers, -1);
14958 }
14959 if (users) {
14960 ao2_ref(users, -1);
14961 }
14962 if (iax_peercallno_pvts) {
14964 }
14967 }
14968 if (peercnts) {
14969 ao2_ref(peercnts, -1);
14970 }
14971 if (callno_limits) {
14973 }
14974 if (calltoken_ignores) {
14976 }
14977 return -1;
14978}
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
#define MAX_USER_BUCKETS
Definition: chan_iax2.c:1002
static int peer_hash_cb(const void *obj, const int flags)
Definition: chan_iax2.c:2009
static int peercnt_hash_cb(const void *obj, const int flags)
Definition: chan_iax2.c:2506
static int peer_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:2020
static int addr_range_hash_cb(const void *obj, const int flags)
Definition: chan_iax2.c:2492
static int pvt_hash_cb(const void *obj, const int flags)
Definition: chan_iax2.c:14861
static int user_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:2043
static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:14886
static int pvt_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:14868
static int create_callno_pools(void)
Definition: chan_iax2.c:3068
static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
Definition: chan_iax2.c:14879
static int user_hash_cb(const void *obj, const int flags)
Definition: chan_iax2.c:2032
static int addr_range_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:2498
#define MAX_PEER_BUCKETS
Definition: chan_iax2.c:998
static int peercnt_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:2516
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary.
@ TPS_REF_DEFAULT
return a reference to a taskprocessor, create one if it does not exist
Definition: taskprocessor.h:76

References addr_range_cmp_cb(), addr_range_hash_cb(), AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_ref, ast_taskprocessor_get(), callno_limits, calltoken_ignores, create_callno_pools(), IAX_MAX_CALLS, iax_peercallno_pvts, iax_transfercallno_pvts, MAX_PEER_BUCKETS, MAX_USER_BUCKETS, NULL, peer_cmp_cb(), peer_hash_cb(), peercnt_cmp_cb(), peercnt_hash_cb(), peercnts, pvt_cmp_cb(), pvt_hash_cb(), TPS_REF_DEFAULT, transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), transmit_processor, user_cmp_cb(), and user_hash_cb().

Referenced by load_module().

◆ log_jitterstats()

static void log_jitterstats ( unsigned short  callno)
static

Definition at line 9811 of file chan_iax2.c.

9812{
9813 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
9814 jb_info jbinfo;
9815
9816 ast_mutex_lock(&iaxsl[callno]);
9817 if (iaxs[callno] && iaxs[callno]->owner && ast_channel_name(iaxs[callno]->owner)) {
9818 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
9819 jb_getinfo(iaxs[callno]->jb, &jbinfo);
9820 localjitter = jbinfo.jitter;
9821 localdelay = jbinfo.current - jbinfo.min;
9822 locallost = jbinfo.frames_lost;
9823 locallosspct = jbinfo.losspct/1000;
9824 localdropped = jbinfo.frames_dropped;
9825 localooo = jbinfo.frames_ooo;
9826 localpackets = jbinfo.frames_in;
9827 }
9828 ast_debug(3, "JB STATS:%s ping=%u ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n",
9829 ast_channel_name(iaxs[callno]->owner),
9830 iaxs[callno]->pingtime,
9831 localjitter,
9832 localdelay,
9833 locallost,
9834 locallosspct,
9835 localdropped,
9836 localooo,
9837 localpackets,
9838 iaxs[callno]->remote_rr.jitter,
9839 iaxs[callno]->remote_rr.delay,
9840 iaxs[callno]->remote_rr.losscnt,
9841 iaxs[callno]->remote_rr.losspct/1000,
9842 iaxs[callno]->remote_rr.dropped,
9843 iaxs[callno]->remote_rr.ooo,
9844 iaxs[callno]->remote_rr.packets);
9845 }
9846 ast_mutex_unlock(&iaxsl[callno]);
9847}

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

Referenced by socket_process_helper().

◆ make_trunk()

static int make_trunk ( unsigned short  callno,
int  locked 
)
static
Note
We delete these before switching the slot, because if they fire in the meantime, they will generate a warning.

Definition at line 2380 of file chan_iax2.c.

2381{
2382 int x;
2383 int res= 0;
2385 if (iaxs[callno]->oseqno) {
2386 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
2387 return -1;
2388 }
2389 if (callno >= TRUNK_CALL_START) {
2390 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
2391 return -1;
2392 }
2393
2397 &entry)) {
2398 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
2399 return -1;
2400 }
2401
2403 ast_mutex_lock(&iaxsl[x]);
2404
2405 /*!
2406 * \note We delete these before switching the slot, because if
2407 * they fire in the meantime, they will generate a warning.
2408 */
2409 AST_SCHED_DEL(sched, iaxs[callno]->pingid);
2410 AST_SCHED_DEL(sched, iaxs[callno]->lagid);
2411 iaxs[callno]->lagid = iaxs[callno]->pingid = -1;
2412 iaxs[x] = iaxs[callno];
2413 iaxs[x]->callno = x;
2414
2415 /* since we copied over the pvt from a different callno, make sure the old entry is replaced
2416 * before assigning the new one */
2417 if (iaxs[x]->callno_entry) {
2419 sched,
2420 MIN_REUSE_TIME * 1000,
2423
2424 }
2425 iaxs[x]->callno_entry = entry;
2426
2427 iaxs[callno] = NULL;
2428 /* Update the two timers that should have been started */
2430 ping_time * 1000, send_ping, (void *)(long)x);
2432 lagrq_time * 1000, send_lagrq, (void *)(long)x);
2433
2434 if (locked)
2435 ast_mutex_unlock(&iaxsl[callno]);
2436 res = x;
2437 if (!locked)
2439
2440 /* We moved this call from a non-trunked to a trunked call */
2441 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
2442
2443 return res;
2444}
#define CALLNO_ENTRY_IS_VALIDATED(a)
Definition: chan_iax2.c:954
#define MIN_REUSE_TIME
Definition: chan_iax2.c:303

References ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, AST_SCHED_DEL, chan_iax2_pvt::callno, iax_frame::callno, chan_iax2_pvt::callno_entry, CALLNO_ENTRY_GET_CALLNO, CALLNO_ENTRY_IS_VALIDATED, CALLNO_ENTRY_TO_PTR, CALLNO_TYPE_TRUNK, get_unused_callno(), iax2_sched_add(), iaxs, iaxsl, chan_iax2_pvt::lagid, lagrq_time, LOG_WARNING, MIN_REUSE_TIME, NULL, iax_frame::oseqno, ping_time, chan_iax2_pvt::pingid, replace_callno(), send_lagrq(), send_ping(), and TRUNK_CALL_START.

Referenced by iax2_request(), and socket_process_helper().

◆ manager_iax2_show_netstats()

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

Definition at line 7298 of file chan_iax2.c.

7299{
7300 ast_cli_netstats(s, -1, 0);
7301 astman_append(s, "\r\n");
7302 return RESULT_SUCCESS;
7303}

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

Referenced by load_module().

◆ manager_iax2_show_peer_list()

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

callback to display iax peers in manager format

Definition at line 7367 of file chan_iax2.c.

7368{
7369 struct show_peers_context cont = {
7370 .havepattern = 0,
7371 .idtext = "",
7372 .registeredonly = 0,
7373
7374 .peerlist = 1,
7375
7376 .total_peers = 0,
7377 .online_peers = 0,
7378 .offline_peers = 0,
7379 .unmonitored_peers = 0,
7380 };
7381
7382 struct iax2_peer *peer = NULL;
7383 struct ao2_iterator i;
7384
7385 const char *id = astman_get_header(m,"ActionID");
7386
7387 if (!ast_strlen_zero(id)) {
7388 snprintf(cont.idtext, sizeof(cont.idtext), "ActionID: %s\r\n", id);
7389 }
7390
7391 astman_send_listack(s, m, "IAX Peer status list will follow", "start");
7392
7393 i = ao2_iterator_init(peers, 0);
7394 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
7395 _iax2_show_peers_one(-1, s, &cont, peer);
7396 }
7398
7399 astman_send_list_complete_start(s, m, "PeerlistComplete", cont.total_peers);
7401
7402 return RESULT_SUCCESS;
7403}
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:3423
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:3459
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:3042
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3467

References _iax2_show_peers_one(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strlen_zero(), astman_get_header(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), show_peers_context::havepattern, show_peers_context::idtext, NULL, peer_unref(), RESULT_SUCCESS, and show_peers_context::total_peers.

Referenced by load_module().

◆ manager_iax2_show_peers()

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

callback to display iax peers in manager

Definition at line 7345 of file chan_iax2.c.

7346{
7347 static const char * const a[] = { "iax2", "show", "peers" };
7348 const char *id = astman_get_header(m,"ActionID");
7349 char idtext[256] = "";
7350 int total = 0;
7351
7352 if (!ast_strlen_zero(id))
7353 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
7354
7355 astman_send_listack(s, m, "Peer status list will follow", "start");
7356
7357 /* List the peers in separate manager events */
7358 __iax2_show_peers(-1, &total, s, 3, a);
7359
7360 /* Send final confirmation */
7361 astman_send_list_complete_start(s, m, "PeerlistComplete", total);
7363 return 0;
7364}

References __iax2_show_peers(), a, ast_strlen_zero(), astman_get_header(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), and total.

Referenced by load_module().

◆ manager_iax2_show_registry()

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

Definition at line 7469 of file chan_iax2.c.

7470{
7471 const char *id = astman_get_header(m, "ActionID");
7472 struct iax2_registry *reg = NULL;
7473 char idtext[256] = "";
7474 char host[80] = "";
7475 char perceived[80] = "";
7476 int total = 0;
7477
7478 if (!ast_strlen_zero(id))
7479 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
7480
7481 astman_send_listack(s, m, "Registrations will follow", "start");
7482
7485 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
7486
7487 snprintf(perceived, sizeof(perceived), "%s", ast_sockaddr_isnull(&reg->us) ? "<Unregistered>" : ast_sockaddr_stringify(&reg->us));
7488
7489 astman_append(s,
7490 "Event: RegistryEntry\r\n"
7491 "%s"
7492 "Host: %s\r\n"
7493 "DNSmanager: %s\r\n"
7494 "Username: %s\r\n"
7495 "Perceived: %s\r\n"
7496 "Refresh: %d\r\n"
7497 "State: %s\r\n"
7498 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
7499 reg->refresh, regstate2str(reg->regstate));
7500
7501 total++;
7502 }
7504
7505 astman_send_list_complete_start(s, m, "RegistrationsComplete", total);
7507
7508 return 0;
7509}

References iax2_registry::addr, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), iax2_registry::dnsmgr, NULL, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), total, iax2_registry::us, and iax2_registry::username.

Referenced by load_module().

◆ match()

static int match ( struct ast_sockaddr addr,
unsigned short  callno,
unsigned short  dcallno,
const struct chan_iax2_pvt cur,
int  check_dcallno 
)
static
Examples
app_skel.c.

Definition at line 2362 of file chan_iax2.c.

2363{
2364 if (!ast_sockaddr_cmp(&cur->addr, addr)) {
2365 /* This is the main host */
2366 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
2367 (check_dcallno ? dcallno == cur->callno : 1) ) {
2368 /* That's us. Be sure we keep track of the peer call number */
2369 return 1;
2370 }
2371 }
2372 if (!ast_sockaddr_cmp(&cur->transfer, addr) && cur->transferring) {
2373 /* We're transferring */
2374 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
2375 return 1;
2376 }
2377 return 0;
2378}

References chan_iax2_pvt::addr, ast_sockaddr_cmp(), chan_iax2_pvt::callno, iax_frame::callno, iax_frame::dcallno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.

Referenced by __find_callno(), aco_process_config(), action_listcategories(), ast_category_insert(), ast_cdr_generic_unregister(), ast_msg_handler_register(), ast_msg_handler_unregister(), ast_msg_tech_register(), ast_msg_tech_unregister(), ast_namedgroups_intersect(), ast_parse_device_state(), ast_refer_tech_register(), ast_refer_tech_unregister(), ast_sched_clean_by_callback(), ast_srtp_add_stream(), ast_srtp_change_source(), ast_variable_delete(), ast_variable_update(), ast_xml_doc_item_cmp(), check_blacklist(), cli_print_body(), cli_show_module_options(), cli_show_module_type(), common_identify(), detect_callback(), does_category_match(), find_command(), find_option_cb(), generic_mute_unmute_helper(), get_device_state_causing_channels(), handle_updates(), has_destination_cb(), help1(), help_workhorse(), internal_aco_type_category_check(), internal_aco_type_find(), internal_ao2_traverse(), kick_conference_participant(), lua_find_extension(), namedgroup_match(), pbx_find_extension(), pvt_cmp_cb(), read_dirs_cb(), realtime_switch_common(), scan_exec(), skel_level_cmp(), test_item_cmp(), transfercallno_pvt_cmp_cb(), xmldoc_attribute_match(), xmldoc_get_syntax_config_object(), and xmpp_config_cmp().

◆ memcpy_decrypt()

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

Definition at line 6475 of file chan_iax2.c.

6476{
6477#if 0
6478 /* Debug with "fake encryption" */
6479 int x;
6480 if (len % 16)
6481 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
6482 for (x=0;x<len;x++)
6483 dst[x] = src[x] ^ 0xff;
6484#else
6485 unsigned char lastblock[16] = { 0 };
6486 int x;
6487 while(len > 0) {
6488 ast_aes_decrypt(src, dst, dcx);
6489 for (x=0;x<16;x++)
6490 dst[x] ^= lastblock[x];
6491 memcpy(lastblock, src, sizeof(lastblock));
6492 dst += 16;
6493 src += 16;
6494 len -= 16;
6495 }
6496#endif
6497}
int ast_aes_decrypt(const unsigned char *in, unsigned char *out, const ast_aes_decrypt_key *key)
AES decrypt data.
Definition: res_crypto.c:790

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

Referenced by decode_frame().

◆ memcpy_encrypt()

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

Definition at line 6499 of file chan_iax2.c.

6500{
6501#if 0
6502 /* Debug with "fake encryption" */
6503 int x;
6504 if (len % 16)
6505 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
6506 for (x=0;x<len;x++)
6507 dst[x] = src[x] ^ 0xff;
6508#else
6509 unsigned char curblock[16] = { 0 };
6510 int x;
6511 while(len > 0) {
6512 for (x=0;x<16;x++)
6513 curblock[x] ^= src[x];
6514 ast_aes_encrypt(curblock, dst, ecx);
6515 memcpy(curblock, dst, sizeof(curblock));
6516 dst += 16;
6517 src += 16;
6518 len -= 16;
6519 }
6520#endif
6521}
int ast_aes_encrypt(const unsigned char *in, unsigned char *out, const ast_aes_encrypt_key *key)
AES encrypt data.
Definition: res_crypto.c:749

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

Referenced by encrypt_frame().

◆ merge_encryption()

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

Definition at line 8136 of file chan_iax2.c.

8137{
8138 /* Select exactly one common encryption if there are any */
8139 p->encmethods &= enc;
8140 if (p->encmethods) {
8141 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */
8142 p->keyrotateid = -2;
8143 }
8146 else
8147 p->encmethods = 0;
8148 }
8149}

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

Referenced by authenticate_reply(), and socket_process_helper().

◆ network_change_sched_cb()

static int network_change_sched_cb ( const void *  data)
static

Definition at line 1531 of file chan_iax2.c.

1532{
1533 struct iax2_registry *reg;
1537 iax2_do_register(reg);
1538 }
1540
1541 return 0;
1542}
static int network_change_sched_id
Definition: chan_iax2.c:329

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_do_register(), and network_change_sched_id.

Referenced by network_change_stasis_cb().

◆ network_change_stasis_cb()

static void network_change_stasis_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 1544 of file chan_iax2.c.

1546{
1547 /* This callback is only concerned with network change messages from the system topic. */
1549 return;
1550 }
1551
1552 ast_verb(1, "IAX, got a network change message, renewing all IAX registrations.\n");
1553 if (network_change_sched_id == -1) {
1555 }
1556}
static int network_change_sched_cb(const void *data)
Definition: chan_iax2.c:1531
struct stasis_message_type * ast_network_change_type(void)
A stasis_message_type for network changes.

References ast_network_change_type(), ast_verb, iax2_sched_add(), network_change_sched_cb(), network_change_sched_id, NULL, and stasis_message_type().

Referenced by network_change_stasis_subscribe().

◆ network_change_stasis_subscribe()

static void network_change_stasis_subscribe ( void  )
static

Definition at line 1501 of file chan_iax2.c.

1502{
1503 if (!network_change_sub) {
1508 }
1509}
static void network_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: chan_iax2.c:1544
static struct stasis_subscription * network_change_sub
Definition: chan_iax2.c:327
struct stasis_topic * ast_system_topic(void)
A Stasis Message Bus API topic which publishes messages regarding system changes.

References ast_network_change_type(), ast_system_topic(), network_change_stasis_cb(), network_change_sub, NULL, stasis_subscribe, stasis_subscription_accept_message_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, and stasis_subscription_set_filter().

Referenced by load_module(), and set_config().

◆ network_change_stasis_unsubscribe()

static void network_change_stasis_unsubscribe ( void  )
static

◆ network_thread()

static void * network_thread ( void *  ignore)
static

Definition at line 12743 of file chan_iax2.c.

12744{
12745 int res;
12746
12747 if (timer) {
12749 }
12750
12751 for (;;) {
12752 pthread_testcancel();
12753 /* Wake up once a second just in case SIGURG was sent while
12754 * we weren't in poll(), to make sure we don't hang when trying
12755 * to unload. */
12756 res = ast_io_wait(io, 1000);
12757 /* Timeout(=0), and EINTR is not a thread exit condition. We do
12758 * not want to exit the thread loop on these conditions. */
12759 if (res < 0 && errno != -EINTR) {
12760 ast_log(LOG_ERROR, "IAX2 network thread unexpected exit: %s\n", strerror(errno));
12761 break;
12762 }
12763 }
12764
12765 return NULL;
12766}
static int timing_read(int *id, int fd, short events, void *cbdata)
Definition: chan_iax2.c:9602
#define AST_IO_IN
Definition: io.h:34
int * ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
Adds an IO context.
Definition: io.c:162
#define AST_IO_PRI
Definition: io.h:38
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
Definition: io.c:278
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
Definition: timing.c:161

References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), ast_log, ast_timer_fd(), errno, io, LOG_ERROR, NULL, timer, and timing_read().

Referenced by start_network_thread().

◆ new_iax()

static struct chan_iax2_pvt * new_iax ( struct ast_sockaddr addr,
const char *  host 
)
static

Definition at line 2290 of file chan_iax2.c.

2291{
2292 struct chan_iax2_pvt *tmp;
2293 jb_conf jbconf;
2294
2295 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
2296 return NULL;
2297 }
2298
2299 tmp->pingid = -1;
2300 tmp->lagid = -1;
2301 tmp->autoid = -1;
2302 tmp->authid = -1;
2303 tmp->initid = -1;
2304 tmp->keyrotateid = -1;
2305 tmp->jbid = -1;
2306
2307 if (ast_string_field_init(tmp, 32)) {
2308 ao2_ref(tmp, -1);
2309 tmp = NULL;
2310 return NULL;
2311 }
2312
2313 tmp->prefs = prefs_global;
2314
2317
2318 tmp->jb = jb_new();
2323 jb_setconf(tmp->jb,&jbconf);
2324
2325 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
2326
2327 tmp->hold_signaling = 1;
2328 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
2329
2330 return tmp;
2331}
static int maxjitterbuffer
Definition: chan_iax2.c:335
static int maxjitterinterps
Definition: chan_iax2.c:337
static void pvt_destructor(void *obj)
Definition: chan_iax2.c:2243
static int resyncthreshold
Definition: chan_iax2.c:336
static int jittertargetextra
Definition: chan_iax2.c:338
jitterbuf * jb_new(void)
new jitterbuf
Definition: jitterbuf.c:86
enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf)
set jitterbuf conf
Definition: jitterbuf.c:825
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
long target_extra
Definition: jitterbuf.h:72
long max_jitterbuf
Definition: jitterbuf.h:69
long resync_threshold
Definition: jitterbuf.h:70
long max_contig_interp
Definition: jitterbuf.h:71

References ao2_alloc, ao2_ref, AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_string_field_set, chan_iax2_pvt::exten, chan_iax2_pvt::host, jb_new(), jb_setconf(), jittertargetextra, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, maxjitterbuffer, maxjitterinterps, NULL, prefs_global, pvt_destructor(), jb_conf::resync_threshold, resyncthreshold, jb_conf::target_extra, and tmp().

Referenced by __find_callno().

◆ parse_dial_string()

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

Parses an IAX dial string into its component parts.

Parameters
datathe string to be parsed
pdspointer to a struct parsed_dial_string to be filled in

This function parses the string and fills the structure with pointers to its component parts. The input string will be modified.

Note
This function supports both plaintext passwords and RSA key names; if the password string is formatted as '[keyname]', then the keyname will be placed into the key field, and the password field will be set to NULL.
The dial string format is:
[username[:password]@]peer[:port][/exten[@context]][/options] 

Definition at line 5092 of file chan_iax2.c.

5093{
5094 char *outkey = NULL;
5095
5096 if (ast_strlen_zero(data))
5097 return;
5098
5099 pds->peer = strsep(&data, "/");
5100 pds->exten = strsep(&data, "/");
5101 pds->options = data;
5102
5103 if (pds->exten) {
5104 data = pds->exten;
5105 pds->exten = strsep(&data, "@");
5106 pds->context = data;
5107 }
5108
5109 if (strchr(pds->peer, '@')) {
5110 data = pds->peer;
5111 pds->username = strsep(&data, "@");
5112 pds->peer = data;
5113 }
5114
5115 if (pds->username) {
5116 data = pds->username;
5117 pds->username = strsep(&data, ":");
5118 pds->password = strsep(&data, ":");
5119 outkey = data;
5120 }
5121
5122 data = pds->peer;
5123 pds->peer = strsep(&data, ":");
5124 pds->port = data;
5125
5126 /*
5127 * Check for a key name wrapped in [] in the password position.
5128 * If found, move it to the key field instead.
5129 * Also allow for both key and secret to be specified, now that
5130 * encryption is possible with RSA authentication.
5131 */
5132
5133 if (pds->password && (pds->password[0] == '[')) { /* key (then maybe secret) */
5134 pds->key = ast_strip_quoted(pds->password, "[", "]");
5135 if (ast_strlen_zero(outkey)) {
5136 pds->password = NULL;
5137 ast_debug(1, "Outkey (%s), no secret\n", pds->key);
5138 } else {
5139 pds->password = outkey;
5140 ast_debug(1, "Outkey (%s) and secret (%s)\n", pds->key, pds->password);
5141 }
5142 } else if (outkey && (outkey[0] == '[')) { /* secret, then key */
5143 pds->key = ast_strip_quoted(outkey, "[", "]");
5144 if (ast_strlen_zero(pds->password)) {
5145 ast_debug(1, "Outkey (%s), no secret\n", pds->key);
5146 } else {
5147 ast_debug(1, "Outkey (%s) and secret (%s)\n", pds->key, pds->password);
5148 }
5149 }
5150}
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
Definition: utils.c:1818

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

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

◆ peer_cmp_cb()

static int peer_cmp_cb ( void *  obj,
void *  arg,
int  flags 
)
static
Note
The only member of the peer passed here guaranteed to be set is the name field

Definition at line 2020 of file chan_iax2.c.

2021{
2022 struct iax2_peer *peer = obj, *peer2 = arg;
2023 const char *name = arg;
2024
2025 return !strcmp(peer->name, flags & OBJ_KEY ? name : peer2->name) ?
2026 CMP_MATCH | CMP_STOP : 0;
2027}
uint64_t flags
Definition: chan_iax2.c:607

References CMP_MATCH, CMP_STOP, iax2_peer::flags, name, iax2_peer::name, and OBJ_KEY.

Referenced by load_objects().

◆ peer_delme_cb()

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

Definition at line 13551 of file chan_iax2.c.

13552{
13553 struct iax2_peer *peer = obj;
13554
13556
13557 return 0;
13558}

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

◆ peer_destructor()

static void peer_destructor ( void *  obj)
static

Definition at line 12936 of file chan_iax2.c.

12937{
12938 struct iax2_peer *peer = obj;
12939 int callno = peer->callno;
12940
12941 ast_free_acl_list(peer->acl);
12942
12943 if (callno > 0) {
12947 }
12948
12949 register_peer_exten(peer, 0);
12950
12951 if (peer->dnsmgr)
12953
12954 if (peer->mwi_event_sub) {
12956 }
12957
12959
12961}
void ast_endpoint_shutdown(struct ast_endpoint *endpoint)
Shutsdown an ast_endpoint.
void * ast_mwi_unsubscribe(struct ast_mwi_subscriber *sub)
Unsubscribe from the stasis topic and MWI.
Definition: mwi.c:254

References iax2_peer::acl, ast_dnsmgr_release(), ast_endpoint_shutdown(), ast_free_acl_list(), ast_mutex_lock, ast_mutex_unlock, ast_mwi_unsubscribe(), ast_string_field_free_memory, iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::endpoint, iax2_destroy(), iaxsl, iax2_peer::mwi_event_sub, and register_peer_exten().

Referenced by build_peer().

◆ peer_hash_cb()

static int peer_hash_cb ( const void *  obj,
const int  flags 
)
static
Note
The only member of the peer passed here guaranteed to be set is the name field

Definition at line 2009 of file chan_iax2.c.

2010{
2011 const struct iax2_peer *peer = obj;
2012 const char *name = obj;
2013
2014 return ast_str_hash(flags & OBJ_KEY ? name : peer->name);
2015}
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259

References ast_str_hash(), iax2_peer::flags, name, iax2_peer::name, and OBJ_KEY.

Referenced by load_objects().

◆ peer_ref()

static struct iax2_peer * peer_ref ( struct iax2_peer peer)
static

◆ peer_set_sock_cb()

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

Definition at line 14851 of file chan_iax2.c.

14852{
14853 struct iax2_peer *peer = obj;
14854
14855 if (peer->sockfd < 0)
14856 peer->sockfd = defaultsockfd;
14857
14858 return 0;
14859}

References defaultsockfd, and iax2_peer::sockfd.

Referenced by load_module().

◆ peer_set_srcaddr()

static int peer_set_srcaddr ( struct iax2_peer peer,
const char *  srcaddr 
)
static

Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found.

Definition at line 12866 of file chan_iax2.c.

12867{
12868 struct ast_sockaddr addr;
12869 int nonlocal = 1;
12870 int port = IAX_DEFAULT_PORTNO;
12871 int sockfd = defaultsockfd;
12872 char *tmp;
12873 char *host;
12874 char *portstr;
12875
12876 tmp = ast_strdupa(srcaddr);
12877 ast_sockaddr_split_hostport(tmp, &host, &portstr, 0);
12878
12879 if (portstr) {
12880 port = atoi(portstr);
12881 if (port < 1)
12882 port = IAX_DEFAULT_PORTNO;
12883 }
12884
12885 addr.ss.ss_family = AST_AF_UNSPEC;
12886 if (!ast_get_ip(&addr, host)) {
12887 struct ast_netsock *sock;
12888
12889 if (check_srcaddr(&addr) == 0) {
12890 /* ip address valid. */
12891 ast_sockaddr_set_port(&addr, port);
12892
12893 if (!(sock = ast_netsock_find(netsock, &addr)))
12894 sock = ast_netsock_find(outsock, &addr);
12895 if (sock) {
12896 sockfd = ast_netsock_sockfd(sock);
12897 nonlocal = 0;
12898 } else {
12899 /* INADDR_ANY matches anyway! */
12900 ast_sockaddr_parse(&addr, "0.0.0.0", 0);
12901 ast_sockaddr_set_port(&addr, port);
12902 if (ast_netsock_find(netsock, &addr)) {
12903 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12904 if (sock) {
12905 sockfd = ast_netsock_sockfd(sock);
12906 ast_netsock_unref(sock);
12907 nonlocal = 0;
12908 } else {
12909 nonlocal = 2;
12910 }
12911 }
12912 }
12913 }
12914 }
12915
12916 peer->sockfd = sockfd;
12917
12918 if (nonlocal == 1) {
12920 "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12921 srcaddr,
12922 peer->name);
12923 return -1;
12924 } else if (nonlocal == 2) {
12926 "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12927 srcaddr,
12928 peer->name);
12929 return -1;
12930 } else {
12931 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12932 return 0;
12933 }
12934}
static struct @116 qos
static int check_srcaddr(struct ast_sockaddr *addr)
Check if address can be used as packet source.
Definition: chan_iax2.c:12843
static int socket_read(int *id, int fd, short events, void *cbdata)
Definition: chan_iax2.c:9915
int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags)
Splits a string into its host and port components.
Definition: netsock2.c:164
struct ast_netsock * ast_netsock_bind(struct ast_netsock_list *list, struct io_context *ioc, const char *bindinfo, int defaultport, int tos, int cos, ast_io_cb callback, void *data)
Definition: netsock.c:167
void ast_netsock_unref(struct ast_netsock *ns)
Definition: netsock.c:198
int ast_netsock_sockfd(const struct ast_netsock *ns)
Definition: netsock.c:183
struct ast_netsock * ast_netsock_find(struct ast_netsock_list *list, struct ast_sockaddr *addr)
Definition: netsock.c:94
int sockfd
Definition: netsock.c:54

References AST_AF_UNSPEC, ast_debug, ast_get_ip(), ast_log, ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_sockaddr_parse(), ast_sockaddr_set_port, ast_sockaddr_split_hostport(), ast_strdupa, check_srcaddr(), defaultsockfd, IAX_DEFAULT_PORTNO, io, LOG_WARNING, iax2_peer::name, netsock, NULL, outsock, qos, socket_read(), iax2_peer::sockfd, ast_netsock::sockfd, ast_sockaddr::ss, and tmp().

Referenced by build_peer().

◆ peer_status()

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

peer_status: Report Peer status in character string

Definition at line 3839 of file chan_iax2.c.

3840{
3841 int res = 0;
3842 if (peer->maxms) {
3843 if (peer->lastms < 0) {
3844 ast_copy_string(status, "UNREACHABLE", statuslen);
3845 } else if (peer->lastms > peer->maxms) {
3846 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
3847 res = 1;
3848 } else if (peer->lastms) {
3849 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
3850 res = 1;
3851 } else {
3852 ast_copy_string(status, "UNKNOWN", statuslen);
3853 }
3854 } else {
3855 ast_copy_string(status, "Unmonitored", statuslen);
3856 res = -1;
3857 }
3858 return res;
3859}

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

Referenced by _iax2_show_peers_one(), function_iaxpeer(), and handle_cli_iax2_show_peer().

◆ peer_unref()

static struct iax2_peer * peer_unref ( struct iax2_peer peer)
inlinestatic

◆ peercnt_add()

static int peercnt_add ( struct ast_sockaddr addr)
static

Definition at line 2678 of file chan_iax2.c.

2679{
2680 struct peercnt *peercnt;
2681 int res = 0;
2682 struct peercnt tmp;
2683
2684 ast_sockaddr_copy(&tmp.addr, addr);
2685
2686 /* Reasoning for peercnts container lock: Two identical ip addresses
2687 * could be added by different threads at the "same time". Without the container
2688 * lock, both threads could alloc space for the same object and attempt
2689 * to link to table. With the lock, one would create the object and link
2690 * to table while the other would find the already created peercnt object
2691 * rather than creating a new one. */
2693 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
2695 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
2697 /* create and set defaults */
2700 /* guarantees it does not go away after unlocking table
2701 * ao2_find automatically adds this */
2703 } else {
2705 return -1;
2706 }
2707
2708 /* check to see if the address has hit its callno limit. If not increment cur. */
2709 if (peercnt->limit > peercnt->cur) {
2710 peercnt->cur++;
2711 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_sockaddr_stringify_addr(addr));
2712 } else { /* max num call numbers for this peer has been reached! */
2713 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_sockaddr_stringify_addr(addr));
2714 res = -1;
2715 }
2716
2717 /* clean up locks and ref count */
2720 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */
2721
2722 return res;
2723}
static void set_peercnt_limit(struct peercnt *peercnt)
Definition: chan_iax2.c:2600

References peercnt::addr, ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_debug, ast_log, ast_sockaddr_copy(), ast_sockaddr_stringify_addr(), peercnt::cur, peercnt::limit, LOG_ERROR, NULL, OBJ_POINTER, peercnts, set_peercnt_limit(), and tmp().

Referenced by __find_callno(), and complete_transfer().

◆ peercnt_cmp_cb()

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

Definition at line 2516 of file chan_iax2.c.

2517{
2518 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
2519 return !ast_sockaddr_cmp_addr(&peercnt1->addr, &peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
2520}

References peercnt::addr, ast_sockaddr_cmp_addr(), CMP_MATCH, and CMP_STOP.

Referenced by load_objects().

◆ peercnt_hash_cb()

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

Definition at line 2506 of file chan_iax2.c.

2507{
2508 const struct peercnt *peercnt = obj;
2509
2511 return 0;
2512 }
2513 return ast_sockaddr_hash(&peercnt->addr);
2514}

References peercnt::addr, ast_sockaddr_hash(), and ast_sockaddr_isnull().

Referenced by load_objects().

◆ peercnt_modify()

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

Definition at line 2650 of file chan_iax2.c.

2651{
2652 /* this function turns off and on custom callno limits set by peer registration */
2653 struct peercnt *peercnt;
2654 struct peercnt tmp;
2655
2656 ast_sockaddr_copy(&tmp.addr, sockaddr);
2657
2658 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
2659 peercnt->reg = reg;
2660 if (limit) {
2661 peercnt->limit = limit;
2662 } else {
2664 }
2665 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_sockaddr_stringify_addr(sockaddr), peercnt->limit, peercnt->reg);
2666 ao2_ref(peercnt, -1); /* decrement ref from find */
2667 }
2668}
unsigned char reg
Definition: chan_iax2.c:1036

References ao2_find, ao2_ref, ast_debug, ast_sockaddr_copy(), ast_sockaddr_stringify_addr(), peercnt::limit, OBJ_POINTER, peercnts, peercnt::reg, set_peercnt_limit(), and tmp().

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

◆ peercnt_remove()

static void peercnt_remove ( struct peercnt peercnt)
static

Definition at line 2729 of file chan_iax2.c.

2730{
2731 struct ast_sockaddr addr;
2732
2733 ast_sockaddr_copy(&addr, &peercnt->addr);
2734
2735 /*
2736 * Container locked here since peercnt may be unlinked from
2737 * list. If left unlocked, peercnt_add could try and grab this
2738 * entry from the table and modify it at the "same time" this
2739 * thread attempts to unlink it.
2740 */
2742 peercnt->cur--;
2743 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_sockaddr_stringify_addr(&addr));
2744 /* if this was the last connection from the peer remove it from table */
2745 if (peercnt->cur == 0) {
2746 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */
2747 }
2749}

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

Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().

◆ peercnt_remove_by_addr()

static int peercnt_remove_by_addr ( struct ast_sockaddr addr)
static

Definition at line 2769 of file chan_iax2.c.

2770{
2771 struct peercnt *peercnt;
2772 struct peercnt tmp;
2773
2774 ast_sockaddr_copy(&tmp.addr, addr);
2775
2776 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
2778 ao2_ref(peercnt, -1); /* decrement ref from find */
2779 }
2780 return 0;
2781}
static void peercnt_remove(struct peercnt *peercnt)
Definition: chan_iax2.c:2729

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

Referenced by __find_callno(), and complete_transfer().

◆ peercnt_remove_cb()

static int peercnt_remove_cb ( const void *  obj)
static

Definition at line 2755 of file chan_iax2.c.

2756{
2757 struct peercnt *peercnt = (struct peercnt *) obj;
2758
2760 ao2_ref(peercnt, -1); /* decrement ref from scheduler */
2761
2762 return 0;
2763}

References ao2_ref, and peercnt_remove().

Referenced by __unload_module(), and sched_delay_remove().

◆ poke_all_peers()

static void poke_all_peers ( void  )
static

Definition at line 14168 of file chan_iax2.c.

14169{
14170 struct ao2_iterator i;
14171 struct iax2_peer *peer;
14172
14173 i = ao2_iterator_init(peers, 0);
14174 while ((peer = ao2_iterator_next(&i))) {
14175 iax2_poke_peer(peer, 0);
14176 peer_unref(peer);
14177 }
14179}

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

Referenced by reload_config().

◆ prune_addr_range_cb()

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

Definition at line 2639 of file chan_iax2.c.

2640{
2641 struct addr_range *addr_range = obj;
2642
2643 return addr_range->delme ? CMP_MATCH : 0;
2644}

References CMP_MATCH, and addr_range::delme.

Referenced by reload_config().

◆ prune_peers()

static void prune_peers ( void  )
static

Definition at line 13614 of file chan_iax2.c.

13615{
13616 struct iax2_peer *peer;
13617 struct ao2_iterator i;
13618
13619 i = ao2_iterator_init(peers, 0);
13620 while ((peer = ao2_iterator_next(&i))) {
13622 unlink_peer(peer);
13623 }
13624 peer_unref(peer);
13625 }
13627}

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

Referenced by handle_cli_iax2_prune_realtime(), and reload_config().

◆ prune_users()

static void prune_users ( void  )
static

Definition at line 13598 of file chan_iax2.c.

13599{
13600 struct iax2_user *user;
13601 struct ao2_iterator i;
13602
13603 i = ao2_iterator_init(users, 0);
13604 while ((user = ao2_iterator_next(&i))) {
13607 }
13609 }
13611}

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

Referenced by handle_cli_iax2_prune_realtime(), and reload_config().

◆ pvt_cmp_cb()

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

Definition at line 14868 of file chan_iax2.c.

14869{
14870 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14871
14872 /* The frames_received field is used to hold whether we're matching
14873 * against a full frame or not ... */
14874
14875 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14876 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14877}

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

Referenced by load_objects().

◆ pvt_destructor()

static void pvt_destructor ( void *  obj)
static

Definition at line 2243 of file chan_iax2.c.

2244{
2245 struct chan_iax2_pvt *pvt = obj;
2246 struct iax_frame *cur = NULL;
2247 struct signaling_queue_entry *s = NULL;
2248
2249 ast_mutex_lock(&iaxsl[pvt->callno]);
2250
2252
2254 pvt->callno_entry = 0;
2255
2256 /* Already gone */
2258
2259 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) {
2260 /* Cancel any pending transmissions */
2261 cur->retries = -1;
2262 }
2263
2265
2266 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
2268 }
2269
2270 if (pvt->reg) {
2271 pvt->reg->callno = 0;
2272 }
2273
2274 if (!pvt->owner) {
2275 jb_frame frame;
2276 if (pvt->vars) {
2278 pvt->vars = NULL;
2279 }
2280
2281 while (jb_getall(pvt->jb, &frame) == JB_OK) {
2282 iax2_frame_free(frame.data);
2283 }
2284
2285 jb_destroy(pvt->jb);
2287 }
2288}
static void free_signaling_queue_entry(struct signaling_queue_entry *s)
Definition: chan_iax2.c:2195
static void sched_delay_remove(struct ast_sockaddr *addr, callno_entry entry)
Definition: chan_iax2.c:3101
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
void jb_destroy(jitterbuf *jb)
destroy jitterbuf
Definition: jitterbuf.c:99
struct chan_iax2_pvt::signaling_queue signaling_queue
Definition: chan_iax2.c:940
struct signaling_queue_entry * next
Definition: chan_iax2.c:942

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

Referenced by new_iax().

◆ pvt_hash_cb()

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

Definition at line 14861 of file chan_iax2.c.

14862{
14863 const struct chan_iax2_pvt *pvt = obj;
14864
14865 return pvt->peercallno;
14866}

References chan_iax2_pvt::peercallno.

Referenced by load_objects().

◆ queue_signalling()

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

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

Definition at line 2218 of file chan_iax2.c.

2219{
2220 struct signaling_queue_entry *qe;
2221
2222 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
2223 return 1; /* do not queue this frame */
2224 } else if (!(qe = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
2225 return -1; /* out of memory */
2226 }
2227
2228 /* copy ast_frame into our queue entry */
2229 qe->f = *f;
2230 if (qe->f.datalen) {
2231 /* if there is data in this frame copy it over as well */
2232 if (!(qe->f.data.ptr = ast_malloc(qe->f.datalen))) {
2234 return -1;
2235 }
2236 memcpy(qe->f.data.ptr, f->data.ptr, qe->f.datalen);
2237 }
2239
2240 return 0;
2241}
char hold_signaling
Definition: chan_iax2.c:935

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

Referenced by __send_command().

◆ raw_hangup()

static int raw_hangup ( struct ast_sockaddr addr,
unsigned short  src,
unsigned short  dst,
int  sockfd 
)
static

Definition at line 8120 of file chan_iax2.c.

8121{
8122 struct ast_iax2_full_hdr fh;
8123 fh.scallno = htons(src | IAX_FLAG_FULL);
8124 fh.dcallno = htons(dst);
8125 fh.ts = 0;
8126 fh.oseqno = 0;
8127 fh.iseqno = 0;
8128 fh.type = AST_FRAME_IAX;
8130 iax_outputframe(NULL, &fh, 0, addr, 0);
8131
8132 ast_debug(1, "Raw Hangup %s, src=%d, dst=%d\n", ast_sockaddr_stringify(addr), src, dst);
8133 return ast_sendto(sockfd, &fh, sizeof(fh), 0, addr);
8134}
@ IAX_COMMAND_INVAL
Definition: iax2.h:61
ssize_t ast_sendto(int sockfd, const void *buf, size_t len, int flags, const struct ast_sockaddr *dest_addr)
Wrapper around sendto(2) that uses ast_sockaddr.
Definition: netsock2.c:614

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

Referenced by socket_process_helper().

◆ realtime_peer()

static struct iax2_peer * realtime_peer ( const char *  peername,
struct ast_sockaddr addr 
)
static
Note
This function calls reg_source_db -> iax2_poke_peer -> find_callno, so do not call this with a pvt lock held.
Note
If this one loaded something, then we need to ensure that the host field matched. The only reason why we can't have this as a criteria is because we only have the IP address and the host field might be set as a name (and the reverse PTR might not match).

Definition at line 4417 of file chan_iax2.c.

4418{
4419 struct ast_variable *var = NULL;
4420 struct ast_variable *tmp;
4421 struct iax2_peer *peer=NULL;
4422 time_t regseconds = 0, nowtime;
4423 int dynamic=0;
4424 char *str_addr, *str_port;
4425
4428
4429 if (peername) {
4430 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
4431 if (!var && !ast_sockaddr_isnull(addr)) {
4432 var = ast_load_realtime("iaxpeers", "name", peername, "host", str_addr, SENTINEL);
4433 }
4434 } else if (!ast_sockaddr_isnull(addr)) {
4435 var = ast_load_realtime("iaxpeers", "ipaddr", str_addr, "port", str_port, SENTINEL);
4436 if (var) {
4437 /* We'll need the peer name in order to build the structure! */
4438 for (tmp = var; tmp; tmp = tmp->next) {
4439 if (!strcasecmp(tmp->name, "name"))
4440 peername = tmp->value;
4441 }
4442 }
4443 }
4444 if (!var && peername) { /* Last ditch effort */
4445 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
4446 /*!\note
4447 * If this one loaded something, then we need to ensure that the host
4448 * field matched. The only reason why we can't have this as a criteria
4449 * is because we only have the IP address and the host field might be
4450 * set as a name (and the reverse PTR might not match).
4451 */
4452 if (var && !ast_sockaddr_isnull(addr)) {
4453 for (tmp = var; tmp; tmp = tmp->next) {
4454 if (!strcasecmp(tmp->name, "host")) {
4455 struct ast_sockaddr *hostaddr = NULL;
4456
4458 || ast_sockaddr_cmp_addr(hostaddr, addr)) {
4459 /* No match */
4461 var = NULL;
4462 }
4463 ast_free(hostaddr);
4464 break;
4465 }
4466 }
4467 }
4468 }
4469 if (!var)
4470 return NULL;
4471
4472 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
4473
4474 if (!peer) {
4476 return NULL;
4477 }
4478
4479 for (tmp = var; tmp; tmp = tmp->next) {
4480 /* Make sure it's not a user only... */
4481 if (!strcasecmp(tmp->name, "type")) {
4482 if (strcasecmp(tmp->value, "friend") &&
4483 strcasecmp(tmp->value, "peer")) {
4484 /* Whoops, we weren't supposed to exist! */
4485 peer = peer_unref(peer);
4486 break;
4487 }
4488 } else if (!strcasecmp(tmp->name, "regseconds")) {
4489 ast_get_time_t(tmp->value, &regseconds, 0, NULL);
4490 } else if (!strcasecmp(tmp->name, "ipaddr")) {
4491 int setport = ast_sockaddr_port(&peer->addr);
4493 ast_log(LOG_WARNING, "Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->value, tmp->name);
4494 } else {
4495 ast_sockaddr_parse(&peer->addr, tmp->value, 0);
4496 }
4497 ast_sockaddr_set_port(&peer->addr, setport);
4498 } else if (!strcasecmp(tmp->name, "port")) {
4499 int bindport;
4500 if (ast_parse_arg(tmp->value, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535)) {
4501 bindport = IAX_DEFAULT_PORTNO;
4502 }
4503 ast_sockaddr_set_port(&peer->addr, bindport);
4504 } else if (!strcasecmp(tmp->name, "host")) {
4505 if (!strcasecmp(tmp->value, "dynamic"))
4506 dynamic = 1;
4507 }
4508 }
4509
4511
4514 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
4515 if (peer->expire > -1) {
4516 if (!AST_SCHED_DEL(sched, peer->expire)) {
4517 peer->expire = -1;
4518 peer_unref(peer);
4519 }
4520 }
4522 if (peer->expire == -1)
4523 peer_unref(peer);
4524 }
4525 ao2_link(peers, peer);
4526 if (ast_test_flag64(peer, IAX_DYNAMIC))
4527 reg_source_db(peer);
4528 } else {
4530 }
4531
4533 time(&nowtime);
4534 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
4535 memset(&peer->addr, 0, sizeof(peer->addr));
4536 realtime_update_peer(peer->name, &peer->addr, 0);
4537 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
4538 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
4539 }
4540 else {
4541 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
4542 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
4543 }
4544 }
4545
4546 return peer;
4547}
static struct iax2_peer * build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
Create peer structure based on configuration.
Definition: chan_iax2.c:12964
static void reg_source_db(struct iax2_peer *p)
Definition: chan_iax2.c:9090
static int global_rtautoclear
Definition: chan_iax2.c:529
#define IAX_RTIGNOREREGEXPIRE
Definition: chan_iax2.c:518
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Definition: main/config.c:3506
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.
Definition: netsock2.c:280
int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
Parse a time (integer) string.
Definition: utils.c:2446

References iax2_peer::addr, ao2_link, AST_AF_UNSPEC, ast_copy_flags64, ast_debug, ast_free, ast_get_time_t(), ast_load_realtime(), ast_log, ast_parse_arg(), AST_SCHED_DEL, ast_set_flag64, ast_sockaddr_cmp_addr(), ast_sockaddr_isnull(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_resolve(), ast_sockaddr_set_port, ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strdupa, ast_test_flag64, ast_variables_destroy(), build_peer(), iax2_peer::expire, expire_registry(), global_rtautoclear, globalflags, iax2_sched_add(), IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, LOG_WARNING, iax2_peer::name, NULL, PARSE_ADDR, PARSE_IN_RANGE, PARSE_PORT_FORBID, PARSE_UINT32, peer_ref(), peer_unref(), realtime_update_peer(), reg_source_db(), SENTINEL, tmp(), and var.

Referenced by authenticate_reply(), calltoken_required(), find_peer(), and iax2_getpeername().

◆ realtime_update_peer()

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

Definition at line 4624 of file chan_iax2.c.

4625{
4626 char regseconds[20];
4627 const char *sysname = ast_config_AST_SYSTEM_NAME;
4628 char *syslabel = NULL;
4629 char *port;
4630
4631 if (ast_strlen_zero(sysname)) /* No system name, disable this */
4632 sysname = NULL;
4634 syslabel = "regserver";
4635
4636 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
4637 port = ast_strdupa(ast_sockaddr_stringify_port(sockaddr));
4638 ast_update_realtime("iaxpeers", "name", peername,
4639 "ipaddr", ast_sockaddr_isnull(sockaddr) ? "" : ast_sockaddr_stringify_addr(sockaddr),
4640 "port", ast_sockaddr_isnull(sockaddr) ? "" : port,
4641 "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslabel can be NULL */
4642}
#define IAX_RTSAVE_SYSNAME
Definition: chan_iax2.c:506
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
Definition: main/config.c:3659
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170

References ast_config_AST_SYSTEM_NAME, ast_sockaddr_isnull(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strdupa, ast_strlen_zero(), ast_test_flag64, ast_update_realtime(), globalflags, IAX_RTSAVE_SYSNAME, NULL, and SENTINEL.

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

◆ realtime_user()

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

Definition at line 4549 of file chan_iax2.c.

4550{
4551 struct ast_variable *var;
4552 struct ast_variable *tmp;
4553 struct iax2_user *user=NULL;
4554 char *str_addr, *str_port;
4555
4556 str_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
4557 str_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
4558
4559 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
4560 if (!var)
4561 var = ast_load_realtime("iaxusers", "name", username, "host", str_addr, SENTINEL);
4562 if (!var && !ast_sockaddr_isnull(addr)) {
4563 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", str_addr, "port", str_port, SENTINEL);
4564 if (!var)
4565 var = ast_load_realtime("iaxusers", "ipaddr", str_addr, "port", str_port, SENTINEL);
4566 }
4567 if (!var) { /* Last ditch effort */
4568 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
4569 /*!\note
4570 * If this one loaded something, then we need to ensure that the host
4571 * field matched. The only reason why we can't have this as a criteria
4572 * is because we only have the IP address and the host field might be
4573 * set as a name (and the reverse PTR might not match).
4574 */
4575 if (var) {
4576 for (tmp = var; tmp; tmp = tmp->next) {
4577 if (!strcasecmp(tmp->name, "host")) {
4578 struct ast_sockaddr *hostaddr = NULL;
4579
4581 || ast_sockaddr_cmp_addr(hostaddr, addr)) {
4582 /* No match */
4584 var = NULL;
4585 }
4586 ast_free(hostaddr);
4587 break;
4588 }
4589 }
4590 }
4591 }
4592 if (!var)
4593 return NULL;
4594
4595 tmp = var;
4596 while(tmp) {
4597 /* Make sure it's not a peer only... */
4598 if (!strcasecmp(tmp->name, "type")) {
4599 if (strcasecmp(tmp->value, "friend") &&
4600 strcasecmp(tmp->value, "user")) {
4601 return NULL;
4602 }
4603 }
4604 tmp = tmp->next;
4605 }
4606
4608
4610
4611 if (!user)
4612 return NULL;
4613
4617 } else {
4619 }
4620
4621 return user;
4622}
static struct iax2_user * build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
Create in-memory user structure from configuration.
Definition: chan_iax2.c:13289

References ao2_link, AST_AF_UNSPEC, ast_free, ast_load_realtime(), ast_set_flag64, ast_sockaddr_cmp_addr(), ast_sockaddr_isnull(), ast_sockaddr_resolve(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strdupa, ast_test_flag64, ast_variables_destroy(), build_user(), globalflags, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, NULL, PARSE_PORT_FORBID, SENTINEL, tmp(), user, and var.

Referenced by calltoken_required(), and check_access().

◆ reg_source_db()

static void reg_source_db ( struct iax2_peer p)
static

Definition at line 9090 of file chan_iax2.c.

9091{
9092 char data[80];
9093 char *expiry;
9094
9095 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
9096 return;
9097 }
9098
9099 expiry = strrchr(data, ':');
9100 if (!expiry) {
9101 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
9102 return;
9103 }
9104 *expiry++ = '\0';
9105
9106 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
9107 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
9108 return;
9109 }
9110
9111 p->expiry = atoi(expiry);
9112
9113 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
9115
9116 iax2_poke_peer(p, 0);
9117 if (p->expire > -1) {
9118 if (!AST_SCHED_DEL(sched, p->expire)) {
9119 p->expire = -1;
9120 peer_unref(p);
9121 }
9122 }
9123
9124 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
9125
9126 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
9127 if (p->expire == -1) {
9128 peer_unref(p);
9129 }
9130
9131 if (iax2_regfunk) {
9132 iax2_regfunk(p->name, 1);
9133 }
9134
9135 register_peer_exten(p, 1);
9136}
@ PARSE_PORT_REQUIRE

References iax2_peer::addr, ast_db_get(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log, AST_SCHED_DEL, ast_sockaddr_parse(), ast_sockaddr_stringify(), ast_test_flag64, ast_verb, iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, LOG_NOTICE, iax2_peer::name, PARSE_PORT_REQUIRE, peer_ref(), peer_unref(), and register_peer_exten().

Referenced by realtime_peer(), and set_config().

◆ register_peer_exten()

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

Definition at line 9002 of file chan_iax2.c.

9003{
9004 char multi[256];
9005 char *stringp, *ext;
9007 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
9008 stringp = multi;
9009 while((ext = strsep(&stringp, "&"))) {
9010 if (onoff) {
9013 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
9014 } else
9016 }
9017 }
9018}
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1739
const char * ext
Definition: http.c:150
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
Definition: pbx.c:6928
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition: pbx.c:4948
const ast_string_field regexten
Definition: chan_iax2.c:599

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

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

◆ register_verify()

static int register_verify ( int  callno,
struct ast_sockaddr addr,
struct iax_ies ies 
)
static

Verify inbound registration.

Definition at line 8303 of file chan_iax2.c.

8304{
8305 char requeststr[256] = "";
8306 char peer[256] = "";
8307 char md5secret[256] = "";
8308 char rsasecret[256] = "";
8309 char secret[256] = "";
8310 struct iax2_peer *p = NULL;
8311 struct ast_key *key;
8312 char *keyn;
8313 int x;
8314 int expire = 0;
8315 int res = -1;
8316
8318 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
8319 if (ies->username)
8320 ast_copy_string(peer, ies->username, sizeof(peer));
8321 if (ies->password)
8322 ast_copy_string(secret, ies->password, sizeof(secret));
8323 if (ies->md5_result)
8324 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
8325 if (ies->rsa_result)
8326 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
8327 if (ies->refresh)
8328 expire = ies->refresh;
8329
8330 if (ast_strlen_zero(peer)) {
8331 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_sockaddr_stringify_addr(addr));
8332 return -1;
8333 }
8334
8335 /* SLD: first call to lookup peer during registration */
8336 ast_mutex_unlock(&iaxsl[callno]);
8337 p = find_peer(peer, 1);
8338 ast_mutex_lock(&iaxsl[callno]);
8339 if (!p || !iaxs[callno]) {
8340 if (iaxs[callno]) {
8341 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
8342 /* Anything, as long as it's non-blank */
8343 ast_string_field_set(iaxs[callno], secret, "badsecret");
8344 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
8345 * 1. A challenge already exists indicating a AUTHREQ was already sent out.
8346 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
8347 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
8348 * to be plaintext, indicating it is an authmethod used by other peers on the system.
8349 *
8350 * If none of these cases exist, res will be returned as 0 without authentication indicating
8351 * an AUTHREQ needs to be sent out. */
8352
8353 if (ast_strlen_zero(iaxs[callno]->challenge) &&
8354 !(!ast_strlen_zero(secret) && plaintext)) {
8355 /* by setting res to 0, an REGAUTH will be sent */
8356 res = 0;
8357 }
8358 }
8359 if (authdebug && !p)
8360 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_sockaddr_stringify_addr(addr));
8361 goto return_unref;
8362 }
8363
8364 if (!ast_test_flag64(p, IAX_DYNAMIC)) {
8365 if (authdebug)
8366 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_sockaddr_stringify_addr(addr));
8367 goto return_unref;
8368 }
8369
8370 if (!ast_apply_acl(p->acl, addr, "IAX2 Peer ACL: ")) {
8371 if (authdebug)
8372 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_sockaddr_stringify_addr(addr), p->name);
8373 goto return_unref;
8374 }
8375 ast_string_field_set(iaxs[callno], secret, p->secret);
8376 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
8377 /* Check secret against what we have on file */
8378 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
8379 if (!ast_strlen_zero(p->inkeys)) {
8380 char *tmpkey;
8381 char *stringp=NULL;
8382 if (!(tmpkey = ast_strdup(p->inkeys))) {
8383 ast_log(LOG_ERROR, "Unable to create a temporary string for parsing stored 'inkeys'\n");
8384 goto return_unref;
8385 }
8386 stringp = tmpkey;
8387 keyn = strsep(&stringp, ":");
8388 while(keyn) {
8389 key = ast_key_get(keyn, AST_KEY_PUBLIC);
8390 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
8392 break;
8393 } else if (!key)
8394 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
8395 keyn = strsep(&stringp, ":");
8396 }
8397 ast_free(tmpkey);
8398 if (!keyn) {
8399 if (authdebug)
8400 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
8401 goto return_unref;
8402 }
8403 } else {
8404 if (authdebug)
8405 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
8406 goto return_unref;
8407 }
8408 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
8409 struct MD5Context md5;
8410 unsigned char digest[16];
8411 char *tmppw, *stringp;
8412
8413 tmppw = ast_strdupa(p->secret);
8414 stringp = tmppw;
8415 while((tmppw = strsep(&stringp, ";"))) {
8416 MD5Init(&md5);
8417 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
8418 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
8419 MD5Final(digest, &md5);
8420 for (x=0;x<16;x++)
8421 sprintf(requeststr + (x << 1), "%02hhx", digest[x]); /* safe */
8422 if (!strcasecmp(requeststr, md5secret))
8423 break;
8424 }
8425 if (tmppw) {
8427 } else {
8428 if (authdebug)
8429 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_sockaddr_stringify_addr(addr), p->name, requeststr, md5secret);
8430 goto return_unref;
8431 }
8432 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
8433 /* They've provided a plain text password and we support that */
8434 if (strcmp(secret, p->secret)) {
8435 if (authdebug)
8436 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_sockaddr_stringify_addr(addr), p->name);
8437 goto return_unref;
8438 } else
8440 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
8441 /* if challenge has been sent, but no challenge response if given, reject. */
8442 goto return_unref;
8443 }
8444 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
8445
8446 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
8447 res = 0;
8448
8449return_unref:
8450 if (iaxs[callno]) {
8451 ast_string_field_set(iaxs[callno], peer, peer);
8452
8453 /* Choose lowest expiry number */
8454 if (expire && (expire < iaxs[callno]->expiry)) {
8455 iaxs[callno]->expiry = expire;
8456 }
8457 }
8458
8459 if (p) {
8460 peer_unref(p);
8461 }
8462 return res;
8463}
const ast_string_field inkeys
Definition: chan_iax2.c:599

References iax2_peer::acl, ast_apply_acl(), ast_check_signature(), ast_clear_flag, ast_copy_string(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_free, ast_key_get(), AST_KEY_PUBLIC, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_sockaddr_stringify_addr(), ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, authdebug, iax2_peer::authmethods, challenge(), chan_iax2_pvt::expiry, find_peer(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, iaxs, iaxsl, iax2_peer::inkeys, last_authmethod, LOG_ERROR, LOG_NOTICE, LOG_WARNING, md5(), iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, NULL, iax_ies::password, peer_unref(), iax_ies::refresh, iax_ies::rsa_result, iax2_peer::secret, strsep(), and iax_ies::username.

Referenced by socket_process_helper().

◆ registry_authrequest()

static int registry_authrequest ( int  callno)
static

Definition at line 9322 of file chan_iax2.c.

9323{
9324 struct iax_ie_data ied;
9325 struct iax2_peer *p;
9326 char challenge[10];
9327 const char *peer_name;
9328 int sentauthmethod;
9329
9330 peer_name = ast_strdupa(iaxs[callno]->peer);
9331
9332 /* SLD: third call to find_peer in registration */
9334 if ((p = find_peer(peer_name, 1))) {
9336 }
9337
9339 if (!iaxs[callno])
9340 goto return_unref;
9341
9342 memset(&ied, 0, sizeof(ied));
9343 /* The selection of which delayed reject is sent may leak information,
9344 * if it sets a static response. For example, if a host is known to only
9345 * use MD5 authentication, then an RSA response would indicate that the
9346 * peer does not exist, and vice-versa.
9347 * Therefore, we use whatever the last peer used (which may vary over the
9348 * course of a server, which should leak minimal information). */
9349 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : IAX_AUTH_MD5;
9350 if (!p) {
9351 iaxs[callno]->authmethods = sentauthmethod;
9352 }
9353 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
9354 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
9355 /* Build the challenge */
9356 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
9359 }
9360 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
9361
9362return_unref:
9363 if (p) {
9364 peer_unref(p);
9365 }
9366
9367 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
9368}
@ IAX_COMMAND_REGAUTH
Definition: iax2.h:67

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

Referenced by socket_process_helper().

◆ registry_rerequest()

static int registry_rerequest ( struct iax_ies ies,
int  callno,
struct ast_sockaddr addr 
)
static

Definition at line 9370 of file chan_iax2.c.

9371{
9372 struct iax2_registry *reg;
9373 /* Start pessimistic */
9374 struct iax_ie_data ied;
9375 char peer[256] = "";
9376 char challenge[256] = "";
9377 int res;
9378 int authmethods = 0;
9379 if (ies->authmethods)
9380 authmethods = ies->authmethods;
9381 if (ies->username)
9382 ast_copy_string(peer, ies->username, sizeof(peer));
9383 if (ies->challenge)
9385 memset(&ied, 0, sizeof(ied));
9386 reg = iaxs[callno]->reg;
9387 if (reg) {
9388
9389 if (ast_sockaddr_cmp(&reg->addr, addr)) {
9390 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_sockaddr_stringify(addr));
9391 return -1;
9392 }
9393 if (ast_strlen_zero(reg->secret)) {
9394 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
9396 return -1;
9397 }
9400 if (reg->secret[0] == '[') {
9401 char tmpkey[256];
9402 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
9403 tmpkey[strlen(tmpkey) - 1] = '\0';
9404 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, addr, NULL);
9405 } else
9406 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, addr, NULL);
9407 if (!res) {
9409 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
9410 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
9411 } else
9412 return -1;
9413 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
9414 } else
9415 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
9416 return -1;
9417}

References add_empty_calltoken_ie(), iax2_registry::addr, ast_copy_string(), AST_FRAME_IAX, ast_log, ast_sockaddr_cmp(), ast_sockaddr_stringify(), ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax_ie_data::buf, iax_ies::challenge, challenge(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, LOG_NOTICE, LOG_WARNING, NULL, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, REG_STATE_NOAUTH, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.

Referenced by socket_process_helper().

◆ regstate2str()

static char * regstate2str ( int  regstate)
static

Definition at line 7406 of file chan_iax2.c.

7407{
7408 switch(regstate) {
7410 return "Unregistered";
7411 case REG_STATE_REGSENT:
7412 return "Request Sent";
7413 case REG_STATE_AUTHSENT:
7414 return "Auth. Sent";
7416 return "Registered";
7417 case REG_STATE_REJECTED:
7418 return "Rejected";
7419 case REG_STATE_TIMEOUT:
7420 return "Timeout";
7421 case REG_STATE_NOAUTH:
7422 return "No Authentication";
7423 default:
7424 return "Unknown";
7425 }
7426}

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

Referenced by handle_cli_iax2_show_registry(), and manager_iax2_show_registry().

◆ reload()

static int reload ( void  )
static

Definition at line 14229 of file chan_iax2.c.

14230{
14231 return reload_config(0);
14232}

References reload_config().

Referenced by set_config().

◆ reload_config()

static int reload_config ( int  forced_reload)
static

Definition at line 14180 of file chan_iax2.c.

14181{
14182 static const char config[] = "iax.conf";
14183 struct iax2_registry *reg;
14184
14185 if (set_config(config, 1, forced_reload) > 0) {
14186 prune_peers();
14187 prune_users();
14193 memset(&debugaddr, '\0', sizeof(debugaddr));
14194
14197 iax2_do_register(reg);
14199
14200 /* Qualify hosts, too */
14202 }
14203
14206 ast_unload_realtime("iaxpeers");
14207
14208 return 0;
14209}
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
@ OBJ_UNLINK
Definition: astobj2.h:1039
static int prune_addr_range_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:2639
static void poke_all_peers(void)
Definition: chan_iax2.c:14168
static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:2625

References ao2_callback, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_unload_realtime(), callno_limits, calltoken_ignores, config, debugaddr, iax2_do_register(), iax_firmware_reload(), iax_provision_reload(), NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, peercnts, poke_all_peers(), prune_addr_range_cb(), prune_peers(), prune_users(), set_config(), set_peercnt_limit_all_cb(), trunk_maxmtu, trunk_nmaxmtu, trunk_timed, and trunk_untimed.

Referenced by acl_change_stasis_cb(), handle_cli_iax2_reload(), and reload().

◆ remove_by_peercallno()

static void remove_by_peercallno ( struct chan_iax2_pvt pvt)
static

Definition at line 2475 of file chan_iax2.c.

2476{
2477 if (!pvt->peercallno) {
2478 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
2479 return;
2480 }
2481
2483}

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

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

◆ remove_by_transfercallno()

static void remove_by_transfercallno ( struct chan_iax2_pvt pvt)
static

Definition at line 2456 of file chan_iax2.c.

2457{
2458 if (!pvt->transfercallno) {
2459 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
2460 return;
2461 }
2462
2464}

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

Referenced by complete_transfer(), and iax2_destroy().

◆ replace_callno()

static int replace_callno ( const void *  obj)
static

Definition at line 3029 of file chan_iax2.c.

3030{
3032 struct call_number_pool *pool;
3033
3034 /* We lock here primarily to ensure thread safety of the
3035 * total_nonval_callno_used check and decrement */
3037
3041 } else {
3043 "Attempted to decrement total non calltoken validated "
3044 "callnumbers below zero. Callno is: %d\n",
3046 }
3047 }
3048
3050 pool = &callno_pool;
3051 } else {
3052 pool = &callno_pool_trunk;
3053 }
3054
3055 ast_assert(pool->capacity > pool->available);
3056
3057 /* This clears the validated flag */
3059
3060 pool->numbers[pool->available] = entry;
3061 pool->available++;
3062
3064
3065 return 0;
3066}
#define PTR_TO_CALLNO_ENTRY(a)
Definition: chan_iax2.c:950

References ast_assert, ast_log, ast_mutex_lock, ast_mutex_unlock, call_number_pool::available, CALLNO_ENTRY_GET_CALLNO, CALLNO_ENTRY_IS_VALIDATED, callno_pool, callno_pool_lock, callno_pool_trunk, call_number_pool::capacity, LOG_ERROR, call_number_pool::numbers, PTR_TO_CALLNO_ENTRY, total_nonval_callno_used, and TRUNK_CALL_START.

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

◆ requirecalltoken_mark_auto()

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

Definition at line 4950 of file chan_iax2.c.

4951{
4952 struct iax2_user *user = NULL;
4953 struct iax2_peer *peer = NULL;
4954
4955 if (ast_strlen_zero(name)) {
4956 return; /* no username given */
4957 }
4958
4959 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
4960 user->calltoken_required = CALLTOKEN_YES;
4961 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
4963 }
4964
4965 if (peer) {
4966 peer_unref(peer);
4967 }
4968 if (user) {
4970 }
4971}

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

Referenced by handle_call_token().

◆ resend_with_token()

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

Definition at line 4868 of file chan_iax2.c.

4869{
4870 struct chan_iax2_pvt *pvt = iaxs[callno];
4871 int frametype = f->af.frametype;
4872 int subclass = f->af.subclass.integer;
4873 struct {
4874 struct ast_iax2_full_hdr fh;
4875 struct iax_ie_data ied;
4876 } data = {
4877 .ied.buf = { 0 },
4878 .ied.pos = 0,
4879 };
4880 /* total len - header len gives us the frame's IE len */
4881 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
4882
4883 if (!pvt) {
4884 return; /* this should not be possible if called from socket_process() */
4885 }
4886
4887 /*
4888 * Check to make sure last frame sent is valid for call token resend
4889 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog
4890 * 2. Frame should _NOT_ already have a destination callno
4891 * 3. Frame must be a valid iax_frame subclass capable of starting dialog
4892 * 4. Pvt must have a calltoken_ie_len which represents the number of
4893 * bytes at the end of the frame used for the previous calltoken ie.
4894 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length
4895 * 6. Total length of f->data must be _LESS_ than size of our data struct
4896 * because f->data must be able to fit within data.
4897 */
4898 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
4899 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
4900 (f->datalen > sizeof(data))) {
4901
4902 return; /* ignore resend, token was not valid for the dialog */
4903 }
4904
4905 /* token is valid
4906 * 1. Copy frame data over
4907 * 2. Redo calltoken IE, it will always be the last ie in the frame.
4908 * NOTE: Having the ie always be last is not protocol specified,
4909 * it is only an implementation choice. Since we only expect the ie to
4910 * be last for frames we have sent, this can no way be affected by
4911 * another end point.
4912 * 3. Remove frame from queue
4913 * 4. Free old frame
4914 * 5. Clear previous seqnos
4915 * 6. Resend with CALLTOKEN ie.
4916 */
4917
4918 /* ---1.--- */
4919 memcpy(&data, f->data, f->datalen);
4920 data.ied.pos = ie_data_pos;
4921
4922 /* ---2.--- */
4923 /* move to the beginning of the calltoken ie so we can write over it */
4924 data.ied.pos -= pvt->calltoken_ie_len;
4925 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
4926
4927 /* make sure to update token length incase it ever has to be stripped off again */
4928 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */
4929
4930 /* ---3.--- */
4931 AST_LIST_REMOVE(&frame_queue[callno], f, list);
4932
4933 /* ---4.--- */
4934 iax2_frame_free(f);
4935
4936 /* ---5.--- */
4937 pvt->oseqno = 0;
4938 pvt->rseqno = 0;
4939 pvt->iseqno = 0;
4940 pvt->aseqno = 0;
4941 if (pvt->peercallno) {
4943 pvt->peercallno = 0;
4944 }
4945
4946 /* ---6.--- */
4947 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
4948}
static int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
Definition: chan_iax2.c:3132

References iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_LIST_REMOVE, iax_ie_data::buf, chan_iax2_pvt::callno, chan_iax2_pvt::calltoken_ie_len, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, iax_frame::encmethods, frame_queue, ast_frame::frametype, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, iaxs, ast_frame_subclass::integer, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, remove_by_peercallno(), chan_iax2_pvt::rseqno, send_command(), and ast_frame::subclass.

Referenced by socket_process_helper().

◆ save_osptoken()

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

Definition at line 9781 of file chan_iax2.c.

9782{
9783 int i;
9784 unsigned int length, offset = 0;
9785 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
9786
9787 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
9788 length = ies->ospblocklength[i];
9789 if (length != 0) {
9790 if (length > IAX_MAX_OSPBLOCK_SIZE) {
9791 /* OSP token block length wrong, clear buffer */
9792 offset = 0;
9793 break;
9794 } else {
9795 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
9796 offset += length;
9797 }
9798 } else {
9799 break;
9800 }
9801 }
9802 *(full_osptoken + offset) = '\0';
9803 if (strlen(full_osptoken) != offset) {
9804 /* OSP token length wrong, clear buffer */
9805 *full_osptoken = '\0';
9806 }
9807
9808 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
9809}
#define IAX_MAX_OSPBUFF_SIZE
Definition: iax2.h:195
#define IAX_MAX_OSPBLOCK_NUM
Definition: iax2.h:193
unsigned int ospblocklength[IAX_MAX_OSPBLOCK_NUM]
Definition: parser.h:83
char * osptokenblock[IAX_MAX_OSPBLOCK_NUM]
Definition: parser.h:82

References ast_string_field_set, iax_frame::callno, IAX_MAX_OSPBLOCK_NUM, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPBUFF_SIZE, iaxs, iax_ies::ospblocklength, and iax_ies::osptokenblock.

Referenced by socket_process_helper().

◆ save_rr()

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

Definition at line 9770 of file chan_iax2.c.

9771{
9772 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
9773 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
9774 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
9775 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
9776 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
9777 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
9778 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
9779}
unsigned int rr_jitter
Definition: parser.h:75
unsigned int rr_pkts
Definition: parser.h:77
unsigned int rr_loss
Definition: parser.h:76
unsigned int rr_dropped
Definition: parser.h:79
unsigned int rr_ooo
Definition: parser.h:80
unsigned short rr_delay
Definition: parser.h:78
int jitter
Definition: chan_iax2.c:727

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

Referenced by socket_process_helper().

◆ sched_delay_remove()

static void sched_delay_remove ( struct ast_sockaddr addr,
callno_entry  entry 
)
static

Definition at line 3101 of file chan_iax2.c.

3102{
3103 int i;
3104 struct peercnt *peercnt;
3105 struct peercnt tmp;
3106
3107 ast_sockaddr_copy(&tmp.addr, addr);
3108
3109 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
3110 /* refcount is incremented with ao2_find. keep that ref for the scheduler */
3111 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_sockaddr_stringify_addr(addr), MIN_REUSE_TIME);
3113 if (i == -1) {
3114 ao2_ref(peercnt, -1);
3115 }
3116 }
3117
3119 sched,
3120 MIN_REUSE_TIME * 1000,
3123}

References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_sockaddr_copy(), ast_sockaddr_stringify_addr(), CALLNO_ENTRY_TO_PTR, iax2_sched_add(), MIN_REUSE_TIME, OBJ_POINTER, peercnt_remove_cb(), peercnts, replace_callno(), and tmp().

Referenced by pvt_destructor().

◆ schedule_delivery()

static int schedule_delivery ( struct iax_frame fr,
int  updatehistory,
int  fromtrunk,
unsigned int *  tsout 
)
static
Note
This function assumes fr->callno is locked
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it.

Definition at line 4276 of file chan_iax2.c.

4277{
4278 int type, len;
4279 int ret;
4280 int needfree = 0;
4281
4282 /*
4283 * Clear fr->af.data if there is no data in the buffer. Things
4284 * like AST_CONTROL_HOLD without a suggested music class must
4285 * have a NULL pointer.
4286 */
4287 if (!fr->af.datalen) {
4288 memset(&fr->af.data, 0, sizeof(fr->af.data));
4289 }
4290
4291 /* Attempt to recover wrapped timestamps */
4292 unwrap_timestamp(fr);
4293
4294 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
4295 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
4296 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
4297 else {
4298#if 0
4299 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
4300#endif
4301 fr->af.delivery = ast_tv(0,0);
4302 }
4303
4305 len = 0;
4306
4307 if(fr->af.frametype == AST_FRAME_VOICE) {
4310 } else if(fr->af.frametype == AST_FRAME_CNG) {
4312 }
4313
4314 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
4315 if (tsout)
4316 *tsout = fr->ts;
4317 __do_deliver(fr);
4318 return -1;
4319 }
4320
4321 /* insert into jitterbuffer */
4322 /* TODO: Perhaps we could act immediately if it's not droppable and late */
4323 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
4324 calc_rxstamp(iaxs[fr->callno],fr->ts));
4325 if (ret == JB_DROP) {
4326 needfree++;
4327 } else if (ret == JB_SCHED) {
4329 }
4330 if (tsout)
4331 *tsout = fr->ts;
4332 if (needfree) {
4333 /* Free our iax frame */
4334 iax2_frame_free(fr);
4335 return -1;
4336 }
4337 return 0;
4338}
static void unwrap_timestamp(struct iax_frame *fr)
Definition: chan_iax2.c:4120
static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
Definition: chan_iax2.c:6284
unsigned int ast_codec_samples_count(struct ast_frame *frame)
Get the number of samples contained within a frame.
Definition: codec.c:379
enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now)
queue a frame
Definition: jitterbuf.c:525
@ JB_TYPE_CONTROL
Definition: jitterbuf.h:61
@ JB_TYPE_SILENCE
Definition: jitterbuf.h:64
@ JB_TYPE_VOICE
Definition: jitterbuf.h:62
@ JB_SCHED
Definition: jitterbuf.h:56
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:235

References __do_deliver(), iax_frame::af, ast_codec_samples_count(), ast_debug, ast_format_get_sample_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_samp2tv(), ast_test_flag64, ast_tv(), ast_tvadd(), ast_tvzero(), calc_rxstamp(), iax_frame::callno, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame_subclass::format, ast_frame::frametype, iax2_frame_free(), IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::jb, JB_DROP, jb_put(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, len(), chan_iax2_pvt::rxcore, ast_frame::subclass, iax_frame::ts, type, unwrap_timestamp(), and update_jbsched().

Referenced by socket_process_helper(), and socket_process_meta().

◆ scheduled_destroy()

static int scheduled_destroy ( const void *  vid)
static

Definition at line 2183 of file chan_iax2.c.

2184{
2185 unsigned short callno = PTR_TO_CALLNO(vid);
2186 ast_mutex_lock(&iaxsl[callno]);
2187 if (iaxs[callno]) {
2188 ast_debug(1, "Really destroying %d now...\n", callno);
2189 iax2_destroy(callno);
2190 }
2191 ast_mutex_unlock(&iaxsl[callno]);
2192 return 0;
2193}

References ast_debug, ast_mutex_lock, ast_mutex_unlock, iax2_destroy(), iaxs, iaxsl, and PTR_TO_CALLNO.

Referenced by iax2_hangup().

◆ send_apathetic_reply()

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

Definition at line 4830 of file chan_iax2.c.

4833{
4834 struct {
4835 struct ast_iax2_full_hdr f;
4836 struct iax_ie_data ied;
4837 } data;
4838 size_t size = sizeof(struct ast_iax2_full_hdr);
4839
4840 if (ied) {
4841 size += ied->pos;
4842 memcpy(&data.ied, ied->buf, ied->pos);
4843 }
4844
4845 data.f.scallno = htons(0x8000 | callno);
4846 data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS);
4847 data.f.ts = htonl(ts);
4848 data.f.iseqno = seqno;
4849 data.f.oseqno = 0;
4850 data.f.type = AST_FRAME_IAX;
4851 data.f.csub = compress_subclass(command);
4852
4853 iax_outputframe(NULL, &data.f, 0, addr, size - sizeof(struct ast_iax2_full_hdr));
4854
4855 return ast_sendto(sockfd, &data, size, 0, addr);
4856}
#define IAX_FLAG_RETRANS
Definition: iax2.h:42

References AST_FRAME_IAX, ast_sendto(), iax_ie_data::buf, compress_subclass(), ast_iax2_full_hdr::dcallno, IAX_FLAG_RETRANS, iax_outputframe(), NULL, iax_ie_data::pos, and ast_iax2_full_hdr::ts.

Referenced by handle_call_token(), and socket_process_helper().

◆ send_command()

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

Definition at line 7831 of file chan_iax2.c.

7832{
7834 /* Control frame should not go out on the wire. */
7835 ast_debug(2, "Callno %d: Blocked sending control frame %d.\n",
7836 i->callno, command);
7837 return 0;
7838 }
7839 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
7840}
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)
Definition: chan_iax2.c:7812
static int iax2_is_control_frame_allowed(int subtype)
Definition: chan_iax2.c:1405

References __send_command(), ast_debug, AST_FRAME_CONTROL, chan_iax2_pvt::callno, ast_frame::data, ast_frame::datalen, iax2_is_control_frame_allowed(), ast_frame::seqno, ast_frame::ts, and type.

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

◆ send_command_final()

static int send_command_final ( struct chan_iax2_pvt i,
char  type,
int  command,
unsigned int  ts,
const unsigned char *  data,
int  datalen,
int  seqno 
)
static
Note
Since this function calls iax2_predestroy() -> iax2_queue_hangup(), the pvt struct for the given call number may disappear during its execution.

Definition at line 7856 of file chan_iax2.c.

7857{
7858 int call_num = i->callno;
7859 /* It is assumed that the callno has already been locked */
7861 if (!iaxs[call_num])
7862 return -1;
7863 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
7864}

References __send_command(), chan_iax2_pvt::callno, ast_frame::data, ast_frame::datalen, iax2_predestroy(), iaxs, ast_frame::seqno, ast_frame::ts, and type.

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

◆ send_command_immediate()

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

Definition at line 7866 of file chan_iax2.c.

7867{
7868 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
7869}

References __send_command(), ast_frame::data, ast_frame::datalen, ast_frame::seqno, ast_frame::ts, and type.

Referenced by iax2_vnak(), and socket_process_helper().

◆ send_command_locked()

static int send_command_locked ( unsigned short  callno,
char  type,
int  command,
unsigned int  ts,
const unsigned char *  data,
int  datalen,
int  seqno 
)
static

Definition at line 7842 of file chan_iax2.c.

7843{
7844 int res;
7845 ast_mutex_lock(&iaxsl[callno]);
7846 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
7847 ast_mutex_unlock(&iaxsl[callno]);
7848 return res;
7849}

References ast_mutex_lock, ast_mutex_unlock, ast_frame::data, ast_frame::datalen, iaxs, iaxsl, send_command(), ast_frame::seqno, ast_frame::ts, and type.

Referenced by iax2_answer(), iax2_digit_begin(), iax2_digit_end(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), and iax2_transfer().

◆ send_command_transfer()

static int send_command_transfer ( struct chan_iax2_pvt i,
char  type,
int  command,
unsigned int  ts,
const unsigned char *  data,
int  datalen 
)
static

Definition at line 7871 of file chan_iax2.c.

7872{
7873 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
7874}

References __send_command(), ast_frame::data, ast_frame::datalen, ast_frame::ts, and type.

Referenced by socket_process_helper(), and try_transfer().

◆ send_lagrq()

static int send_lagrq ( const void *  data)
static

Definition at line 1851 of file chan_iax2.c.

1852{
1853#ifdef SCHED_MULTITHREADED
1854 if (schedule_action(__send_lagrq, data))
1855#endif
1856 __send_lagrq(data);
1857 return 0;
1858}
static void __send_lagrq(const void *data)
Definition: chan_iax2.c:1827

References __send_lagrq(), and schedule_action.

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

◆ send_packet()

static int send_packet ( struct iax_frame f)
static

Definition at line 3449 of file chan_iax2.c.

3450{
3451 int res;
3452 int callno = f->callno;
3453
3454 /* Don't send if there was an error, but return error instead */
3455 if (!callno || !iaxs[callno] || iaxs[callno]->error)
3456 return -1;
3457
3458 /* Called with iaxsl held */
3459 if (iaxdebug) {
3460 ast_debug(8, "Sending %u on %d/%d to %s\n", f->ts, callno, iaxs[callno]->peercallno, ast_sockaddr_stringify(&iaxs[callno]->addr));
3461 }
3462 if (f->transfer) {
3463 iax_outputframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
3464 res = ast_sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0, &iaxs[callno]->transfer);
3465 } else {
3466 iax_outputframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
3467 res = ast_sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0, &iaxs[callno]->addr);
3468 }
3469 if (res < 0) {
3470 if (iaxdebug)
3471 ast_debug(1, "Received error: %s\n", strerror(errno));
3472 handle_error();
3473 } else
3474 res = 0;
3475
3476 return res;
3477}
static int handle_error(void)
Definition: chan_iax2.c:3402

References chan_iax2_pvt::addr, ast_debug, ast_sendto(), ast_sockaddr_stringify(), iax_frame::callno, iax_frame::data, iax_frame::datalen, errno, error(), handle_error(), iax_outputframe(), iaxdebug, iaxs, NULL, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, transfer(), iax_frame::transfer, and iax_frame::ts.

Referenced by __attempt_transmit(), iax2_send(), transmit_frame(), and vnak_retransmit().

◆ send_ping()

static int send_ping ( const void *  data)
static

Definition at line 1787 of file chan_iax2.c.

1788{
1789#ifdef SCHED_MULTITHREADED
1790 if (schedule_action(__send_ping, data))
1791#endif
1792 __send_ping(data);
1793
1794 return 0;
1795}
static void __send_ping(const void *data)
Definition: chan_iax2.c:1763

References __send_ping(), and schedule_action.

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

◆ send_signaling()

static void send_signaling ( struct chan_iax2_pvt pvt)
static

This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.

Definition at line 2205 of file chan_iax2.c.

2206{
2207 struct signaling_queue_entry *s = NULL;
2208
2209 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
2210 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
2212 }
2213 pvt->hold_signaling = 0;
2214}

References AST_LIST_REMOVE_HEAD, signaling_queue_entry::f, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_send(), signaling_queue_entry::next, NULL, and chan_iax2_pvt::signaling_queue.

Referenced by socket_process_helper().

◆ send_trunk()

static int send_trunk ( struct iax2_trunk_peer tpeer,
struct timeval *  now 
)
static

Definition at line 9551 of file chan_iax2.c.

9552{
9553 int res = 0;
9554 struct iax_frame *fr;
9555 struct ast_iax2_meta_hdr *meta;
9556 struct ast_iax2_meta_trunk_hdr *mth;
9557 int calls = 0;
9558
9559 /* Point to frame */
9560 fr = (struct iax_frame *)tpeer->trunkdata;
9561 /* Point to meta data */
9562 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
9563 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
9564 if (tpeer->trunkdatalen) {
9565 /* We're actually sending a frame, so fill the meta trunk header and meta header */
9566 meta->zeros = 0;
9567 meta->metacmd = IAX_META_TRUNK;
9569 meta->cmddata = IAX_META_TRUNK_MINI;
9570 else
9571 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
9572 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
9573 /* And the rest of the ast_iax2 header */
9575 fr->retrans = -1;
9576 fr->transfer = 0;
9577 /* Any appropriate call will do */
9578 fr->data = fr->afdata;
9579 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
9580 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
9581 calls = tpeer->calls;
9582#if 0
9583 ast_debug(1, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts));
9584#endif
9585 /* Reset transmit trunk side data */
9586 tpeer->trunkdatalen = 0;
9587 tpeer->calls = 0;
9588 }
9589 if (res < 0)
9590 return res;
9591 return calls;
9592}
static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
Definition: chan_iax2.c:6105
static int transmit_trunk(struct iax_frame *f, struct ast_sockaddr *addr, int sockfd)
Definition: chan_iax2.c:3436
#define IAX_META_TRUNK_SUPERMINI
Definition: iax2.h:207
#define IAX_META_TRUNK
Definition: iax2.h:204
#define IAX_META_TRUNK_MINI
Definition: iax2.h:208
meta
below block is needed for mssql
Definition: cdr/env.py:22
unsigned int ts
Definition: iax2.h:278
unsigned char afdata[0]
Definition: parser.h:146
unsigned int direction
Definition: parser.h:122

References iax2_trunk_peer::addr, iax_frame::afdata, ast_debug, ast_inet_ntoa(), ast_test_flag64, calc_txpeerstamp(), iax2_trunk_peer::calls, iax_frame::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, if(), env::meta, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, trunkfreq, and ast_iax2_meta_trunk_hdr::ts.

Referenced by iax2_trunk_queue(), and timing_read().

◆ set_config()

static int set_config ( const char *  config_file,
int  reload,
int  forced 
)
static

Load configuration.

Definition at line 13646 of file chan_iax2.c.

13647{
13648 struct ast_config *cfg, *ucfg;
13649 iax2_format capability;
13650 struct ast_variable *v;
13651 char *cat;
13652 const char *utype;
13653 const char *tosval;
13654 int format;
13655 int portno = IAX_DEFAULT_PORTNO;
13656 int x;
13657 int mtuv;
13658 int subscribe_network_change = 1;
13659 struct iax2_user *user;
13660 struct iax2_peer *peer;
13661 struct ast_netsock *ns;
13662 struct ast_flags config_flags = { (reload && !forced) ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13663 struct ast_sockaddr bindaddr;
13664 struct iax2_codec_pref prefs_new;
13665
13666 cfg = ast_config_load(config_file, config_flags);
13667
13668 if (!cfg) {
13669 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13670 return -1;
13671 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13672 ucfg = ast_config_load("users.conf", config_flags);
13673 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13674 return 0;
13675 /* Otherwise we need to reread both files */
13677 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13678 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13679 ast_config_destroy(ucfg);
13680 return 0;
13681 }
13682 if (!cfg) {
13683 /* should have been able to load the config here */
13684 ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file);
13685 return -1;
13686 }
13687 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13688 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13689 return 0;
13690 } else { /* iax.conf changed, gotta reread users.conf, too */
13692 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13693 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
13694 ast_config_destroy(cfg);
13695 return 0;
13696 }
13697 }
13698
13699 if (reload) {
13701 }
13702
13703 ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0);
13704
13705 /* Setup new codec prefs */
13707
13708 /* Reset Global Flags */
13709 memset(&globalflags, 0, sizeof(globalflags));
13712
13713#ifdef SO_NO_CHECK
13714 nochecksums = 0;
13715#endif
13716 /* Reset default parking lot */
13717 default_parkinglot[0] = '\0';
13718
13724
13725 maxauthreq = 3;
13726
13727 srvlookup = 0;
13728 iax2_authmethods = 0;
13729
13730 v = ast_variable_browse(cfg, "general");
13731
13732 /* Seed initial tos value */
13733 tosval = ast_variable_retrieve(cfg, "general", "tos");
13734 if (tosval) {
13735 if (ast_str2tos(tosval, &qos.tos))
13736 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13737 }
13738 /* Seed initial cos value */
13739 tosval = ast_variable_retrieve(cfg, "general", "cos");
13740 if (tosval) {
13741 if (ast_str2cos(tosval, &qos.cos))
13742 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13743 }
13744 while(v) {
13745 if (!strcasecmp(v->name, "bindport")) {
13746 if (reload) {
13747 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13748 }
13749 else if (ast_parse_arg(v->value, PARSE_UINT32 | PARSE_IN_RANGE, &portno, 1024, 65535)) {
13750 portno = IAX_DEFAULT_PORTNO;
13751 }
13752 } else if (!strcasecmp(v->name, "pingtime")){
13753 ping_time = atoi(v->value);
13754 }
13755 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13756 if (reload) {
13757 if (atoi(v->value) != iaxthreadcount)
13758 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13759 } else {
13760 iaxthreadcount = atoi(v->value);
13761 if (iaxthreadcount < 1) {
13762 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13763 iaxthreadcount = 1;
13764 } else if (iaxthreadcount > 256) {
13765 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13766 iaxthreadcount = 256;
13767 }
13768 }
13769 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13770 if (reload) {
13772 iaxmaxthreadcount = atoi(v->value);
13774 } else {
13775 iaxmaxthreadcount = atoi(v->value);
13776 if (iaxmaxthreadcount < 0) {
13777 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13779 } else if (iaxmaxthreadcount > 256) {
13780 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13781 iaxmaxthreadcount = 256;
13782 }
13783 }
13784 } else if (!strcasecmp(v->name, "nochecksums")) {
13785#ifdef SO_NO_CHECK
13786 if (ast_true(v->value))
13787 nochecksums = 1;
13788 else
13789 nochecksums = 0;
13790#else
13791 if (ast_true(v->value))
13792 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13793#endif
13794 }
13795 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13796 maxjitterbuffer = atoi(v->value);
13797 else if (!strcasecmp(v->name, "resyncthreshold"))
13798 resyncthreshold = atoi(v->value);
13799 else if (!strcasecmp(v->name, "maxjitterinterps"))
13800 maxjitterinterps = atoi(v->value);
13801 else if (!strcasecmp(v->name, "jittertargetextra"))
13802 jittertargetextra = atoi(v->value);
13803 else if (!strcasecmp(v->name, "lagrqtime"))
13804 lagrq_time = atoi(v->value);
13805 else if (!strcasecmp(v->name, "maxregexpire"))
13806 max_reg_expire = atoi(v->value);
13807 else if (!strcasecmp(v->name, "minregexpire"))
13808 min_reg_expire = atoi(v->value);
13809 else if (!strcasecmp(v->name, "bindaddr")) {
13810 if (reload) {
13811 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13812 } else {
13813
13814 if (!ast_parse_arg(v->value, PARSE_ADDR, NULL)) {
13815
13817
13818 if (!ast_sockaddr_port(&bindaddr)) {
13820 }
13821
13822 if (!(ns = ast_netsock_bindaddr(netsock, io, &bindaddr, qos.tos, qos.cos, socket_read, NULL))) {
13823 ast_log(LOG_WARNING, "Unable to apply binding to '%s' at line %d\n", v->value, v->lineno);
13824 } else {
13825 ast_verb(2, "Binding IAX2 to address %s\n", ast_sockaddr_stringify(&bindaddr));
13826
13827 if (defaultsockfd < 0) {
13829 }
13831 }
13832
13833 } else {
13834 ast_log(LOG_WARNING, "Invalid address '%s' specified, at line %d\n", v->value, v->lineno);
13835 }
13836 }
13837 } else if (!strcasecmp(v->name, "auth")) {
13840 ast_log(LOG_WARNING, "Default auth method is set to deprecated 'plaintext' at line %d of iax.conf\n", v->lineno);
13841 }
13842 } else if (!strcasecmp(v->name, "authdebug")) {
13843 authdebug = ast_true(v->value);
13844 } else if (!strcasecmp(v->name, "encryption")) {
13846 if (!iax2_encryption) {
13848 }
13849 } else if (!strcasecmp(v->name, "forceencryption")) {
13850 if (ast_false(v->value)) {
13852 } else {
13854 if (iax2_encryption) {
13856 }
13857 }
13858 } else if (!strcasecmp(v->name, "transfer")) {
13859 if (!strcasecmp(v->value, "mediaonly")) {
13861 } else if (ast_true(v->value)) {
13863 } else
13865 } else if (!strcasecmp(v->name, "codecpriority")) {
13866 if(!strcasecmp(v->value, "caller"))
13868 else if(!strcasecmp(v->value, "disabled"))
13870 else if(!strcasecmp(v->value, "reqonly")) {
13873 }
13874 } else if (!strcasecmp(v->name, "jitterbuffer"))
13876 else if (!strcasecmp(v->name, "delayreject"))
13878 else if (!strcasecmp(v->name, "allowfwdownload"))
13880 else if (!strcasecmp(v->name, "rtcachefriends"))
13882 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13884 else if (!strcasecmp(v->name, "rtupdate"))
13886 else if (!strcasecmp(v->name, "rtsavesysname"))
13888 else if (!strcasecmp(v->name, "trunktimestamps"))
13890 else if (!strcasecmp(v->name, "rtautoclear")) {
13891 int i = atoi(v->value);
13892 if(i > 0)
13894 else
13895 i = 0;
13897 } else if (!strcasecmp(v->name, "trunkfreq")) {
13898 trunkfreq = atoi(v->value);
13899 if (trunkfreq < 10) {
13900 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n");
13901 trunkfreq = 10;
13902 } else if (trunkfreq > 1000) {
13903 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n");
13904 trunkfreq = 1000;
13905 }
13906 if (timer) {
13908 }
13909 } else if (!strcasecmp(v->name, "trunkmtu")) {
13910 mtuv = atoi(v->value);
13911 if (mtuv == 0 )
13913 else if (mtuv >= 172 && mtuv < 4000)
13914 global_max_trunk_mtu = mtuv;
13915 else
13916 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13917 mtuv, v->lineno);
13918 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13919 trunkmaxsize = atoi(v->value);
13920 if (trunkmaxsize == 0)
13922 } else if (!strcasecmp(v->name, "autokill")) {
13923 if (sscanf(v->value, "%30d", &x) == 1) {
13924 if (x >= 0)
13925 autokill = x;
13926 else
13927 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13928 } else if (ast_true(v->value)) {
13930 } else {
13931 autokill = 0;
13932 }
13933 } else if (!strcasecmp(v->name, "bandwidth")) {
13934 if (!strcasecmp(v->value, "low")) {
13935 capability = iax2_codec_pref_from_bitfield(&prefs_new,
13937 } else if (!strcasecmp(v->value, "medium")) {
13938 capability = iax2_codec_pref_from_bitfield(&prefs_new,
13940 } else if (!strcasecmp(v->value, "high")) {
13941 capability = iax2_codec_pref_from_bitfield(&prefs_new,
13943 } else {
13944 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13945 }
13946 } else if (!strcasecmp(v->name, "allow")) {
13947 iax2_parse_allow_disallow(&prefs_new, &capability, v->value, 1);
13948 } else if (!strcasecmp(v->name, "disallow")) {
13949 iax2_parse_allow_disallow(&prefs_new, &capability, v->value, 0);
13950 } else if (!strcasecmp(v->name, "register")) {
13951 iax2_register(v->value, v->lineno);
13952 } else if (!strcasecmp(v->name, "iaxcompat")) {
13953 iaxcompat = ast_true(v->value);
13954 } else if (!strcasecmp(v->name, "regcontext")) {
13956 /* Create context if it doesn't exist already */
13958 } else if (!strcasecmp(v->name, "tos")) {
13959 if (ast_str2tos(v->value, &qos.tos))
13960 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13961 } else if (!strcasecmp(v->name, "cos")) {
13962 if (ast_str2cos(v->value, &qos.cos))
13963 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13964 } else if (!strcasecmp(v->name, "parkinglot")) {
13966 } else if (!strcasecmp(v->name, "accountcode")) {
13968 } else if (!strcasecmp(v->name, "mohinterpret")) {
13970 } else if (!strcasecmp(v->name, "mohsuggest")) {
13972 } else if (!strcasecmp(v->name, "amaflags")) {
13973 format = ast_channel_string2amaflag(v->value);
13974 if (format < 0) {
13975 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13976 } else {
13977 amaflags = format;
13978 }
13979 } else if (!strcasecmp(v->name, "language")) {
13980 ast_copy_string(language, v->value, sizeof(language));
13981 } else if (!strcasecmp(v->name, "maxauthreq")) {
13982 maxauthreq = atoi(v->value);
13983 if (maxauthreq < 0)
13984 maxauthreq = 0;
13985 } else if (!strcasecmp(v->name, "adsi")) {
13986 adsi = ast_true(v->value);
13987 } else if (!strcasecmp(v->name, "srvlookup")) {
13988 srvlookup = ast_true(v->value);
13989 } else if (!strcasecmp(v->name, "connectedline")) {
13990 if (ast_true(v->value)) {
13992 } else if (!strcasecmp(v->value, "send")) {
13995 } else if (!strcasecmp(v->value, "receive")) {
13998 } else {
14000 }
14001 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
14002 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
14003 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
14004 }
14005 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
14006 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
14007 ast_log(LOG_WARNING, "maxcallnumbers_nonvalidated must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
14008 }
14009 } else if (!strcasecmp(v->name, "calltokenoptional")) {
14010 if (add_calltoken_ignore(v->value)) {
14011 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
14012 return -1;
14013 }
14014 } else if (!strcasecmp(v->name, "calltokenexpiration")) {
14015 int temp = -1;
14016 sscanf(v->value, "%u", &temp);
14017 if( temp <= 0 ){
14018 ast_log(LOG_WARNING, "Invalid calltokenexpiration value %s. Should be integer greater than 0.\n", v->value);
14019 } else {
14020 max_calltoken_delay = temp;
14021 }
14022 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
14023 if (ast_true(v->value)) {
14024 subscribe_network_change = 1;
14025 } else if (ast_false(v->value)) {
14026 subscribe_network_change = 0;
14027 } else {
14028 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
14029 }
14030 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
14031 if (ast_true(v->value)) {
14033 } else if (ast_false(v->value)) {
14035 } else {
14036 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
14037 }
14038 }/*else if (strcasecmp(v->name,"type")) */
14039 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
14040 v = v->next;
14041 }
14042
14043 if (subscribe_network_change) {
14045 } else {
14047 }
14048
14049 if (defaultsockfd < 0) {
14050
14052
14053 if (!(ns = ast_netsock_bindaddr(netsock, io, &bindaddr, qos.tos, qos.cos, socket_read, NULL))) {
14054 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
14055 } else {
14056 ast_verb(2, "Binding IAX2 to default address %s\n", ast_sockaddr_stringify(&bindaddr));
14059 }
14060 }
14061 if (reload) {
14064 if (!outsock) {
14065 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14066 return -1;
14067 }
14069 }
14070
14072 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
14075 }
14076 prefs_global = prefs_new;
14077 iax2_capability = capability;
14078
14079 if (ucfg) {
14080 struct ast_variable *gen;
14081 int genhasiax;
14082 int genregisteriax;
14083 const char *hasiax, *registeriax;
14084
14085 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
14086 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
14087 gen = ast_variable_browse(ucfg, "general");
14088 cat = ast_category_browse(ucfg, NULL);
14089 while (cat) {
14090 if (strcasecmp(cat, "general")) {
14091 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
14092 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
14093 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
14094 /* Start with general parameters, then specific parameters, user and peer */
14095 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
14096 if (user) {
14098 user = user_unref(user);
14099 }
14100 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
14101 if (peer) {
14102 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
14103 reg_source_db(peer);
14104 }
14105 ao2_link(peers, peer);
14106 peer = peer_unref(peer);
14107 }
14108 }
14109 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
14110 char tmp[256];
14111 const char *host = ast_variable_retrieve(ucfg, cat, "host");
14112 const char *username = ast_variable_retrieve(ucfg, cat, "username");
14113 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
14114 if (!host)
14115 host = ast_variable_retrieve(ucfg, "general", "host");
14116 if (!username)
14117 username = ast_variable_retrieve(ucfg, "general", "username");
14118 if (!secret)
14119 secret = ast_variable_retrieve(ucfg, "general", "secret");
14120 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
14121 if (!ast_strlen_zero(secret))
14122 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
14123 else
14124 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
14125 iax2_register(tmp, 0);
14126 }
14127 }
14128 }
14129 cat = ast_category_browse(ucfg, cat);
14130 }
14131 ast_config_destroy(ucfg);
14132 }
14133
14134 cat = ast_category_browse(cfg, NULL);
14135 while(cat) {
14136 if (strcasecmp(cat, "general")) {
14137 utype = ast_variable_retrieve(cfg, cat, "type");
14138 if (!strcasecmp(cat, "callnumberlimits")) {
14140 } else if (utype) {
14141 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
14142 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
14143 if (user) {
14145 user = user_unref(user);
14146 }
14147 }
14148 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
14149 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
14150 if (peer) {
14151 if (ast_test_flag64(peer, IAX_DYNAMIC))
14152 reg_source_db(peer);
14153 ao2_link(peers, peer);
14154 peer = peer_unref(peer);
14155 }
14156 } else if (strcasecmp(utype, "user")) {
14157 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
14158 }
14159 } else
14160 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
14161 }
14162 cat = ast_category_browse(cfg, cat);
14163 }
14164 ast_config_destroy(cfg);
14165 return 1;
14166}
int ast_str2tos(const char *value, unsigned int *tos)
Convert a string to the appropriate TOS value.
Definition: acl.c:966
int ast_str2cos(const char *value, unsigned int *cos)
Convert a string to the appropriate COS value.
Definition: acl.c:952
static struct ast_generator gen
static const char config_file[]
Definition: cdr_odbc.c:54
static int iaxcompat
Definition: chan_iax2.c:347
static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL
Definition: chan_iax2.c:1016
static uint16_t DEFAULT_MAXCALLNO_LIMIT
Definition: chan_iax2.c:1014
static int add_calltoken_ignore(const char *addr)
Definition: chan_iax2.c:2842
#define MAX_TRUNKDATA
Definition: chan_iax2.c:340
static int iax2_register(const char *value, int lineno)
Definition: chan_iax2.c:8966
static int max_reg_expire
Definition: chan_iax2.c:360
static void set_config_destroy(void)
Definition: chan_iax2.c:13629
static int reload(void)
Definition: chan_iax2.c:14229
#define IAX_ALLOWFWDOWNLOAD
Definition: chan_iax2.c:523
static uint16_t global_maxcallno
Definition: chan_iax2.c:1018
static void build_callno_limits(struct ast_variable *v)
Definition: chan_iax2.c:2787
struct ast_sockaddr bindaddr
Definition: chan_ooh323.c:353
uint64_t iax2_codec_pref_from_bitfield(struct iax2_codec_pref *pref, uint64_t bitfield)
Create codec preference list from the given bitfield formats.
Definition: codec_pref.c:481
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3326
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:783
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
@ CONFIG_FLAG_FILEUNCHANGED
struct ast_netsock * ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc, struct ast_sockaddr *bindaddr, int tos, int cos, ast_io_cb callback, void *data)
Definition: netsock.c:109
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:6149
Structure used to handle boolean flags.
Definition: utils.h:199

References accountcode, add_calltoken_ignore(), adsi, amaflags, ao2_link, ast_category_browse(), ast_channel_string2amaflag(), ast_clear_flag, ast_clear_flag64, ast_config_destroy(), ast_config_load, ast_context_find_or_create(), ast_copy_string(), ast_false(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, ast_netsock_bindaddr(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_arg(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_test_flag64, ast_timer_set_rate(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, authdebug, autokill, bindaddr, build_callno_limits(), build_peer(), build_user(), config_file, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXCALLNO_LIMIT, DEFAULT_MAXCALLNO_LIMIT_NONVAL, DEFAULT_MAXMS, default_parkinglot, defaultsockfd, delayreject, errno, gen, get_auth_methods(), get_encrypt_methods(), global_max_trunk_mtu, global_maxcallno, global_maxcallno_nonval, global_rtautoclear, globalflags, iax2_authmethods, iax2_capability, iax2_codec_pref_from_bitfield(), iax2_encryption, iax2_parse_allow_disallow(), iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_AUTH_PLAINTEXT, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTSAVE_SYSNAME, IAX_RTUPDATE, IAX_SENDCONNECTEDLINE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxcompat, iaxmaxthreadcount, iaxthreadcount, io, jittertargetextra, lagrq_time, language, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, max_calltoken_delay, max_reg_expire, MAX_TRUNK_MTU, MAX_TRUNKDATA, maxauthreq, maxjitterbuffer, maxjitterinterps, min_reg_expire, mohinterpret, mohsuggest, ast_variable::name, netsock, network_change_stasis_subscribe(), network_change_stasis_unsubscribe(), ast_variable::next, NULL, outsock, PARSE_ADDR, PARSE_IN_RANGE, PARSE_UINT32, peer_unref(), ping_time, prefs_global, qos, reg_source_db(), regcontext, reload(), resyncthreshold, set_config_destroy(), socket_read(), srvlookup, timer, tmp(), trunkfreq, trunkmaxsize, user, user_unref(), and ast_variable::value.

Referenced by load_module(), and reload_config().

◆ set_config_destroy()

static void set_config_destroy ( void  )
static

◆ set_hangup_source_and_cause()

static void set_hangup_source_and_cause ( int  callno,
unsigned char  causecode 
)
static

Definition at line 10204 of file chan_iax2.c.

10205{
10206 iax2_lock_owner(callno);
10207 if (iaxs[callno] && iaxs[callno]->owner) {
10208 struct ast_channel *owner;
10209 const char *name;
10210
10211 owner = iaxs[callno]->owner;
10212 if (causecode) {
10213 ast_channel_hangupcause_set(owner, causecode);
10214 }
10216 ast_channel_ref(owner);
10217 ast_channel_unlock(owner);
10218 ast_mutex_unlock(&iaxsl[callno]);
10219 ast_set_hangupsource(owner, name, 0);
10220 ast_channel_unref(owner);
10221 ast_mutex_lock(&iaxsl[callno]);
10222 }
10223}
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it's bridge.
Definition: channel.c:2499
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958

References ast_channel_hangupcause_set(), ast_channel_name(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_mutex_lock, ast_mutex_unlock, ast_set_hangupsource(), ast_strdupa, iax2_lock_owner(), iaxs, iaxsl, name, and chan_iax2_pvt::owner.

Referenced by socket_process_helper().

◆ set_peercnt_limit()

static void set_peercnt_limit ( struct peercnt peercnt)
static

Definition at line 2600 of file chan_iax2.c.

2601{
2602 uint16_t limit = global_maxcallno;
2603 struct addr_range *addr_range;
2604 struct ast_sockaddr addr;
2605
2606 ast_sockaddr_copy(&addr, &peercnt->addr);
2607
2608 if (peercnt->reg && peercnt->limit) {
2609 return; /* this peercnt has a custom limit set by a registration */
2610 }
2611
2613 limit = addr_range->limit;
2614 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_sockaddr_stringify(&addr));
2615 ao2_ref(addr_range, -1);
2616 }
2617
2618 peercnt->limit = limit;
2619}

References peercnt::addr, addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_sockaddr_copy(), ast_sockaddr_stringify(), callno_limits, global_maxcallno, peercnt::limit, addr_range::limit, and peercnt::reg.

Referenced by peercnt_add(), peercnt_modify(), and set_peercnt_limit_all_cb().

◆ set_peercnt_limit_all_cb()

static int set_peercnt_limit_all_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 2625 of file chan_iax2.c.

2626{
2627 struct peercnt *peercnt = obj;
2628
2630 ast_debug(1, "Reset limits for peercnts table\n");
2631
2632 return 0;
2633}

References ast_debug, and set_peercnt_limit().

Referenced by reload_config().

◆ signal_condition()

static void signal_condition ( ast_mutex_t lock,
ast_cond_t cond 
)
static

Definition at line 1158 of file chan_iax2.c.

1159{
1163}
ast_cond_t cond
Definition: app_sla.c:330
ast_mutex_t lock
Definition: app_sla.c:331

References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, cond, and lock.

Referenced by __schedule_action(), cleanup_thread_list(), iax2_process_thread(), and socket_read().

◆ socket_process()

static int socket_process ( struct iax2_thread thread)
static

Definition at line 12136 of file chan_iax2.c.

12137{
12138 int res = socket_process_helper(thread);
12141 }
12142 return res;
12143}
static int socket_process_helper(struct iax2_thread *thread)
Definition: chan_iax2.c:10225
int ast_callid_threadassoc_remove(void)
Removes callid from thread storage of the calling thread.
Definition: logger.c:2327

References ast_callid_threadassoc_remove(), ast_read_threadstorage_callid(), socket_process_helper(), and thread.

Referenced by handle_deferred_full_frames(), and iax2_process_thread().

◆ socket_process_helper()

static int socket_process_helper ( struct iax2_thread thread)
static

Definition at line 10225 of file chan_iax2.c.

10226{
10227 struct ast_sockaddr addr;
10228 int res;
10229 int updatehistory=1;
10230 int new = NEW_PREVENT;
10231 int dcallno = 0;
10232 char decrypted = 0;
10233 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
10234 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
10235 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
10236 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
10237 struct iax_frame *fr;
10238 struct iax_frame *cur;
10239 struct ast_frame f = { 0, };
10240 struct ast_channel *c = NULL;
10241 struct iax2_dpcache *dp;
10242 struct iax2_peer *peer;
10243 struct iax_ies ies;
10244 struct iax_ie_data ied0, ied1;
10245 iax2_format format;
10246 int fd;
10247 int exists;
10248 int minivid = 0;
10249 char empty[32]=""; /* Safety measure */
10250 struct iax_frame *duped_fr;
10251 char host_pref_buf[128];
10252 char caller_pref_buf[128];
10253 struct iax2_codec_pref pref;
10254 char *using_prefs = "mine";
10255
10256 /* allocate an iax_frame with 4096 bytes of data buffer */
10257 fr = ast_alloca(sizeof(*fr) + 4096);
10258 memset(fr, 0, sizeof(*fr));
10259 fr->afdatalen = 4096; /* From ast_alloca() above */
10260
10261 /* Copy frequently used parameters to the stack */
10262 res = thread->buf_len;
10263 fd = thread->iofd;
10264 ast_sockaddr_copy(&addr, &thread->ioaddr);
10265
10266 if (res < sizeof(*mh)) {
10267 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
10268 return 1;
10269 }
10270 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
10271 if (res < sizeof(*vh)) {
10272 ast_log(LOG_WARNING, "Rejecting packet from '%s' that is flagged as a video frame but is too short\n",
10273 ast_sockaddr_stringify(&addr));
10274 return 1;
10275 }
10276
10277 /* This is a video frame, get call number */
10278 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &addr, new, fd, 0);
10279 minivid = 1;
10280 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
10281 return socket_process_meta(res, meta, &addr, fd, fr);
10282
10283#ifdef DEBUG_SUPPORT
10284 if (res >= sizeof(*fh))
10285 iax_outputframe(NULL, fh, 1, &addr, res - sizeof(*fh));
10286#endif
10287 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10288 if (res < sizeof(*fh)) {
10289 ast_log(LOG_WARNING, "Rejecting packet from '%s' that is flagged as a full frame but is too short\n",
10290 ast_sockaddr_stringify(&addr));
10291 return 1;
10292 }
10293
10294 /* Get the destination call number */
10295 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
10296
10297
10298 /* check to make sure this full frame isn't encrypted before we attempt
10299 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the
10300 * callno is not found here, that just means one hasn't been allocated for
10301 * this connection yet. */
10302 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &addr, NEW_PREVENT, fd, 1))) {
10304 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
10305 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10306 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10308 return 1;
10309 }
10310 decrypted = 1;
10311 }
10313 }
10314
10315 /* Retrieve the type and subclass */
10316 f.frametype = fh->type;
10317 if (f.frametype == AST_FRAME_VIDEO) {
10319 if (!f.subclass.format) {
10320 return 1;
10321 }
10322 if ((fh->csub >> 6) & 0x1) {
10323 f.subclass.frame_ending = 1;
10324 }
10325 } else if (f.frametype == AST_FRAME_VOICE) {
10327 if (!f.subclass.format) {
10328 return 1;
10329 }
10330 } else {
10332 }
10333
10334 /* Deal with POKE/PONG without allocating a callno */
10336 /* Reply back with a PONG, but don't care about the result. */
10337 send_apathetic_reply(1, ntohs(fh->scallno), &addr, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10338 return 1;
10339 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
10340 /* Ignore */
10341 return 1;
10342 }
10343
10344 f.datalen = res - sizeof(*fh);
10345 if (f.datalen) {
10346 if (f.frametype == AST_FRAME_IAX) {
10347 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
10348 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_sockaddr_stringify(&addr));
10349 ast_variables_destroy(ies.vars);
10350 return 1;
10351 }
10352 f.data.ptr = NULL;
10353 f.datalen = 0;
10354 } else {
10355 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
10356 memset(&ies, 0, sizeof(ies));
10357 }
10358 } else {
10359 if (f.frametype == AST_FRAME_IAX)
10360 f.data.ptr = NULL;
10361 else
10362 f.data.ptr = empty;
10363 memset(&ies, 0, sizeof(ies));
10364 }
10365
10366 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
10367 /* only set NEW_ALLOW if calltoken checks out */
10368 if (handle_call_token(fh, &ies, &addr, fd)) {
10369 ast_variables_destroy(ies.vars);
10370 return 1;
10371 }
10372
10373 if (ies.calltoken && ies.calltokendata) {
10374 /* if we've gotten this far, and the calltoken ie data exists,
10375 * then calltoken validation _MUST_ have taken place. If calltoken
10376 * data is provided, it is always validated reguardless of any
10377 * calltokenoptional or requirecalltoken options */
10379 } else {
10380 new = NEW_ALLOW;
10381 }
10382 }
10383 } else {
10384 /* Don't know anything about it yet */
10386 f.subclass.integer = 0;
10387 memset(&ies, 0, sizeof(ies));
10388 }
10389
10390 if (!fr->callno) {
10391 int check_dcallno = 0;
10392
10393 /*
10394 * We enforce accurate destination call numbers for ACKs. This forces the other
10395 * end to know the destination call number before call setup can complete.
10396 *
10397 * Discussed in the following thread:
10398 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html
10399 */
10400
10401 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10402 check_dcallno = 1;
10403 }
10404
10405 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &addr, new, fd, check_dcallno))) {
10407 send_apathetic_reply(1, ntohs(fh->scallno), &addr, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10409 send_apathetic_reply(1, ntohs(fh->scallno), &addr, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10410 }
10411 ast_variables_destroy(ies.vars);
10412 return 1;
10413 }
10414 }
10415
10416 if (fr->callno > 0) {
10417 ast_callid mount_callid;
10419 if (iaxs[fr->callno] && ((mount_callid = iax_pvt_callid_get(fr->callno)))) {
10420 /* Bind to thread */
10421 ast_callid_threadassoc_add(mount_callid);
10422 }
10423 }
10424
10425 if (!fr->callno || !iaxs[fr->callno]) {
10426 /* A call arrived for a nonexistent destination. Unless it's an "inval"
10427 frame, reply with an inval */
10428 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10429 /* We can only raw hangup control frames */
10430 if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10434 (f.frametype != AST_FRAME_IAX))
10435 raw_hangup(&addr, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10436 fd);
10437 }
10438 if (fr->callno > 0){
10440 }
10441 ast_variables_destroy(ies.vars);
10442 return 1;
10443 }
10444 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10445 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10446 ast_log(LOG_WARNING, "Packet Decrypt Failed!\n");
10447 ast_variables_destroy(ies.vars);
10449 return 1;
10450 }
10451 decrypted = 1;
10452 }
10453
10454#ifdef DEBUG_SUPPORT
10455 if (decrypted) {
10456 iax_outputframe(NULL, fh, 3, &addr, res - sizeof(*fh));
10457 }
10458#endif
10459
10460 if (iaxs[fr->callno]->owner && fh->type == AST_FRAME_IAX &&
10461 (fh->csub == IAX_COMMAND_HANGUP
10462 || fh->csub == IAX_COMMAND_REJECT
10463 || fh->csub == IAX_COMMAND_REGREJ
10464 || fh->csub == IAX_COMMAND_TXREJ)) {
10465 struct ast_control_pvt_cause_code *cause_code;
10466 int data_size = sizeof(*cause_code);
10467 char subclass[40] = "";
10468
10469 /* get subclass text */
10470 iax_frame_subclass2str(fh->csub, subclass, sizeof(subclass));
10471
10472 /* add length of "IAX2 " */
10473 data_size += 5;
10474 /* for IAX hangup frames, add length of () and number */
10475 data_size += 3;
10476 if (ies.causecode > 9) {
10477 data_size++;
10478 }
10479 if (ies.causecode > 99) {
10480 data_size++;
10481 }
10482 /* add length of subclass */
10483 data_size += strlen(subclass);
10484
10485 cause_code = ast_alloca(data_size);
10486 memset(cause_code, 0, data_size);
10488
10489 cause_code->ast_cause = ies.causecode;
10490 snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "IAX2 %s(%d)", subclass, ies.causecode);
10491
10493 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10494 ast_queue_control_data(iaxs[fr->callno]->owner, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
10495 ast_channel_hangupcause_hash_set(iaxs[fr->callno]->owner, cause_code, data_size);
10497 }
10498 if (!iaxs[fr->callno]) {
10499 ast_variables_destroy(ies.vars);
10501 return 1;
10502 }
10503 }
10504
10505 /* count this frame */
10506 iaxs[fr->callno]->frames_received++;
10507
10508 if (!ast_sockaddr_cmp(&addr, &iaxs[fr->callno]->addr) && !minivid &&
10509 f.subclass.integer != IAX_COMMAND_TXCNT && /* for attended transfer */
10510 f.subclass.integer != IAX_COMMAND_TXACC) { /* for attended transfer */
10511 unsigned short new_peercallno;
10512
10513 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10514 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10515 if (iaxs[fr->callno]->peercallno) {
10517 }
10518 iaxs[fr->callno]->peercallno = new_peercallno;
10520 }
10521 }
10522 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10523 if (iaxdebug)
10524 ast_debug(1, "Received packet %d, (%u, %d)\n", fh->oseqno, f.frametype, f.subclass.integer);
10525 /* Check if it's out of order (and not an ACK or INVAL) */
10526 fr->oseqno = fh->oseqno;
10527 fr->iseqno = fh->iseqno;
10528 fr->ts = ntohl(fh->ts);
10529#ifdef IAXTESTS
10530 if (test_resync) {
10531 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10532 fr->ts += test_resync;
10533 }
10534#endif /* IAXTESTS */
10535#if 0
10536 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10537 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10538 (f.subclass == IAX_COMMAND_NEW ||
10541 f.subclass == IAX_COMMAND_REJECT)) ) )
10542#endif
10543 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10544 updatehistory = 0;
10545 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10546 (iaxs[fr->callno]->iseqno ||
10548 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */
10549 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */
10550 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
10552 (f.frametype != AST_FRAME_IAX))) {
10553 if (
10557 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */
10558 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */
10559 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
10562 (f.frametype != AST_FRAME_IAX)) {
10563 /* If it's not an ACK packet, it's out of order. */
10564 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %u, subclass = %d)\n",
10565 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10566 /* Check to see if we need to request retransmission,
10567 * and take sequence number wraparound into account */
10568 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10569 /* If we've already seen it, ack it XXX There's a border condition here XXX */
10570 if ((f.frametype != AST_FRAME_IAX) ||
10572 ast_debug(1, "Acking anyway\n");
10573 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
10574 we have anything to send, we'll retransmit and get an ACK back anyway XXX */
10576 }
10577 } else {
10578 /* Send a VNAK requesting retransmission */
10579 iax2_vnak(fr->callno);
10580 }
10581 ast_variables_destroy(ies.vars);
10583 return 1;
10584 }
10585 } else {
10586 /* Increment unless it's an ACK or VNAK */
10587 if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10592 (f.frametype != AST_FRAME_IAX))
10593 iaxs[fr->callno]->iseqno++;
10594 }
10595 /* Ensure text frames are NULL-terminated */
10596 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10597 if (res < thread->buf_size)
10598 thread->buf[res++] = '\0';
10599 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
10600 thread->buf[res - 1] = '\0';
10601 }
10602
10603 /* Handle implicit ACKing unless this is an INVAL, and only if this is
10604 from the real peer, not the transfer peer */
10605 if (!ast_sockaddr_cmp(&addr, &iaxs[fr->callno]->addr) &&
10607 (f.frametype != AST_FRAME_IAX))) {
10608 unsigned char x;
10609 int call_to_destroy;
10610 /* First we have to qualify that the ACKed value is within our window */
10611 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10612 x = fr->iseqno;
10613 else
10614 x = iaxs[fr->callno]->oseqno;
10615 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10616 /* The acknowledgement is within our window. Time to acknowledge everything
10617 that it says to */
10618 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10619 /* Ack the packet with the given timestamp */
10620 if (iaxdebug)
10621 ast_debug(1, "Cancelling transmission of packet %d\n", x);
10622 call_to_destroy = 0;
10623 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10624 /* If it's our call, and our timestamp, mark -1 retries */
10625 if (x == cur->oseqno) {
10626 cur->retries = -1;
10627 /* Destroy call if this is the end */
10628 if (cur->final)
10629 call_to_destroy = fr->callno;
10630 }
10631 }
10632 if (call_to_destroy) {
10633 if (iaxdebug)
10634 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10635 ast_mutex_lock(&iaxsl[call_to_destroy]);
10636 iax2_destroy(call_to_destroy);
10637 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10638 }
10639 }
10640 /* Note how much we've received acknowledgement for */
10641 if (iaxs[fr->callno])
10642 iaxs[fr->callno]->rseqno = fr->iseqno;
10643 else {
10644 /* Stop processing now */
10645 ast_variables_destroy(ies.vars);
10647 return 1;
10648 }
10649 } else {
10650 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10651 }
10652 }
10653 if (ast_sockaddr_cmp(&addr, &iaxs[fr->callno]->addr) &&
10654 ((f.frametype != AST_FRAME_IAX) ||
10657 /* Only messages we accept from a transfer host are TXACC and TXCNT */
10658 ast_variables_destroy(ies.vars);
10660 return 1;
10661 }
10662
10663 /* when we receive the first full frame for a new incoming channel,
10664 it is safe to start the PBX on the channel because we have now
10665 completed a 3-way handshake with the peer */
10666 if ((f.frametype == AST_FRAME_VOICE) ||
10667 (f.frametype == AST_FRAME_VIDEO) ||
10668 (f.frametype == AST_FRAME_IAX)) {
10674 ast_variables_destroy(ies.vars);
10676 return 1;
10677 }
10678 }
10679
10680 if (ies.vars) {
10681 struct ast_datastore *variablestore = NULL;
10682 struct ast_variable *var, *prev = NULL;
10683 AST_LIST_HEAD(, ast_var_t) *varlist;
10684
10686 if (!iaxs[fr->callno]) {
10687 ast_variables_destroy(ies.vars);
10689 return 1;
10690 }
10691 if ((c = iaxs[fr->callno]->owner)) {
10692 varlist = ast_calloc(1, sizeof(*varlist));
10694
10695 if (variablestore && varlist) {
10696 variablestore->data = varlist;
10697 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10698 AST_LIST_HEAD_INIT(varlist);
10699 ast_debug(1, "I can haz IAX vars?\n");
10700 for (var = ies.vars; var; var = var->next) {
10701 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10702 if (prev) {
10703 ast_free(prev);
10704 }
10705 prev = var;
10706 if (!newvar) {
10707 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
10708 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10709 } else {
10710 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10711 }
10712 }
10713 if (prev) {
10714 ast_free(prev);
10715 }
10716 ies.vars = NULL;
10717 ast_channel_datastore_add(c, variablestore);
10718 } else {
10719 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10720 if (variablestore) {
10721 ast_datastore_free(variablestore);
10722 }
10723 if (varlist) {
10724 ast_free(varlist);
10725 }
10726 }
10728 } else {
10729 /* No channel yet, so transfer the variables directly over to the pvt,
10730 * for later inheritance. */
10731 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10732 for (var = ies.vars; var && var->next; var = var->next);
10733 if (var) {
10734 var->next = iaxs[fr->callno]->iaxvars;
10735 iaxs[fr->callno]->iaxvars = ies.vars;
10736 ies.vars = NULL;
10737 }
10738 }
10739 }
10740
10741 if (ies.vars) {
10742 ast_debug(1, "I have IAX variables, but they were not processed\n");
10743 }
10744 }
10745
10746 /* once we receive our first IAX Full Frame that is not CallToken related, send all
10747 * queued signaling frames that were being held. */
10750 }
10751
10752 if (f.frametype == AST_FRAME_VOICE) {
10755 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_format_get_name(f.subclass.format));
10756 if (iaxs[fr->callno]->owner) {
10758 if (iaxs[fr->callno]) {
10759 if (iaxs[fr->callno]->owner) {
10761 if (native) {
10766 }
10767 ao2_ref(native, -1);
10768 }
10770 }
10771 } else {
10772 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10773 /* Free remote variables (if any) */
10774 if (ies.vars) {
10775 ast_variables_destroy(ies.vars);
10776 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
10777 ies.vars = NULL;
10778 }
10780 return 1;
10781 }
10782 }
10783 }
10784 }
10785 if (f.frametype == AST_FRAME_VIDEO) {
10787 ast_debug(1, "Ooh, video format changed to %s\n", ast_format_get_name(f.subclass.format));
10789 }
10790 }
10791 if (f.frametype == AST_FRAME_IAX) {
10793 /* Handle the IAX pseudo frame itself */
10794 if (iaxdebug)
10795 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10796
10797 /* Update last ts unless the frame's timestamp originated with us. */
10798 if (iaxs[fr->callno]->last < fr->ts &&
10802 iaxs[fr->callno]->last = fr->ts;
10803 if (iaxdebug)
10804 ast_debug(1, "For call=%d, set last=%u\n", fr->callno, fr->ts);
10805 }
10807 if (!iaxs[fr->callno]->first_iax_message) {
10809 }
10810 switch(f.subclass.integer) {
10811 case IAX_COMMAND_ACK:
10812 /* Do nothing */
10813 break;
10814 case IAX_COMMAND_QUELCH:
10817 if (ies.musiconhold) {
10818 const char *moh_suggest;
10819
10821 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10822 break;
10823 }
10824
10825 /*
10826 * We already hold the owner lock so we do not
10827 * need to check iaxs[fr->callno] after it returns.
10828 */
10829 moh_suggest = iaxs[fr->callno]->mohsuggest;
10830 iax2_queue_hold(fr->callno, moh_suggest);
10832 }
10833 }
10834 break;
10838 if (!iaxs[fr->callno]) {
10839 break;
10840 }
10841
10843 if (!iaxs[fr->callno]->owner) {
10844 break;
10845 }
10846
10847 /*
10848 * We already hold the owner lock so we do not
10849 * need to check iaxs[fr->callno] after it returns.
10850 */
10853 }
10854 break;
10855 case IAX_COMMAND_TXACC:
10856 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10857 /* Ack the packet with the given timestamp */
10858 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10859 /* Cancel any outstanding txcnt's */
10860 if (cur->transfer) {
10861 cur->retries = -1;
10862 }
10863 }
10864 memset(&ied1, 0, sizeof(ied1));
10866 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10868 }
10869 break;
10870 case IAX_COMMAND_NEW:
10871 /* Ignore if it's already up */
10873 break;
10874 if (ies.provverpres && ies.serviceident && !(ast_sockaddr_isnull(&addr))) {
10876 check_provisioning(&addr, fd, ies.serviceident, ies.provver);
10878 if (!iaxs[fr->callno]) {
10879 break;
10880 }
10881 }
10882 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
10883 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10884 int new_callno;
10885 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10886 fr->callno = new_callno;
10887 }
10888 /* For security, always ack immediately */
10889 if (delayreject)
10891 if (check_access(fr->callno, &addr, &ies)) {
10892 /* They're not allowed on */
10894 if (authdebug) {
10895 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n",
10897 }
10898 break;
10899 }
10902 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10903 break;
10904 }
10905 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10906 const char *context, *exten, *cid_num;
10907
10909 exten = ast_strdupa(iaxs[fr->callno]->exten);
10910 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10911
10912 /* This might re-enter the IAX code and need the lock */
10914 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10916
10917 if (!iaxs[fr->callno]) {
10918 break;
10919 }
10920 } else
10921 exists = 0;
10922 /* Get OSP token if it does exist */
10923 save_osptoken(fr, &ies);
10925 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10926 memset(&ied0, 0, sizeof(ied0));
10927 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10929 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10930 if (!iaxs[fr->callno]) {
10931 break;
10932 }
10933 if (authdebug) {
10934 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n",
10936 }
10937 } else {
10938 /* Select an appropriate format */
10939
10942 using_prefs = "reqonly";
10943 } else {
10944 using_prefs = "disabled";
10945 }
10946 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10947 memset(&pref, 0, sizeof(pref));
10948 strcpy(caller_pref_buf, "disabled");
10949 strcpy(host_pref_buf, "disabled");
10950 } else {
10951 struct ast_format *tmpfmt;
10952 using_prefs = "mine";
10953 /* If the information elements are in here... use them */
10954 if (ies.codec_prefs)
10955 iax2_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10956 if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
10957 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
10959 pref = iaxs[fr->callno]->rprefs;
10960 using_prefs = "caller";
10961 } else {
10962 pref = iaxs[fr->callno]->prefs;
10963 }
10964 } else
10965 pref = iaxs[fr->callno]->prefs;
10966
10967 format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability);
10968 iax2_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10969 iax2_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10970 }
10971 if (!format) {
10973 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10974 if (!format) {
10975 memset(&ied0, 0, sizeof(ied0));
10976 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10978 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10979 if (!iaxs[fr->callno]) {
10980 break;
10981 }
10982 if (authdebug) {
10985 struct ast_str *peer_form_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
10986
10988 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10990 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
10992 } else {
10993 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10995 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
10998 }
10999 }
11000 } else {
11001 /* Pick one... */
11003 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11004 format = 0;
11005 } else {
11007 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11008 memset(&pref, 0, sizeof(pref));
11010 strcpy(caller_pref_buf,"disabled");
11011 strcpy(host_pref_buf,"disabled");
11012 } else {
11013 struct ast_format *tmpfmt;
11014 using_prefs = "mine";
11015 if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11016 /* Do the opposite of what we tried above. */
11018 pref = iaxs[fr->callno]->prefs;
11019 } else {
11020 pref = iaxs[fr->callno]->rprefs;
11021 using_prefs = "caller";
11022 }
11023 format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11024 } else /* if no codec_prefs IE do it the old way */
11026 }
11027 }
11028
11029 if (!format) {
11032 struct ast_str *peer_form_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11033
11034 memset(&ied0, 0, sizeof(ied0));
11035 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11037 ast_log(LOG_ERROR, "No best format in '%s'???\n", iax2_getformatname_multiple(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, &cap_buf));
11038 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11039 if (!iaxs[fr->callno]) {
11040 break;
11041 }
11042 if (authdebug) {
11043 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11045 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11048 }
11050 break;
11051 }
11052 }
11053 }
11054 if (format) {
11055 /* No authentication required, let them in */
11056 memset(&ied1, 0, sizeof(ied1));
11057 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11059 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11060 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11062 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
11063 "%srequested format = %s,\n"
11064 "%srequested prefs = %s,\n"
11065 "%sactual format = %s,\n"
11066 "%shost prefs = %s,\n"
11067 "%spriority = %s\n",
11072 caller_pref_buf,
11074 iax2_getformatname(format),
11076 host_pref_buf,
11078 using_prefs);
11079
11080 iaxs[fr->callno]->chosenformat = format;
11081
11082 /* Since this is a new call, we should go ahead and set the callid for it. */
11085 } else {
11087 /* If this is a TBD call, we're ready but now what... */
11088 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_sockaddr_stringify(&addr));
11089 }
11090 }
11091 }
11092 break;
11093 }
11096 else
11097 iaxs[fr->callno]->encmethods = 0;
11098 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
11100 break;
11101 case IAX_COMMAND_DPREQ:
11102 /* Request status in the dialplan */
11104 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
11105 if (iaxcompat) {
11106 /* Spawn a thread for the lookup */
11107 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
11108 } else {
11109 /* Just look it up */
11110 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
11111 }
11112 }
11113 break;
11114 case IAX_COMMAND_HANGUP:
11116 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
11117 /* Set hangup cause according to remote and hangupsource */
11118 if (iaxs[fr->callno]->owner) {
11119 set_hangup_source_and_cause(fr->callno, ies.causecode);
11120 if (!iaxs[fr->callno]) {
11121 break;
11122 }
11123 }
11124
11125 /* Send ack immediately, before we destroy */
11127 iax2_destroy(fr->callno);
11128 break;
11129 case IAX_COMMAND_REJECT:
11130 /* Set hangup cause according to remote and hangup source */
11131 if (iaxs[fr->callno]->owner) {
11132 set_hangup_source_and_cause(fr->callno, ies.causecode);
11133 if (!iaxs[fr->callno]) {
11134 break;
11135 }
11136 }
11137
11139 if (iaxs[fr->callno]->owner && authdebug)
11140 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
11142 ies.cause ? ies.cause : "<Unknown>");
11143 ast_debug(1, "Immediately destroying %d, having received reject\n",
11144 fr->callno);
11145 }
11146 /* Send ack immediately, before we destroy */
11148 fr->ts, NULL, 0, fr->iseqno);
11150 iaxs[fr->callno]->error = EPERM;
11151 iax2_destroy(fr->callno);
11152 break;
11154 {
11156 if (!iaxs[fr->callno]) {
11157 /* Initiating call went away before we could transfer. */
11158 break;
11159 }
11160 if (iaxs[fr->callno]->owner) {
11161 struct ast_channel *owner = iaxs[fr->callno]->owner;
11162 char *context = ast_strdupa(iaxs[fr->callno]->context);
11163
11164 ast_channel_ref(owner);
11165 ast_channel_unlock(owner);
11167
11168 if (ast_bridge_transfer_blind(1, owner, ies.called_number,
11170 ast_log(LOG_WARNING, "Blind transfer of '%s' to '%s@%s' failed\n",
11171 ast_channel_name(owner), ies.called_number,
11172 context);
11173 }
11174
11175 ast_channel_unref(owner);
11177 }
11178
11179 break;
11180 }
11181 case IAX_COMMAND_ACCEPT:
11182 /* Ignore if call is already up or needs authentication or is a TBD */
11184 break;
11186 /* Send ack immediately, before we destroy */
11188 iax2_destroy(fr->callno);
11189 break;
11190 }
11191 if (ies.format) {
11192 iaxs[fr->callno]->peerformat = ies.format;
11193 } else {
11194 if (iaxs[fr->callno]->owner)
11196 else
11198 }
11199 ast_verb(3, "Call accepted by %s (format %s)\n", ast_sockaddr_stringify(&addr),
11201 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
11202 memset(&ied0, 0, sizeof(ied0));
11203 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11205 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11206 if (!iaxs[fr->callno]) {
11207 break;
11208 }
11209 if (authdebug) {
11212
11213 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
11217 }
11218 } else {
11220
11223 if (iaxs[fr->callno] && iaxs[fr->callno]->owner && native) {
11225
11226 /* Switch us to use a compatible format */
11228 iaxs[fr->callno]->peerformat, &iaxs[fr->callno]->rprefs,
11229 native);
11231 ast_verb(3, "Format for call is %s\n", ast_format_cap_get_names(ast_channel_nativeformats(iaxs[fr->callno]->owner), &cap_buf));
11232
11233 /* Setup read/write formats properly. */
11239 }
11240
11241 ao2_cleanup(native);
11242 }
11243 if (iaxs[fr->callno]) {
11245 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
11246 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
11247 iax2_dprequest(dp, fr->callno);
11249 }
11250 break;
11251 case IAX_COMMAND_POKE:
11252 /* Send back a pong packet with the original timestamp */
11254 break;
11255 case IAX_COMMAND_PING:
11256 {
11257 struct iax_ie_data pingied;
11258 construct_rr(iaxs[fr->callno], &pingied);
11259 /* Send back a pong packet with the original timestamp */
11260 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
11261 }
11262 break;
11263 case IAX_COMMAND_PONG:
11264 /* Calculate ping time */
11265 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
11266 /* save RR info */
11267 save_rr(fr, &ies);
11268
11269 /* Good time to write jb stats for this call */
11271
11272 if (iaxs[fr->callno]->peerpoke) {
11273 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
11274 peer = iaxs[fr->callno]->peerpoke;
11275 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
11276 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
11277 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %u\n", peer->name, iaxs[fr->callno]->pingtime);
11279 blob = ast_json_pack("{s: s, s: I}",
11280 "peer_status", "Reachable",
11281 "time", (ast_json_int_t)iaxs[fr->callno]->pingtime);
11282 ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
11283 }
11284 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
11285 if (iaxs[fr->callno]->pingtime > peer->maxms) {
11286 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%u ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
11288 blob = ast_json_pack("{s: s, s: I}",
11289 "peer_status", "Lagged",
11290 "time", (ast_json_int_t)iaxs[fr->callno]->pingtime);
11291 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
11292 }
11293 }
11295 peer->lastms = iaxs[fr->callno]->pingtime;
11296 if (peer->smoothing && (peer->lastms > -1))
11297 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
11298 else if (peer->smoothing && peer->lastms < 0)
11299 peer->historicms = (0 + peer->historicms) / 2;
11300 else
11301 peer->historicms = iaxs[fr->callno]->pingtime;
11302
11303 /* Remove scheduled iax2_poke_noanswer */
11304 if (peer->pokeexpire > -1) {
11305 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
11306 peer_unref(peer);
11307 peer->pokeexpire = -1;
11308 }
11309 }
11310 /* Schedule the next cycle */
11311 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
11313 else
11315 if (peer->pokeexpire == -1)
11316 peer_unref(peer);
11317 /* and finally send the ack */
11319 /* And wrap up the qualify call */
11320 iax2_destroy(fr->callno);
11321 peer->callno = 0;
11322 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
11323 }
11324 break;
11325 case IAX_COMMAND_LAGRQ:
11326 case IAX_COMMAND_LAGRP:
11327 f.src = "LAGRQ";
11328 f.mallocd = 0;
11329 f.offset = 0;
11330 f.samples = 0;
11331 iax_frame_wrap(fr, &f);
11333 /* Received a LAGRQ - echo back a LAGRP */
11335 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
11336 } else {
11337 /* Received LAGRP in response to our LAGRQ */
11338 unsigned int ts;
11339 /* This is a reply we've been given, actually measure the difference */
11340 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
11341 iaxs[fr->callno]->lag = ts - fr->ts;
11342 if (iaxdebug)
11343 ast_debug(1, "Peer %s lag measured as %dms\n",
11344 ast_sockaddr_stringify(&addr), iaxs[fr->callno]->lag);
11345 }
11346 break;
11349 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11350 break;
11351 }
11352 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
11353 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
11354 .subclass.integer = AST_CONTROL_HANGUP,
11355 };
11357 "I don't know how to authenticate %s to %s\n",
11358 ies.username ? ies.username : "<unknown>", ast_sockaddr_stringify(&addr));
11359 iax2_queue_frame(fr->callno, &hangup_fr);
11360 }
11361 break;
11363 /* For security, always ack immediately */
11364 if (delayreject)
11366 /* Ignore once we've started */
11368 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11369 break;
11370 }
11371 if (authenticate_verify(iaxs[fr->callno], &ies)) {
11372 if (authdebug)
11373 ast_log(LOG_WARNING, "Host %s failed to authenticate as %s\n", ast_sockaddr_stringify(&addr),
11374 iaxs[fr->callno]->username);
11375 memset(&ied0, 0, sizeof(ied0));
11377 break;
11378 }
11379 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
11380 /* This might re-enter the IAX code and need the lock */
11382 } else
11383 exists = 0;
11384 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
11385 if (authdebug)
11386 ast_log(LOG_WARNING, "Rejected connect attempt from %s, request '%s@%s' does not exist\n",
11388 iaxs[fr->callno]->exten,
11389 iaxs[fr->callno]->context);
11390 memset(&ied0, 0, sizeof(ied0));
11391 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11393 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11394 if (!iaxs[fr->callno]) {
11395 break;
11396 }
11397 } else {
11398 /* Select an appropriate format */
11401 using_prefs = "reqonly";
11402 } else {
11403 using_prefs = "disabled";
11404 }
11405 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
11406 memset(&pref, 0, sizeof(pref));
11407 strcpy(caller_pref_buf, "disabled");
11408 strcpy(host_pref_buf, "disabled");
11409 } else {
11410 struct ast_format *tmpfmt;
11411 using_prefs = "mine";
11412 if (ies.codec_prefs)
11413 iax2_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11414 if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11416 pref = iaxs[fr->callno]->rprefs;
11417 using_prefs = "caller";
11418 } else {
11419 pref = iaxs[fr->callno]->prefs;
11420 }
11421 } else /* if no codec_prefs IE do it the old way */
11422 pref = iaxs[fr->callno]->prefs;
11423 format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability);
11424 iax2_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11425 iax2_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11426 }
11427 if (!format) {
11430 struct ast_str *peer_form_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11431
11433 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11436 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11437 }
11438 if (!format) {
11439 if (authdebug) {
11441 ast_log(LOG_WARNING, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11443 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11445 } else {
11446 ast_log(LOG_WARNING, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11448 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11451 }
11452 }
11453 memset(&ied0, 0, sizeof(ied0));
11454 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11456 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11457 if (!iaxs[fr->callno]) {
11458 break;
11459 }
11460 } else {
11461 /* Pick one... */
11463 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11464 format = 0;
11465 } else {
11467 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11468 memset(&pref, 0, sizeof(pref));
11470 ? iaxs[fr->callno]->peerformat
11472 strcpy(caller_pref_buf,"disabled");
11473 strcpy(host_pref_buf,"disabled");
11474 } else {
11475 struct ast_format *tmpfmt;
11476 using_prefs = "mine";
11477 if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11478 /* Do the opposite of what we tried above. */
11480 pref = iaxs[fr->callno]->prefs;
11481 } else {
11482 pref = iaxs[fr->callno]->rprefs;
11483 using_prefs = "caller";
11484 }
11485 format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11486 } else /* if no codec_prefs IE do it the old way */
11488 }
11489 }
11490 if (!format) {
11493 struct ast_str *peer_form_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11494
11495 ast_log(LOG_ERROR, "No best format in %s???\n",
11497 if (authdebug) {
11499 ast_log(LOG_WARNING, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11501 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11503 } else {
11504 ast_log(LOG_WARNING, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11506 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11509 }
11510 }
11511 memset(&ied0, 0, sizeof(ied0));
11512 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11514 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11515 if (!iaxs[fr->callno]) {
11516 break;
11517 }
11518 }
11519 }
11520 }
11521 if (format) {
11522 /* Authentication received */
11523 memset(&ied1, 0, sizeof(ied1));
11524 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11526 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11527 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11528 char authmethodnames[AUTH_METHOD_NAMES_BUFSIZE];
11530 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11531 "%srequested auth methods = (%s),\n"
11532 "%sactual auth method = %s,\n"
11533 "%sencrypted = %s,\n"
11534 "%srequested format = %s,\n"
11535 "%srequested prefs = %s,\n"
11536 "%sactual format = %s,\n"
11537 "%shost prefs = %s,\n"
11538 "%spriority = %s\n",
11541 auth_method_names(iaxs[fr->callno]->authmethods, authmethodnames),
11545 IAX_CALLENCRYPTED(iaxs[fr->callno]) ? "yes" : "no",
11549 caller_pref_buf,
11551 iax2_getformatname(format),
11553 host_pref_buf,
11555 using_prefs);
11556
11558 c = ast_iax2_new(fr->callno, AST_STATE_RING, format,
11559 &iaxs[fr->callno]->rprefs, NULL, NULL, 1);
11560 if (!c) {
11561 iax2_destroy(fr->callno);
11562 } else if (ies.vars) {
11563 struct ast_datastore *variablestore;
11564 struct ast_variable *var, *prev = NULL;
11565 AST_LIST_HEAD(, ast_var_t) *varlist;
11566 varlist = ast_calloc(1, sizeof(*varlist));
11568 if (variablestore && varlist) {
11569 variablestore->data = varlist;
11570 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11571 AST_LIST_HEAD_INIT(varlist);
11572 ast_debug(1, "I can haz IAX vars? w00t\n");
11573 for (var = ies.vars; var; var = var->next) {
11574 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11575 if (prev)
11576 ast_free(prev);
11577 prev = var;
11578 if (!newvar) {
11579 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11580 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11581 } else {
11582 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11583 }
11584 }
11585 if (prev)
11586 ast_free(prev);
11587 ies.vars = NULL;
11588 ast_channel_datastore_add(c, variablestore);
11589 } else {
11590 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11591 if (variablestore)
11592 ast_datastore_free(variablestore);
11593 if (varlist)
11594 ast_free(varlist);
11595 }
11596 }
11597 } else {
11599 /* If this is a TBD call, we're ready but now what... */
11600 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_sockaddr_stringify(&addr));
11602 goto immediatedial;
11603 }
11604 }
11605 }
11606 }
11607 break;
11608 case IAX_COMMAND_DIAL:
11609immediatedial:
11612 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11613 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11614 if (authdebug)
11615 ast_log(LOG_WARNING, "Rejected dial attempt from %s, request '%s@%s' does not exist\n",
11617 iaxs[fr->callno]->exten,
11618 iaxs[fr->callno]->context);
11619 memset(&ied0, 0, sizeof(ied0));
11620 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11622 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11623 if (!iaxs[fr->callno]) {
11624 break;
11625 }
11626 } else {
11629 ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11635 iaxs[fr->callno]->peerformat, &iaxs[fr->callno]->rprefs,
11636 NULL, NULL, 1);
11637 if (!c) {
11638 iax2_destroy(fr->callno);
11639 } else if (ies.vars) {
11640 struct ast_datastore *variablestore;
11641 struct ast_variable *var, *prev = NULL;
11642 AST_LIST_HEAD(, ast_var_t) *varlist;
11643 varlist = ast_calloc(1, sizeof(*varlist));
11645 ast_debug(1, "I can haz IAX vars? w00t\n");
11646 if (variablestore && varlist) {
11647 variablestore->data = varlist;
11648 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11649 AST_LIST_HEAD_INIT(varlist);
11650 for (var = ies.vars; var; var = var->next) {
11651 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11652 if (prev)
11653 ast_free(prev);
11654 prev = var;
11655 if (!newvar) {
11656 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11657 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11658 } else {
11659 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11660 }
11661 }
11662 if (prev)
11663 ast_free(prev);
11664 ies.vars = NULL;
11665 ast_channel_datastore_add(c, variablestore);
11666 } else {
11667 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11668 if (variablestore)
11669 ast_datastore_free(variablestore);
11670 if (varlist)
11671 ast_free(varlist);
11672 }
11673 }
11674 }
11675 }
11676 break;
11677 case IAX_COMMAND_INVAL:
11678 iaxs[fr->callno]->error = ENOTCONN;
11679 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11680 iax2_destroy(fr->callno);
11681 ast_debug(1, "Destroying call %d\n", fr->callno);
11682 break;
11683 case IAX_COMMAND_VNAK:
11684 ast_debug(1, "Received VNAK: resending outstanding frames\n");
11685 /* Force retransmission */
11686 vnak_retransmit(fr->callno, fr->iseqno);
11687 break;
11688 case IAX_COMMAND_REGREQ:
11689 case IAX_COMMAND_REGREL:
11690 /* For security, always ack immediately */
11691 if (delayreject)
11693 if (register_verify(fr->callno, &addr, &ies)) {
11694 if (!iaxs[fr->callno]) {
11695 break;
11696 }
11697 /* Send delayed failure */
11699 break;
11700 }
11701 if (!iaxs[fr->callno]) {
11702 break;
11703 }
11706
11708 ast_sockaddr_setnull(&addr);
11709 }
11710 if (update_registry(&addr, fr->callno, ies.devicetype, fd, ies.refresh)) {
11711 ast_log(LOG_WARNING, "Registry error\n");
11712 }
11713 if (!iaxs[fr->callno]) {
11714 break;
11715 }
11716 if (ies.provverpres && ies.serviceident && !(ast_sockaddr_isnull(&addr))) {
11718 check_provisioning(&addr, fd, ies.serviceident, ies.provver);
11720 }
11721 break;
11722 }
11724 break;
11725 case IAX_COMMAND_REGACK:
11726 if (iax2_ack_registry(&ies, &addr, fr->callno)) {
11727 ast_log(LOG_WARNING, "Registration failure\n");
11728 }
11729 /* Send ack immediately, before we destroy */
11731 iax2_destroy(fr->callno);
11732 break;
11733 case IAX_COMMAND_REGREJ:
11734 if (iaxs[fr->callno]->reg) {
11735 if (authdebug) {
11736 ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n",
11737 iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>",
11738 ast_sockaddr_stringify(&addr));
11739 }
11740 iax2_publish_registry(iaxs[fr->callno]->reg->username, ast_sockaddr_stringify(&addr), "Rejected", S_OR(ies.cause, "<unknown>"));
11742 }
11743 /* Send ack immediately, before we destroy */
11745 iax2_destroy(fr->callno);
11746 break;
11748 /* Authentication request */
11749 if (registry_rerequest(&ies, fr->callno, &addr)) {
11750 memset(&ied0, 0, sizeof(ied0));
11751 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11753 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11754 }
11755 break;
11756 case IAX_COMMAND_TXREJ:
11757 while (iaxs[fr->callno]
11758 && iaxs[fr->callno]->bridgecallno
11761 }
11762 if (!iaxs[fr->callno]) {
11763 break;
11764 }
11765
11767 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11768 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11769
11770 if (!iaxs[fr->callno]->bridgecallno) {
11771 break;
11772 }
11773
11774 if (iaxs[iaxs[fr->callno]->bridgecallno]
11778 }
11780 break;
11782 while (iaxs[fr->callno]
11783 && iaxs[fr->callno]->bridgecallno
11786 }
11787 if (!iaxs[fr->callno]) {
11788 break;
11789 }
11790
11791 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
11793 } else if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) {
11795 } else {
11796 if (iaxs[fr->callno]->bridgecallno) {
11798 }
11799 break;
11800 }
11801 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11802
11803 if (!iaxs[fr->callno]->bridgecallno) {
11804 break;
11805 }
11806
11807 if (!iaxs[iaxs[fr->callno]->bridgecallno]
11811 break;
11812 }
11813
11814 /* Both sides are ready */
11815
11816 /* XXX what isn't checked here is that both sides match transfer types. */
11817
11818 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11819 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
11821
11824
11825 memset(&ied0, 0, sizeof(ied0));
11826 memset(&ied1, 0, sizeof(ied1));
11829 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11830 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11831 } else {
11832 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
11834
11839
11840 /* Stop doing lag & ping requests */
11841 stop_stuff(fr->callno);
11843
11844 memset(&ied0, 0, sizeof(ied0));
11845 memset(&ied1, 0, sizeof(ied1));
11848 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11849 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11850 }
11852 break;
11853 case IAX_COMMAND_TXREQ:
11854 try_transfer(iaxs[fr->callno], &ies);
11855 break;
11856 case IAX_COMMAND_TXCNT:
11857 if (iaxs[fr->callno]->transferring)
11859 break;
11860 case IAX_COMMAND_TXREL:
11861 /* Send ack immediately, rather than waiting until we've changed addresses */
11863 complete_transfer(fr->callno, &ies);
11864 stop_stuff(fr->callno); /* for attended transfer to work with libiax */
11865 break;
11867 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11868 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11869 /* Cancel any outstanding frames and start anew */
11870 if (cur->transfer) {
11871 cur->retries = -1;
11872 }
11873 }
11874 /* Start sending our media to the transfer address, but otherwise leave the call as-is */
11876 }
11877 break;
11878 case IAX_COMMAND_RTKEY:
11879 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11881 "we've been told to rotate our encryption key, "
11882 "but this isn't an encrypted call. bad things will happen.\n"
11883 );
11884 break;
11885 }
11886
11887 IAX_DEBUGDIGEST("Receiving", ies.challenge);
11888
11889 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11890 break;
11891 case IAX_COMMAND_DPREP:
11892 complete_dpreply(iaxs[fr->callno], &ies);
11893 break;
11895 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11896 break;
11898 /* Firmware download */
11901 break;
11902 }
11903 memset(&ied0, 0, sizeof(ied0));
11904 res = iax_firmware_append(&ied0, ies.devicetype, ies.fwdesc);
11905 if (res < 0)
11906 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11907 else if (res > 0)
11908 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11909 else
11910 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11911 break;
11913 {
11914 struct iax_frame *cur;
11915 /* find last sent frame */
11916 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11917 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11918 }
11919 break;
11920 }
11921 default:
11922 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11923 memset(&ied0, 0, sizeof(ied0));
11925 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11926 }
11927 /* Free remote variables (if any) */
11928 if (ies.vars) {
11929 ast_variables_destroy(ies.vars);
11930 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11931 ies.vars = NULL;
11932 }
11933
11934 /* Don't actually pass these frames along */
11935 if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11940 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) {
11942 }
11943 }
11945 return 1;
11946 }
11947 /* Unless this is an ACK or INVAL frame, ack it */
11948 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11950 } else if (minivid) {
11952 if (iaxs[fr->callno]->videoformat > 0) {
11953 if (ntohs(vh->ts) & 0x8000LL) {
11954 f.subclass.frame_ending = 1;
11955 }
11957 if (!f.subclass.format) {
11958 ast_variables_destroy(ies.vars);
11960 return 1;
11961 }
11962 } else {
11963 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11964 iax2_vnak(fr->callno);
11965 ast_variables_destroy(ies.vars);
11967 return 1;
11968 }
11969 f.datalen = res - sizeof(*vh);
11970 if (f.datalen)
11971 f.data.ptr = thread->buf + sizeof(*vh);
11972 else
11973 f.data.ptr = NULL;
11974#ifdef IAXTESTS
11975 if (test_resync) {
11976 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11977 } else
11978#endif /* IAXTESTS */
11979 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11980 } else {
11981 /* A mini frame */
11983 if (iaxs[fr->callno]->voiceformat > 0) {
11985 if (!f.subclass.format) {
11986 ast_variables_destroy(ies.vars);
11988 return 1;
11989 }
11990 } else {
11991 ast_debug(1, "Received mini frame before first full voice frame\n");
11992 iax2_vnak(fr->callno);
11993 ast_variables_destroy(ies.vars);
11995 return 1;
11996 }
11997 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11998 if (f.datalen < 0) {
11999 ast_log(LOG_WARNING, "Datalen < 0?\n");
12000 ast_variables_destroy(ies.vars);
12002 return 1;
12003 }
12004 if (f.datalen)
12005 f.data.ptr = thread->buf + sizeof(*mh);
12006 else
12007 f.data.ptr = NULL;
12008#ifdef IAXTESTS
12009 if (test_resync) {
12010 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
12011 } else
12012#endif /* IAXTESTS */
12013 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
12014 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
12015 }
12016
12017 /* Don't pass any packets until we're started */
12018 if (!iaxs[fr->callno]
12020 ast_variables_destroy(ies.vars);
12022 return 1;
12023 }
12024
12025 if (f.frametype == AST_FRAME_CONTROL) {
12027 /* Control frame not allowed to come from the wire. */
12028 ast_debug(2, "Callno %d: Blocked receiving control frame %d.\n",
12029 fr->callno, f.subclass.integer);
12030 ast_variables_destroy(ies.vars);
12032 return 1;
12033 }
12036 if (iaxs[fr->callno]
12038 /* We are not configured to allow receiving these updates. */
12039 ast_debug(2, "Callno %d: Config blocked receiving control frame %d.\n",
12040 fr->callno, f.subclass.integer);
12041 ast_variables_destroy(ies.vars);
12043 return 1;
12044 }
12045 }
12046
12048 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
12051 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
12053 }
12055 }
12056 }
12057
12060 && iaxs[fr->callno]) {
12062
12063 /*
12064 * Process a received connected line update.
12065 *
12066 * Initialize defaults.
12067 */
12069 connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
12070 connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
12071
12073 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
12074 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
12076
12078 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
12080 S_COR(connected.id.number.valid, connected.id.number.str, ""),
12081 S_COR(connected.id.name.valid, connected.id.name.str, ""),
12082 NULL);
12083 ast_channel_caller(iaxs[fr->callno]->owner)->id.number.presentation = connected.id.number.presentation;
12084 ast_channel_caller(iaxs[fr->callno]->owner)->id.name.presentation = connected.id.name.presentation;
12086 }
12087 }
12089 }
12090
12091 /* Common things */
12092 f.src = "IAX2";
12093 f.mallocd = 0;
12094 f.offset = 0;
12095 f.len = 0;
12096 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
12098 /* We need to byteswap incoming slinear samples from network byte order */
12101 } else
12102 f.samples = 0;
12103 iax_frame_wrap(fr, &f);
12104
12105 /* If this is our most recent packet, use it as our basis for timestamping */
12106 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
12107 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
12108 fr->outoforder = 0;
12109 } else {
12110 if (iaxdebug && iaxs[fr->callno]) {
12111 ast_debug(1, "Received out of order packet... (type=%u, subclass %d, ts = %u, last = %u)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last);
12112 }
12113 fr->outoforder = 1;
12114 }
12116 if (iaxs[fr->callno]) {
12117 duped_fr = iaxfrdup2(fr);
12118 if (duped_fr) {
12119 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
12120 }
12121 }
12122 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
12123 iaxs[fr->callno]->last = fr->ts;
12124#if 1
12125 if (iaxdebug)
12126 ast_debug(8, "For call=%d, set last=%u\n", fr->callno, fr->ts);
12127#endif
12128 }
12129
12130 /* Always run again */
12131 ast_variables_destroy(ies.vars);
12133 return 1;
12134}
enum ast_transfer_result ast_bridge_transfer_blind(int is_external, struct ast_channel *transferer, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
Blind transfer target to the extension and context provided.
Definition: bridge.c:4425
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1100
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:100
#define AST_CAUSE_BUSY
Definition: causes.h:149
static int check_access(int callno, struct ast_sockaddr *addr, struct iax_ies *ies)
Definition: chan_iax2.c:7887
static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
Definition: chan_iax2.c:9770
static int update_registry(struct ast_sockaddr *addr, int callno, char *devtype, int fd, unsigned short refresh)
Definition: chan_iax2.c:9144
#define AUTH_METHOD_NAMES_BUFSIZE
Definition: chan_iax2.c:407
static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct ast_sockaddr *addr, int sockfd, struct iax_frame *fr)
Definition: chan_iax2.c:9993
static int iax2_queue_hold(int callno, const char *musicclass)
Queue a hold frame on the ast_channel owner.
Definition: chan_iax2.c:3323
static int check_provisioning(struct ast_sockaddr *addr, int sockfd, char *si, unsigned int ver)
Definition: chan_iax2.c:9741
static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int)
Definition: chan_iax2.c:7871
static int auth_fail(int callno, int failcode)
Definition: chan_iax2.c:9458
static const char * auth_method_labels[]
Name of effective auth method.
Definition: chan_iax2.c:399
static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
Definition: chan_iax2.c:4868
static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct ast_sockaddr *addr, int fd)
Definition: chan_iax2.c:4990
static void vnak_retransmit(int callno, int last)
Definition: chan_iax2.c:9520
static int registry_rerequest(struct iax_ies *ies, int callno, struct ast_sockaddr *addr)
Definition: chan_iax2.c:9370
static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
Definition: chan_iax2.c:9754
static int complete_transfer(int callno, struct iax_ies *ies)
Definition: chan_iax2.c:8791
static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
Definition: chan_iax2.c:4276
static void iax_pvt_callid_new(int callno)
Definition: chan_iax2.c:1185
static int iax2_queue_unhold(int callno)
Queue an unhold frame on the ast_channel owner.
Definition: chan_iax2.c:3346
static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
Definition: chan_iax2.c:8710
static int authenticate_reply(struct chan_iax2_pvt *p, struct ast_sockaddr *addr, struct iax_ies *ies, const char *override, const char *okey)
Definition: chan_iax2.c:8543
static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
Definition: chan_iax2.c:8744
static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
Definition: chan_iax2.c:9723
static struct iax_frame * iaxfrdup2(struct iax_frame *fr)
Definition: chan_iax2.c:2333
static void set_hangup_source_and_cause(int callno, unsigned char causecode)
Definition: chan_iax2.c:10204
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....
Definition: chan_iax2.c:2205
static int authenticate_request(int call_num)
Definition: chan_iax2.c:8157
static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
Definition: chan_iax2.c:9781
static iax2_format iax2_codec_choose(struct iax2_codec_pref *pref, iax2_format formats)
Definition: chan_iax2.c:1928
static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
Definition: chan_iax2.c:6615
static char * auth_method_names(int authmethods, char *restrict buf)
Get names of all auth methods.
Definition: chan_iax2.c:415
static int raw_hangup(struct ast_sockaddr *addr, unsigned short src, unsigned short dst, int sockfd)
Definition: chan_iax2.c:8120
static int iax2_ack_registry(struct iax_ies *ies, struct ast_sockaddr *addr, int callno)
Acknowledgment received for OUR registration.
Definition: chan_iax2.c:8858
static int iax2_vnak(int callno)
Definition: chan_iax2.c:9515
static int registry_authrequest(int callno)
Definition: chan_iax2.c:9322
#define IAX_DELAYPBXSTART
Definition: chan_iax2.c:522
static void stop_stuff(int callno)
Definition: chan_iax2.c:9419
static void log_jitterstats(unsigned short callno)
Definition: chan_iax2.c:9811
static ast_callid iax_pvt_callid_get(int callno)
Definition: chan_iax2.c:1175
static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
Definition: chan_iax2.c:8208
static int register_verify(int callno, struct ast_sockaddr *addr, struct iax_ies *ies)
Verify inbound registration.
Definition: chan_iax2.c:8303
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2072
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
Definition: channel.c:7334
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5762
int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
Parse connected line indication frame data.
Definition: channel.c:8785
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel.
Definition: channel.c:4346
#define AST_CHANNEL_NAME
Definition: channel.h:171
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5803
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
uint64_t iax2_format_compatibility_best(uint64_t formats)
Pick the best format from the given bitfield formats.
@ AST_STATE_RING
Definition: channelstate.h:40
@ AST_DEVICE_NOT_INUSE
Definition: devicestate.h:54
char connected
Definition: eagi_proxy.c:82
@ AST_ENDPOINT_ONLINE
Definition: endpoints.h:57
int iax_firmware_append(struct iax_ie_data *ied, const char *dev, unsigned int desc)
Definition: firmware.c:283
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
static int exists(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_logic.c:157
@ IAX_COMMAND_TXREL
Definition: iax2.h:91
@ IAX_COMMAND_TXMEDIA
Definition: iax2.h:115
@ IAX_COMMAND_FWDATA
Definition: iax2.h:113
@ IAX_COMMAND_PONG
Definition: iax2.h:54
@ IAX_COMMAND_TXREADY
Definition: iax2.h:89
@ IAX_COMMAND_TXACC
Definition: iax2.h:87
@ IAX_COMMAND_QUELCH
Definition: iax2.h:95
@ IAX_COMMAND_LAGRP
Definition: iax2.h:63
@ IAX_COMMAND_TXCNT
Definition: iax2.h:85
@ IAX_COMMAND_REGACK
Definition: iax2.h:69
@ IAX_COMMAND_DIAL
Definition: iax2.h:81
@ IAX_COMMAND_ACCEPT
Definition: iax2.h:58
@ IAX_COMMAND_UNSUPPORT
Definition: iax2.h:105
@ IAX_COMMAND_UNQUELCH
Definition: iax2.h:97
@ IAX_COMMAND_TXREQ
Definition: iax2.h:83
#define IAX_IE_IAX_UNKNOWN
Definition: iax2.h:153
#define IAX_IE_CALLNO
Definition: iax2.h:151
#define ast_frame_byteswap_be(fr)
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
Definition: logger.c:2308
#define VERBOSE_PREFIX_4
AST_JSON_INT_T ast_json_int_t
Primarily used to cast when packing to an "I" type.
Definition: json.h:87
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:429
int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
Definition: parser.c:795
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
char chan_name[AST_CHANNEL_NAME]
Connected Line/Party information.
Definition: channel.h:456
int frames_received
Definition: chan_iax2.c:929
const ast_string_field outkey
Definition: chan_iax2.c:861
struct chan_iax2_pvt::@122 dpentries
const ast_string_field mohsuggest
Definition: chan_iax2.c:861
unsigned short bridgecallno
Definition: chan_iax2.c:904
iax2_format chosenformat
Definition: chan_iax2.c:790
unsigned int outoforder
Definition: parser.h:114
Definition: parser.h:27

References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, ao2_cleanup, ao2_ref, chan_iax2_pvt::aseqno, ast_aes_set_decrypt_key(), ast_alloca, ast_bridge_transfer_blind(), AST_BRIDGE_TRANSFER_SUCCESS, ast_callid_threadassoc_add(), ast_calloc, ast_control_pvt_cause_code::ast_cause, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_channel_caller(), ast_channel_datastore_add(), ast_channel_hangupcause_hash_set(), ast_channel_hangupcause_set(), AST_CHANNEL_NAME, ast_channel_name(), ast_channel_nativeformats(), ast_channel_nativeformats_set(), ast_channel_readformat(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_channel_writeformat(), ast_clear_flag, ast_clear_flag64, ast_codec_samples_count(), ast_connected_line_parse_data(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_REDIRECTING, ast_copy_string(), ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_endpoint_blob_publish(), AST_ENDPOINT_ONLINE, ast_endpoint_set_state(), ast_endpoint_state_type(), ast_exists_extension(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_compatibility_bitfield2format(), ast_format_compatibility_format2bitfield(), ast_format_get_name(), ast_format_slin, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_free, ast_iax2_new(), ast_json_pack(), ast_json_unref(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_id_presentation(), ast_queue_control_data(), AST_SCHED_DEL, ast_set_callerid(), ast_set_flag, ast_set_flag64, ast_set_read_format(), ast_set_write_format(), ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_setnull(), ast_sockaddr_stringify(), AST_STATE_RING, ast_str_alloca, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_var_assign, ast_variables_destroy(), ast_verb, auth_fail(), auth_method_labels, auth_method_names(), AUTH_METHOD_NAMES_BUFSIZE, authdebug, authenticate_reply(), authenticate_request(), authenticate_verify(), chan_iax2_pvt::authmethods, chan_iax2_pvt::bridgecallno, iax_ie_data::buf, c, CACHE_FLAG_TRANSMITTED, iax_frame::cacheable, calc_timestamp(), iax_ies::called_number, chan_iax2_pvt::calling_pres, iax2_peer::callno, chan_iax2_pvt::callno, iax_frame::callno, iax_ies::calltoken, iax_ies::calltokendata, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, ast_control_pvt_cause_code::chan_name, check_access(), check_provisioning(), chan_iax2_pvt::chosenformat, chan_iax2_pvt::cid_num, ast_control_pvt_cause_code::code, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), connected, construct_rr(), chan_iax2_pvt::context, voicemailpwcheck::context, ast_iax2_full_hdr::csub, ast_datastore::data, ast_frame::data, ast_frame::datalen, DATASTORE_INHERIT_FOREVER, ast_iax2_full_hdr::dcallno, chan_iax2_pvt::dcx, DEADLOCK_AVOIDANCE, decrypt_frame(), delayreject, iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::dpentries, chan_iax2_pvt::eff_auth_method, chan_iax2_pvt::encmethods, iax_ies::encmethods, iax2_peer::endpoint, ast_var_t::entries, chan_iax2_pvt::error, exists(), chan_iax2_pvt::exten, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, ast_frame_subclass::format, ast_frame_subclass::frame_ending, frame_queue, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, globalflags, handle_call_token(), iax2_peer::historicms, chan_iax2_pvt::hold_signaling, iax2_ack_registry(), iax2_allow_new(), iax2_codec_choose(), iax2_codec_pref_best_bitfield2cap(), iax2_codec_pref_convert(), iax2_codec_pref_index(), iax2_codec_pref_string(), iax2_destroy(), iax2_dprequest(), iax2_format_compatibility_best(), iax2_format_compatibility_cap2bitfield(), iax2_getformatname(), iax2_getformatname_multiple(), iax2_is_control_frame_allowed(), iax2_lock_owner(), iax2_poke_peer_s(), iax2_publish_registry(), iax2_queue_frame(), iax2_queue_hold(), iax2_queue_unhold(), iax2_sched_add(), iax2_send(), iax2_variable_datastore_info, iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_CALLENCRYPTED, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_RTKEY, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DEBUGDIGEST, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, IAX_FORCE_ENCRYPT, iax_frame_subclass2str(), iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_IAX_UNKNOWN, IAX_IMMEDIATE, iax_outputframe(), iax_parse_ies(), IAX_PROVISION, iax_pvt_callid_get(), iax_pvt_callid_new(), IAX_QUELCH, IAX_RECVCONNECTEDLINE, IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxcompat, iaxdebug, iaxfrdup2(), iaxs, iaxsl, chan_iax2_pvt::iaxvars, ast_party_caller::id, ast_datastore::inheritance, chan_iax2_pvt::initid, chan_iax2_pvt::inkeys, ast_frame_subclass::integer, chan_iax2_pvt::iseqno, ast_iax2_full_hdr::iseqno, iax_frame::iseqno, chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, ast_frame::len, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, iax2_peer::maxms, merge_encryption(), env::meta, chan_iax2_pvt::mohsuggest, iax_ies::musiconhold, iax2_peer::name, ast_party_id::name, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, NULL, ast_party_id::number, ast_frame::offset, chan_iax2_pvt::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::oseqno, chan_iax2_pvt::outkey, iax_frame::outoforder, chan_iax2_pvt::owner, peer_ref(), peer_unref(), chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, ast_party_name::presentation, ast_party_number::presentation, iax_ies::provver, iax_ies::provverpres, ast_frame::ptr, RAII_VAR, raw_hangup(), iax_ies::refresh, chan_iax2_pvt::reg, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), iax2_registry::regstate, remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rprefs, chan_iax2_pvt::rseqno, S_COR, S_OR, ast_frame::samples, save_osptoken(), save_rr(), ast_iax2_full_hdr::scallno, schedule_delivery(), chan_iax2_pvt::secret, send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), send_signaling(), iax_ies::serviceident, set_hangup_source_and_cause(), iax2_peer::smoothing, socket_process_meta(), spawn_dp_lookup(), ast_frame::src, chan_iax2_pvt::state, stop_stuff(), store_by_peercallno(), ast_frame::subclass, thread, chan_iax2_pvt::transfer, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MEDIAPASS, TRANSFER_MREADY, TRANSFER_NONE, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, uncompress_subclass(), update_registry(), iax2_registry::username, chan_iax2_pvt::username, iax_ies::username, var, iax_ies::vars, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), and chan_iax2_pvt::voiceformat.

Referenced by socket_process().

◆ socket_process_meta()

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

Definition at line 9993 of file chan_iax2.c.

9995{
9996 unsigned char metatype;
9997 struct ast_iax2_meta_trunk_mini *mtm;
9998 struct ast_iax2_meta_trunk_hdr *mth;
9999 struct ast_iax2_meta_trunk_entry *mte;
10000 struct iax2_trunk_peer *tpeer;
10001 unsigned int ts;
10002 void *ptr;
10003 struct timeval rxtrunktime;
10004 struct ast_frame f = { 0, };
10005
10006 if (packet_len < sizeof(*meta)) {
10007 ast_log(LOG_WARNING, "Rejecting packet from '%s' that is flagged as a meta frame but is too short\n",
10009 return 1;
10010 }
10011
10012 if (meta->metacmd != IAX_META_TRUNK)
10013 return 1;
10014
10015 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
10016 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
10017 (int) (sizeof(*meta) + sizeof(*mth)));
10018 return 1;
10019 }
10020 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
10021 ts = ntohl(mth->ts);
10022 metatype = meta->cmddata;
10023 packet_len -= (sizeof(*meta) + sizeof(*mth));
10024 ptr = mth->data;
10025 tpeer = find_tpeer(addr, sockfd);
10026 if (!tpeer) {
10027 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s': No matching peer\n",
10029 return 1;
10030 }
10031 tpeer->trunkact = ast_tvnow();
10032 if (!ts || ast_tvzero(tpeer->rxtrunktime))
10033 tpeer->rxtrunktime = tpeer->trunkact;
10034 rxtrunktime = tpeer->rxtrunktime;
10035 ast_mutex_unlock(&tpeer->lock);
10036 while (packet_len >= sizeof(*mte)) {
10037 /* Process channels */
10038 unsigned short callno, trunked_ts, len;
10039
10040 if (metatype == IAX_META_TRUNK_MINI) {
10041 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
10042 ptr += sizeof(*mtm);
10043 packet_len -= sizeof(*mtm);
10044 len = ntohs(mtm->len);
10045 callno = ntohs(mtm->mini.callno);
10046 trunked_ts = ntohs(mtm->mini.ts);
10047 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
10048 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
10049 ptr += sizeof(*mte);
10050 packet_len -= sizeof(*mte);
10051 len = ntohs(mte->len);
10052 callno = ntohs(mte->callno);
10053 trunked_ts = 0;
10054 } else {
10055 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s': dropping\n", ast_sockaddr_stringify(addr));
10056 break;
10057 }
10058 /* Stop if we don't have enough data */
10059 if (len > packet_len)
10060 break;
10061 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, addr, NEW_PREVENT, sockfd, 0);
10062 if (!fr->callno)
10063 continue;
10064
10065 /* If it's a valid call, deliver the contents. If not, we
10066 drop it, since we don't have a scallno to use for an INVAL */
10067 /* Process as a mini frame */
10068 memset(&f, 0, sizeof(f));
10070 if (!iaxs[fr->callno]) {
10071 /* drop it */
10072 } else if (iaxs[fr->callno]->voiceformat == 0) {
10073 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
10074 iax2_vnak(fr->callno);
10076 iaxs[fr->callno]->voiceformat))) {
10077 f.datalen = len;
10078 if (f.datalen >= 0) {
10079 if (f.datalen)
10080 f.data.ptr = ptr;
10081 else
10082 f.data.ptr = NULL;
10083 if (trunked_ts)
10084 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
10085 else
10086 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
10087 /* Don't pass any packets until we're started */
10089 struct iax_frame *duped_fr;
10090
10091 /* Common things */
10092 f.src = "IAX2";
10093 f.mallocd = 0;
10094 f.offset = 0;
10095 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
10097 else
10098 f.samples = 0;
10099 fr->outoforder = 0;
10100 iax_frame_wrap(fr, &f);
10101 duped_fr = iaxfrdup2(fr);
10102 if (duped_fr)
10103 schedule_delivery(duped_fr, 1, 1, &fr->ts);
10104 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
10105 iaxs[fr->callno]->last = fr->ts;
10106 }
10107 } else {
10108 ast_log(LOG_WARNING, "Datalen < 0?\n");
10109 }
10110 }
10112 ptr += len;
10113 packet_len -= len;
10114 }
10115
10116 return 1;
10117}
static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
Definition: chan_iax2.c:6134
unsigned char data[0]
Definition: iax2.h:279
struct timeval rxtrunktime
Definition: chan_iax2.c:645

References ast_codec_samples_count(), ast_format_compatibility_bitfield2format(), AST_FRAME_VOICE, ast_log, ast_mutex_unlock, ast_sockaddr_stringify(), ast_test_flag, ast_tvnow(), ast_tvzero(), ast_iax2_mini_hdr::callno, ast_iax2_meta_trunk_entry::callno, iax_frame::callno, ast_iax2_meta_trunk_hdr::data, ast_frame::data, ast_frame::datalen, find_callno_locked(), find_tpeer(), fix_peerts(), ast_frame_subclass::format, ast_frame::frametype, iax2_vnak(), IAX_FLAG_FULL, iax_frame_wrap(), IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_STATE_STARTED, iaxfrdup2(), iaxs, iaxsl, chan_iax2_pvt::last, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, len(), iax2_trunk_peer::lock, LOG_WARNING, ast_frame::mallocd, env::meta, ast_iax2_meta_trunk_mini::mini, NEW_PREVENT, NULL, ast_frame::offset, iax_frame::outoforder, ast_frame::ptr, iax2_trunk_peer::rxtrunktime, ast_frame::samples, schedule_delivery(), ast_frame::src, chan_iax2_pvt::state, ast_frame::subclass, iax2_trunk_peer::trunkact, ast_iax2_mini_hdr::ts, ast_iax2_meta_trunk_hdr::ts, iax_frame::ts, and chan_iax2_pvt::voiceformat.

Referenced by socket_process_helper().

◆ socket_read()

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

Definition at line 9915 of file chan_iax2.c.

9916{
9917 struct iax2_thread *thread;
9918 time_t t;
9919 static time_t last_errtime = 0;
9920 struct ast_iax2_full_hdr *fh;
9921
9922 if (!(thread = find_idle_thread())) {
9923 time(&t);
9924 if (t != last_errtime) {
9925 last_errtime = t;
9926 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
9927 }
9928 usleep(1);
9929 return 1;
9930 }
9931
9932 thread->iofd = fd;
9933 thread->buf_len = ast_recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, &thread->ioaddr);
9934 thread->buf_size = sizeof(thread->readbuf);
9935 thread->buf = thread->readbuf;
9936 if (thread->buf_len < 0) {
9937 if (errno != ECONNREFUSED && errno != EAGAIN)
9938 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
9939 handle_error();
9940 thread->iostate = IAX_IOSTATE_IDLE;
9941 signal_condition(&thread->lock, &thread->cond);
9942 return 1;
9943 }
9944 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
9945 thread->iostate = IAX_IOSTATE_IDLE;
9946 signal_condition(&thread->lock, &thread->cond);
9947 return 1;
9948 }
9949
9950 /* Determine if this frame is a full frame; if so, and any thread is currently
9951 processing a full frame for the same callno from this peer, then drop this
9952 frame (and the peer will retransmit it) */
9953 fh = (struct ast_iax2_full_hdr *) thread->buf;
9954 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
9955 struct iax2_thread *cur = NULL;
9956 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
9957
9960 if ((cur->ffinfo.callno == callno) &&
9961 !ast_sockaddr_cmp_addr(&cur->ffinfo.addr, &thread->ioaddr))
9962 break;
9963 }
9964 if (cur) {
9965 /* we found another thread processing a full frame for this call,
9966 so queue it up for processing later. */
9969 thread->iostate = IAX_IOSTATE_IDLE;
9970 signal_condition(&thread->lock, &thread->cond);
9971 return 1;
9972 } else {
9973 /* this thread is going to process this frame, so mark it */
9974 thread->ffinfo.callno = callno;
9975 ast_sockaddr_copy(&thread->ffinfo.addr, &thread->ioaddr);
9976 thread->ffinfo.type = fh->type;
9977 thread->ffinfo.csub = fh->csub;
9979 }
9981 }
9982
9983 /* Mark as ready and send on its way */
9984 thread->iostate = IAX_IOSTATE_READY;
9985#ifdef DEBUG_SCHED_MULTITHREAD
9986 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
9987#endif
9988 signal_condition(&thread->lock, &thread->cond);
9989
9990 return 1;
9991}
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.
Definition: chan_iax2.c:9884
ssize_t ast_recvfrom(int sockfd, void *buf, size_t len, int flags, struct ast_sockaddr *src_addr)
Wrapper around recvfrom(2) that uses struct ast_sockaddr.
Definition: netsock2.c:606
struct ast_sockaddr addr
Definition: chan_iax2.c:1139
struct iax2_thread::@128 ffinfo
unsigned short callno
Definition: chan_iax2.c:1138

References iax2_thread::addr, ast_copy_string(), ast_debug, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_random(), ast_recvfrom(), ast_sockaddr_cmp_addr(), ast_sockaddr_copy(), iax2_thread::callno, ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, if(), iax2_thread::list, LOG_WARNING, NULL, ast_iax2_full_hdr::scallno, signal_condition(), test_losspct, thread, and ast_iax2_full_hdr::type.

Referenced by peer_set_srcaddr(), and set_config().

◆ spawn_dp_lookup()

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

Definition at line 9723 of file chan_iax2.c.

9724{
9725 pthread_t newthread;
9726 struct dpreq_data *dpr;
9727
9728 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
9729 return;
9730
9731 dpr->callno = callno;
9732 ast_copy_string(dpr->context, context, sizeof(dpr->context));
9733 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
9734 if (callerid)
9736 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
9737 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
9738 }
9739}
static void * dp_lookup_thread(void *data)
Definition: chan_iax2.c:9712
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:588

References ast_calloc, ast_copy_string(), ast_log, ast_pthread_create_detached, ast_strdup, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, voicemailpwcheck::context, dp_lookup_thread(), LOG_WARNING, and NULL.

Referenced by socket_process_helper().

◆ start_network_thread()

static int start_network_thread ( void  )
static

Definition at line 12768 of file chan_iax2.c.

12769{
12770 struct iax2_thread *thread;
12771 int threadcount = 0;
12772 int x;
12773 for (x = 0; x < iaxthreadcount; x++) {
12774 thread = ast_calloc(1, sizeof(*thread));
12775 if (thread) {
12777 thread->threadnum = ++threadcount;
12778 ast_mutex_init(&thread->lock);
12779 ast_cond_init(&thread->cond, NULL);
12780 ast_mutex_init(&thread->init_lock);
12781 ast_cond_init(&thread->init_cond, NULL);
12782
12783 ast_mutex_lock(&thread->init_lock);
12784
12786 ast_log(LOG_WARNING, "Failed to create new thread!\n");
12787 ast_mutex_destroy(&thread->lock);
12788 ast_cond_destroy(&thread->cond);
12789 ast_mutex_unlock(&thread->init_lock);
12790 ast_mutex_destroy(&thread->init_lock);
12791 ast_cond_destroy(&thread->init_cond);
12793 thread = NULL;
12794 continue;
12795 }
12796 /* Wait for the thread to be ready */
12797 ast_cond_wait(&thread->init_cond, &thread->init_lock);
12798
12799 /* Done with init_lock */
12800 ast_mutex_unlock(&thread->init_lock);
12801
12805 }
12806 }
12808 ast_log(LOG_ERROR, "Failed to create new thread!\n");
12809 return -1;
12810 }
12811 ast_verb(2, "%d helper threads started\n", threadcount);
12812 return 0;
12813}
static void * network_thread(void *ignore)
Definition: chan_iax2.c:12743

References ast_calloc, ast_cond_destroy, ast_cond_init, ast_cond_wait, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, ast_verb, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, iax2_thread::list, LOG_ERROR, LOG_WARNING, netthreadid, network_thread(), NULL, and thread.

Referenced by load_module().

◆ stop_stuff()

static void stop_stuff ( int  callno)
static

Definition at line 9419 of file chan_iax2.c.

9420{
9421 iax2_destroy_helper(iaxs[callno]);
9422}

References iax2_destroy_helper(), and iaxs.

Referenced by socket_process_helper().

◆ store_by_peercallno()

static void store_by_peercallno ( struct chan_iax2_pvt pvt)
static

Definition at line 2465 of file chan_iax2.c.

2466{
2467 if (!pvt->peercallno) {
2468 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
2469 return;
2470 }
2471
2473}

References ao2_link, ast_log, iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.

Referenced by __find_callno(), complete_transfer(), and socket_process_helper().

◆ store_by_transfercallno()

static void store_by_transfercallno ( struct chan_iax2_pvt pvt)
static

Definition at line 2446 of file chan_iax2.c.

2447{
2448 if (!pvt->transfercallno) {
2449 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
2450 return;
2451 }
2452
2454}

References ao2_link, ast_log, iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.

Referenced by try_transfer().

◆ timing_read()

static int timing_read ( int *  id,
int  fd,
short  events,
void *  cbdata 
)
static

Definition at line 9602 of file chan_iax2.c.

9603{
9604 int res, processed = 0, totalcalls = 0;
9605 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
9606 struct timeval now = ast_tvnow();
9607
9608 if (iaxtrunkdebug) {
9609 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
9610 }
9611
9612 if (timer) {
9613 if (ast_timer_ack(timer, 1) < 0) {
9614 ast_log(LOG_ERROR, "Timer failed acknowledge\n");
9615 return 0;
9616 }
9617 }
9618
9619 /* For each peer that supports trunking... */
9621 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
9622 processed++;
9623 res = 0;
9624 ast_mutex_lock(&tpeer->lock);
9625 /* We can drop a single tpeer per pass. That makes all this logic
9626 substantially easier */
9627 if (!drop && iax2_trunk_expired(tpeer, &now)) {
9628 /* Take it out of the list, but don't free it yet, because it
9629 could be in use */
9631 drop = tpeer;
9632 } else {
9633 res = send_trunk(tpeer, &now);
9634 trunk_timed++;
9635 if (iaxtrunkdebug) {
9636 ast_verbose(" - Trunk peer (%s) has %d call chunk%s in transit, %u bytes backlogged and has hit a high water mark of %u bytes\n",
9638 res,
9639 (res != 1) ? "s" : "",
9640 tpeer->trunkdatalen,
9641 tpeer->trunkdataalloc);
9642 }
9643 }
9644 totalcalls += res;
9645 res = 0;
9646 ast_mutex_unlock(&tpeer->lock);
9647 }
9650
9651 if (drop) {
9652 ast_mutex_lock(&drop->lock);
9653 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it,
9654 because by the time they could get tpeerlock, we've already grabbed it */
9655 ast_debug(1, "Dropping unused iax2 trunk peer '%s'\n", ast_sockaddr_stringify(&drop->addr));
9656 if (drop->trunkdata) {
9657 ast_free(drop->trunkdata);
9658 drop->trunkdata = NULL;
9659 }
9660 ast_mutex_unlock(&drop->lock);
9661 ast_mutex_destroy(&drop->lock);
9662 ast_free(drop);
9663 }
9664
9665 if (iaxtrunkdebug) {
9666 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
9667 }
9668 iaxtrunkdebug = 0;
9669
9670 return 1;
9671}
static int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
Definition: chan_iax2.c:9594
static int totalcalls
Definition: pbx.c:779
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
Definition: timing.c:171

References iax2_trunk_peer::addr, ast_debug, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_stringify(), ast_timer_ack(), ast_tvnow(), ast_verbose(), iax2_trunk_expired(), iaxtrunkdebug, iax2_trunk_peer::lock, LOG_ERROR, NULL, send_trunk(), timer, totalcalls, trunk_timed, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, and trunkmaxsize.

Referenced by network_thread().

◆ transfercallno_pvt_cmp_cb()

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

Definition at line 14886 of file chan_iax2.c.

14887{
14888 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14889
14890 /* The frames_received field is used to hold whether we're matching
14891 * against a full frame or not ... */
14892
14893 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14894 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14895}

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

Referenced by load_objects().

◆ transfercallno_pvt_hash_cb()

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

Definition at line 14879 of file chan_iax2.c.

14880{
14881 const struct chan_iax2_pvt *pvt = obj;
14882
14883 return pvt->transfercallno;
14884}

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

◆ transmit_frame()

static int transmit_frame ( void *  data)
static

Definition at line 4340 of file chan_iax2.c.

4341{
4342 struct iax_frame *fr = data;
4343
4345
4346 fr->sentyet = 1;
4347
4348 if (iaxs[fr->callno]) {
4349 send_packet(fr);
4350 }
4351
4352 if (fr->retries < 0) {
4354 /* No retransmit requested */
4355 iax_frame_free(fr);
4356 } else {
4357 /* We need reliable delivery. Schedule a retransmission */
4359 fr->retries++;
4362 }
4363
4364 return 0;
4365}

References AST_LIST_INSERT_TAIL, ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, iax_frame::data, frame_queue, iax2_sched_add(), iax_frame_free(), iaxs, iaxsl, iax_frame::list, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), and iax_frame::sentyet.

Referenced by iax2_transmit().

◆ transmit_trunk()

static int transmit_trunk ( struct iax_frame f,
struct ast_sockaddr addr,
int  sockfd 
)
static

Definition at line 3436 of file chan_iax2.c.

3437{
3438 int res;
3439 res = ast_sendto(sockfd, f->data, f->datalen, 0, addr);
3440
3441 if (res < 0) {
3442 ast_debug(1, "Received error: %s\n", strerror(errno));
3443 handle_error();
3444 } else
3445 res = 0;
3446 return res;
3447}

References ast_debug, ast_sendto(), iax_frame::data, iax_frame::datalen, errno, and handle_error().

Referenced by send_trunk().

◆ try_transfer()

static int try_transfer ( struct chan_iax2_pvt pvt,
struct iax_ies ies 
)
static

Definition at line 8710 of file chan_iax2.c.

8711{
8712 int newcall = 0;
8713 struct iax_ie_data ied;
8714 struct ast_sockaddr new = { {0,} };
8715
8716 memset(&ied, 0, sizeof(ied));
8717 if (!ast_sockaddr_isnull(&ies->apparent_addr)) {
8718 ast_sockaddr_copy(&new, &ies->apparent_addr);
8719 }
8720 if (ies->callno) {
8721 newcall = ies->callno;
8722 }
8723 if (!newcall || ast_sockaddr_isnull(&new)) {
8724 ast_log(LOG_WARNING, "Invalid transfer request\n");
8725 return -1;
8726 }
8727 pvt->transfercallno = newcall;
8728 ast_sockaddr_copy(&pvt->transfer, &new);
8729 pvt->transferid = ies->transferid;
8730 /* only store by transfercallno if this is a new transfer,
8731 * just in case we get a duplicate TXREQ */
8732 if (pvt->transferring == TRANSFER_NONE) {
8734 }
8736
8737 if (ies->transferid) {
8739 }
8740 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
8741 return 0;
8742}
static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:2446
#define IAX_IE_TRANSFERID
Definition: iax2.h:157
unsigned int transferid
Definition: parser.h:62

References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log, ast_sockaddr_copy(), ast_sockaddr_isnull(), iax_ie_data::buf, iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, LOG_WARNING, iax_ie_data::pos, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferid, iax_ies::transferid, and chan_iax2_pvt::transferring.

Referenced by socket_process_helper().

◆ uncompress_subclass()

static iax2_format uncompress_subclass ( unsigned char  csub)
static

Definition at line 1880 of file chan_iax2.c.

1881{
1882 /* If the SC_LOG flag is set, return 2^csub otherwise csub */
1883 if (csub & IAX_FLAG_SC_LOG) {
1884 /* special case for 'compressed' -1 */
1885 if (csub == 0xff)
1886 return -1;
1887 else
1888 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
1889 }
1890 else
1891 return csub;
1892}

References iax2_thread::csub, IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

Referenced by decode_frame(), handle_call_token(), and socket_process_helper().

◆ unlink_peer()

static void unlink_peer ( struct iax2_peer peer)
static

Definition at line 9021 of file chan_iax2.c.

9022{
9023 if (peer->expire > -1) {
9024 if (!AST_SCHED_DEL(sched, peer->expire)) {
9025 peer->expire = -1;
9026 peer_unref(peer);
9027 }
9028 }
9029
9030 if (peer->pokeexpire > -1) {
9031 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
9032 peer->pokeexpire = -1;
9033 peer_unref(peer);
9034 }
9035 }
9036
9037 ao2_unlink(peers, peer);
9038}

References ao2_unlink, AST_SCHED_DEL, iax2_peer::expire, peer_unref(), and iax2_peer::pokeexpire.

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

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 14844 of file chan_iax2.c.

14845{
14848 return __unload_module();
14849}
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.

References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.

◆ unwrap_timestamp()

static void unwrap_timestamp ( struct iax_frame fr)
static

Definition at line 4120 of file chan_iax2.c.

4121{
4122 /* Video mini frames only encode the lower 15 bits of the session
4123 * timestamp, but other frame types (e.g. audio) encode 16 bits. */
4124 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
4125 const int lower_mask = (1 << ts_shift) - 1;
4126 const int upper_mask = ~lower_mask;
4127 const int last_upper = iaxs[fr->callno]->last & upper_mask;
4128
4129 if ( (fr->ts & upper_mask) == last_upper ) {
4130 const int x = fr->ts - iaxs[fr->callno]->last;
4131 const int threshold = (ts_shift == 15) ? 25000 : 50000;
4132
4133 if (x < -threshold) {
4134 /* Sudden big jump backwards in timestamp:
4135 What likely happened here is that miniframe timestamp has circled but we haven't
4136 gotten the update from the main packet. We'll just pretend that we did, and
4137 update the timestamp appropriately. */
4138 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
4139 if (iaxdebug)
4140 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
4141 } else if (x > threshold) {
4142 /* Sudden apparent big jump forwards in timestamp:
4143 What's likely happened is this is an old miniframe belonging to the previous
4144 top 15 or 16-bit timestamp that has turned up out of order.
4145 Adjust the timestamp appropriately. */
4146 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
4147 if (iaxdebug)
4148 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
4149 }
4150 }
4151}
threshold
Definition: dsp.h:71

References iax_frame::af, ast_debug, AST_FRAME_VIDEO, iax_frame::callno, ast_frame::frametype, iaxdebug, iaxs, chan_iax2_pvt::last, and iax_frame::ts.

Referenced by schedule_delivery().

◆ update_jbsched()

static void update_jbsched ( struct chan_iax2_pvt pvt)
static

Definition at line 4155 of file chan_iax2.c.

4156{
4157 int when;
4158
4159 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
4160
4161 when = jb_next(pvt->jb) - when;
4162
4163 if (when <= 0) {
4164 /* XXX should really just empty until when > 0.. */
4165 when = 1;
4166 }
4167
4168 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
4169 CALLNO_TO_PTR(pvt->callno));
4170}
static int get_from_jb(const void *p)
Definition: chan_iax2.c:4261

References ast_tvdiff_ms(), ast_tvnow(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_replace(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, and chan_iax2_pvt::rxcore.

Referenced by __get_from_jb(), and schedule_delivery().

◆ update_packet()

static int update_packet ( struct iax_frame f)
static

Definition at line 3568 of file chan_iax2.c.

3569{
3570 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
3571 struct ast_iax2_full_hdr *fh = f->data;
3572 struct ast_frame af;
3573
3574 /* if frame is encrypted. decrypt before updating it. */
3575 if (f->encmethods) {
3576 decode_frame(&f->mydcx, fh, &af, &f->datalen);
3577 }
3578 /* Mark this as a retransmission */
3579 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
3580 /* Update iseqno */
3581 f->iseqno = iaxs[f->callno]->iseqno;
3582 fh->iseqno = f->iseqno;
3583
3584 /* Now re-encrypt the frame */
3585 if (f->encmethods) {
3586 /* since this is a retransmit frame, create a new random padding
3587 * before re-encrypting. */
3588 build_rand_pad(f->semirand, sizeof(f->semirand));
3589 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
3590 }
3591 return 0;
3592}

References build_rand_pad(), iax_frame::callno, iax_frame::data, iax_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, decode_frame(), iax_frame::ecx, iax_frame::encmethods, encrypt_frame(), IAX_FLAG_RETRANS, iaxs, chan_iax2_pvt::iseqno, ast_iax2_full_hdr::iseqno, iax_frame::iseqno, iax_frame::mydcx, and iax_frame::semirand.

Referenced by __attempt_transmit().

◆ update_registry()

static int update_registry ( struct ast_sockaddr addr,
int  callno,
char *  devtype,
int  fd,
unsigned short  refresh 
)
static
Precondition
iaxsl[callno] is locked
Note
Since this function calls send_command_final(), the pvt struct for the given call number may disappear while executing this function.

Definition at line 9144 of file chan_iax2.c.

9145{
9146
9147 /* Called from IAX thread only, with proper iaxsl lock */
9148 struct iax_ie_data ied = {
9149 .pos = 0,
9150 };
9151 struct iax2_peer *p;
9152 int msgcount;
9153 char data[80];
9154 uint16_t version;
9155 const char *peer_name;
9156 int res = -1;
9157 char *str_addr;
9158
9159 peer_name = ast_strdupa(iaxs[callno]->peer);
9160
9161 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
9163 if (!(p = find_peer(peer_name, 1))) {
9165 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
9166 return -1;
9167 }
9169 if (!iaxs[callno])
9170 goto return_unref;
9171
9173 if (!ast_sockaddr_isnull(addr)) {
9174 time_t nowtime;
9175 time(&nowtime);
9176 realtime_update_peer(peer_name, addr, nowtime);
9177 } else {
9178 realtime_update_peer(peer_name, addr, 0);
9179 }
9180 }
9181
9182 /* treat an unspecified refresh interval as the minimum */
9183 if (!refresh) {
9185 }
9186 if (refresh > max_reg_expire) {
9187 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
9190 } else if (refresh < min_reg_expire) {
9191 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
9194 } else {
9195 p->expiry = refresh;
9196 }
9197
9198 if (ast_sockaddr_cmp(&p->addr, addr)) {
9199 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
9200
9201 if (iax2_regfunk) {
9202 iax2_regfunk(p->name, 1);
9203 }
9204
9205 /* modify entry in peercnts table as _not_ registered */
9206 peercnt_modify((unsigned char) 0, 0, &p->addr);
9207
9208 /* Stash the IP address from which they registered */
9210
9212
9213 snprintf(data, sizeof(data), "%s:%d", ast_sockaddr_stringify(addr), p->expiry);
9214
9216 ast_db_put("IAX/Registry", p->name, data);
9217 ast_verb(3, "Registered IAX2 '%s' (%s) at %s\n",
9218 p->name,
9219 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED",
9222 blob = ast_json_pack("{s: s, s: s, s: i}",
9223 "peer_status", "Registered",
9224 "address", str_addr,
9225 "port", ast_sockaddr_port(addr));
9226 register_peer_exten(p, 1);
9227 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
9228 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
9229 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n",
9230 p->name,
9231 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
9233 blob = ast_json_pack("{s: s}",
9234 "peer_status", "Unregistered");
9235 register_peer_exten(p, 0);
9236 ast_db_del("IAX/Registry", p->name);
9237 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
9238 }
9239
9241
9242 /* Update the host */
9243 /* Verify that the host is really there */
9245 }
9246
9247 /* modify entry in peercnts table as registered */
9248 if (p->maxcallno) {
9249 peercnt_modify((unsigned char) 1, p->maxcallno, &p->addr);
9250 }
9251
9252 /* Make sure our call still exists, an INVAL at the right point may make it go away */
9253 if (!iaxs[callno]) {
9254 res = -1;
9255 goto return_unref;
9256 }
9257
9258 /* Store socket fd */
9259 p->sockfd = fd;
9260 /* Setup the expiry */
9261 if (p->expire > -1) {
9262 if (!AST_SCHED_DEL(sched, p->expire)) {
9263 p->expire = -1;
9264 peer_unref(p);
9265 }
9266 }
9267
9268 if (p->expiry && !ast_sockaddr_isnull(addr)) {
9269 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
9270 if (p->expire == -1)
9271 peer_unref(p);
9272 }
9275 if (!ast_sockaddr_isnull(addr)) {
9276 struct ast_sockaddr peer_addr;
9277
9278 ast_sockaddr_copy(&peer_addr, &p->addr);
9279
9281 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
9282 if (!ast_strlen_zero(p->mailbox)) {
9283 int new, old;
9284 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
9285
9287 if (msg) {
9288 struct ast_mwi_state *mwi_state = stasis_message_data(msg);
9289 new = mwi_state->new_msgs;
9290 old = mwi_state->old_msgs;
9291 } else { /* Fall back on checking the mailbox directly */
9292 ast_app_inboxcount(p->mailbox, &new, &old);
9293 }
9294
9295 if (new > 255) {
9296 new = 255;
9297 }
9298 if (old > 255) {
9299 old = 255;
9300 }
9301 msgcount = (old << 8) | new;
9302
9303 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
9304 }
9308 }
9309 }
9310 if (iax_firmware_get_version(devtype, &version)) {
9312 }
9313
9314 res = 0;
9315
9316return_unref:
9317 peer_unref(p);
9318
9319 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
9320}
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: main/db.c:342
int iax_firmware_get_version(const char *dev, uint16_t *version)
Definition: firmware.c:263
#define IAX_IE_MSGCOUNT
Definition: iax2.h:154
#define IAX_IE_FIRMWAREVER
Definition: iax2.h:164
#define IAX_IE_APPARENT_ADDR
Definition: iax2.h:148
int ast_app_inboxcount(const char *mailboxes, int *newmsgs, int *oldmsgs)
Determine number of new/old messages in a mailbox.
Definition: main/app.c:604
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
struct stasis_cache * ast_mwi_state_cache(void)
Backend cache for ast_mwi_topic_cached().
Definition: mwi.c:94
int iax_ie_append_addr(struct iax_ie_data *ied, unsigned char ie, const struct ast_sockaddr *addr)
Definition: parser.c:741
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_message * stasis_cache_get(struct stasis_cache *cache, struct stasis_message_type *type, const char *id)
Retrieve an item from the cache for the ast_eid_default entity.
Definition: stasis_cache.c:686
The structure that contains MWI state.
Definition: mwi.h:455
int old_msgs
Definition: mwi.h:460
int new_msgs
Definition: mwi.h:459

References iax2_peer::addr, ao2_cleanup, ast_app_inboxcount(), ast_db_del(), ast_db_put(), AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_endpoint_blob_publish(), AST_ENDPOINT_OFFLINE, AST_ENDPOINT_ONLINE, ast_endpoint_set_state(), ast_endpoint_state_type(), AST_FRAME_IAX, ast_json_pack(), ast_json_unref(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_mwi_state_cache(), ast_mwi_state_type(), AST_SCHED_DEL, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_verb, iax_ie_data::buf, iax2_peer::callno, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::endpoint, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_COMMAND_REGACK, iax_firmware_get_version(), IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, iaxsl, LOG_NOTICE, LOG_WARNING, iax2_peer::mailbox, max_reg_expire, iax2_peer::maxcallno, min_reg_expire, iax2_peer::name, ast_mwi_state::new_msgs, NULL, ast_mwi_state::old_msgs, peer_ref(), peer_unref(), peercnt_modify(), iax_ie_data::pos, RAII_VAR, realtime_update_peer(), refresh, register_peer_exten(), send_command_final(), iax2_peer::sockfd, stasis_cache_get(), stasis_message_data(), version, and iax2_peer::zonetag.

Referenced by socket_process_helper().

◆ user_cmp_cb()

static int user_cmp_cb ( void *  obj,
void *  arg,
int  flags 
)
static
Note
The only member of the user passed here guaranteed to be set is the name field

Definition at line 2043 of file chan_iax2.c.

2044{
2045 struct iax2_user *user = obj, *user2 = arg;
2046 const char *name = arg;
2047
2048 return !strcmp(user->name, flags & OBJ_KEY ? name : user2->name) ?
2049 CMP_MATCH | CMP_STOP : 0;
2050}
uint64_t flags
Definition: chan_iax2.c:567

References CMP_MATCH, CMP_STOP, iax2_user::flags, name, and OBJ_KEY.

Referenced by load_objects().

◆ user_delme_cb()

static int user_delme_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 13560 of file chan_iax2.c.

13561{
13562 struct iax2_user *user = obj;
13563
13565
13566 return 0;
13567}

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

◆ user_destructor()

static void user_destructor ( void *  obj)
static

Definition at line 13275 of file chan_iax2.c.

13276{
13277 struct iax2_user *user = obj;
13278
13279 ast_free_acl_list(user->acl);
13280 free_context(user->contexts);
13281 if(user->vars) {
13283 user->vars = NULL;
13284 }
13286}

References ast_free_acl_list(), ast_string_field_free_memory, ast_variables_destroy(), free_context(), and NULL.

Referenced by build_user().

◆ user_hash_cb()

static int user_hash_cb ( const void *  obj,
const int  flags 
)
static
Note
The only member of the user passed here guaranteed to be set is the name field

Definition at line 2032 of file chan_iax2.c.

2033{
2034 const struct iax2_user *user = obj;
2035 const char *name = obj;
2036
2037 return ast_str_hash(flags & OBJ_KEY ? name : user->name);
2038}

References ast_str_hash(), iax2_user::flags, name, and OBJ_KEY.

Referenced by load_objects().

◆ user_unref()

static struct iax2_user * user_unref ( struct iax2_user user)
inlinestatic

◆ vnak_retransmit()

static void vnak_retransmit ( int  callno,
int  last 
)
static

Definition at line 9520 of file chan_iax2.c.

9521{
9522 struct iax_frame *f;
9523
9525 /* Send a copy immediately */
9526 if (((unsigned char) (f->oseqno - last) < 128) &&
9527 (f->retries >= 0)) {
9528 send_packet(f);
9529 }
9530 }
9531}
struct iax_frame * last
Definition: chan_iax2.c:980

References AST_LIST_TRAVERSE, iax_frame::callno, frame_queue, last, iax_frame::list, iax_frame::oseqno, iax_frame::retries, and send_packet().

Referenced by socket_process_helper().

◆ wait_for_peercallno()

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

Definition at line 5425 of file chan_iax2.c.

5426{
5427 unsigned short callno = pvt->callno;
5428
5429 if (!pvt->peercallno) {
5430 /* We don't know the remote side's call number, yet. :( */
5431 int count = 10;
5432 while (count-- && pvt && !pvt->peercallno) {
5433 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
5434 pvt = iaxs[callno];
5435 }
5436 if (!pvt || !pvt->peercallno) {
5437 return -1;
5438 }
5439 }
5440
5441 return 0;
5442}

References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, iaxs, iaxsl, and chan_iax2_pvt::peercallno.

Referenced by iax2_indicate(), and iax2_setoption().

Variable Documentation

◆ __mod_info

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, .requires = "dnsmgr", .optional_modules = "res_crypto", }
static

Definition at line 15136 of file chan_iax2.c.

◆ accountcode

char accountcode[AST_MAX_ACCOUNT_CODE]
static

◆ acl_change_sub

struct stasis_subscription* acl_change_sub
static

subscription id for ACL change events

Definition at line 328 of file chan_iax2.c.

Referenced by acl_change_stasis_subscribe(), acl_change_stasis_unsubscribe(), rtp_reload(), and unload_module().

◆ active_list

struct active_list active_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ adsi

int adsi = 0
static

Definition at line 477 of file chan_iax2.c.

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

◆ amaflags

int amaflags = 0
static

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 15136 of file chan_iax2.c.

◆ auth_method_labels

const char* auth_method_labels[]
static

Name of effective auth method.

Definition at line 399 of file chan_iax2.c.

Referenced by socket_process_helper().

◆ authdebug

int authdebug = 0
static

◆ autokill

int autokill = 0
static

Definition at line 346 of file chan_iax2.c.

Referenced by iax2_call(), and set_config().

◆ callno_limits

struct ao2_container* callno_limits
static

Table containing custom callno limit rules for a range of ip addresses.

Definition at line 1009 of file chan_iax2.c.

Referenced by __unload_module(), build_callno_limits(), load_objects(), reload_config(), set_config_destroy(), and set_peercnt_limit().

◆ callno_pool

struct call_number_pool callno_pool
static

table of available call numbers

Definition at line 966 of file chan_iax2.c.

Referenced by create_callno_pools(), get_unused_callno(), handle_cli_iax2_show_callno_limits(), and replace_callno().

◆ callno_pool_lock

ast_mutex_t callno_pool_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 963 of file chan_iax2.c.

Referenced by get_unused_callno(), and replace_callno().

◆ callno_pool_trunk

struct call_number_pool callno_pool_trunk
static

table of available trunk call numbers

Definition at line 969 of file chan_iax2.c.

Referenced by create_callno_pools(), get_unused_callno(), handle_cli_iax2_show_callno_limits(), and replace_callno().

◆ calltoken_ignores

struct ao2_container* calltoken_ignores
static

Table containing ip addresses not requiring calltoken validation

Definition at line 1012 of file chan_iax2.c.

Referenced by __unload_module(), add_calltoken_ignore(), calltoken_required(), load_objects(), reload_config(), and set_config_destroy().

◆ cli_iax2

struct ast_cli_entry cli_iax2[]
static

Definition at line 14715 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

◆ cos

unsigned int cos

◆ debugaddr

struct ast_sockaddr debugaddr
static

Definition at line 1225 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_debug(), iax_outputframe(), and reload_config().

◆ DEFAULT_MAXCALLNO_LIMIT

uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048
static

Definition at line 1014 of file chan_iax2.c.

Referenced by set_config().

◆ DEFAULT_MAXCALLNO_LIMIT_NONVAL

uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192
static

Definition at line 1016 of file chan_iax2.c.

Referenced by set_config().

◆ default_parkinglot

char default_parkinglot[AST_MAX_CONTEXT]
static

Definition at line 322 of file chan_iax2.c.

Referenced by __find_callno(), and set_config().

◆ defaultsockfd

int defaultsockfd = -1
static

◆ delayreject

int delayreject = 0
static

Definition at line 478 of file chan_iax2.c.

Referenced by auth_fail(), set_config(), set_config_destroy(), and socket_process_helper().

◆ dpcache

struct dpcache dpcache = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ dynamic_list

struct dynamic_list dynamic_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ first

struct iax_frame* first

Definition at line 980 of file chan_iax2.c.

◆ 

struct { ... } frame_queue[IAX_MAX_CALLS]

a list of frames that may need to be retransmitted

Note
The contents of this list do not need to be explicitly destroyed on module unload. This is because all active calls are destroyed, and all frames in this queue will get destroyed as a part of that process.
Contents protected by the iaxsl[] locks

Referenced by __attempt_transmit(), complete_transfer(), handle_cli_iax2_show_stats(), pvt_destructor(), resend_with_token(), socket_process_helper(), transmit_frame(), and vnak_retransmit().

◆ global_max_trunk_mtu

int global_max_trunk_mtu
static

Maximum MTU, 0 if not used

Definition at line 317 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_mtu(), handle_cli_iax2_show_stats(), iax2_trunk_queue(), and set_config().

◆ global_maxcallno

uint16_t global_maxcallno
static

Definition at line 1018 of file chan_iax2.c.

Referenced by set_config(), and set_peercnt_limit().

◆ global_maxcallno_nonval

uint16_t global_maxcallno_nonval
static

Total num of call numbers allowed to be allocated without calltoken validation

Definition at line 1021 of file chan_iax2.c.

Referenced by get_unused_callno(), handle_cli_iax2_show_callno_limits(), and set_config().

◆ global_rtautoclear

int global_rtautoclear = 120
static

Definition at line 529 of file chan_iax2.c.

Referenced by realtime_peer(), and set_config().

◆ globalflags

struct ast_flags64 globalflags = { 0 }
static

◆ iax2_authmethods

int iax2_authmethods = 0
static

Definition at line 480 of file chan_iax2.c.

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

◆ iax2_capability

iax2_format iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH
static

Definition at line 459 of file chan_iax2.c.

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

◆ iax2_encryption

int iax2_encryption = 0
static

Definition at line 479 of file chan_iax2.c.

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

◆ iax2_regfunk

int(* iax2_regfunk) (const char *username, int onoff) ( const char *  username,
int  onoff 
) = NULL
static

Definition at line 370 of file chan_iax2.c.

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

◆ iax2_switch

struct ast_switch iax2_switch
static

Definition at line 14705 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

◆ iax2_tech

struct ast_channel_tech iax2_tech
static

◆ iax2_variable_datastore_info

const struct ast_datastore_info iax2_variable_datastore_info
static
Initial value:
= {
.type = "IAX2_VARIABLE",
}
static void * iax2_dup_variable_datastore(void *)
Definition: chan_iax2.c:1575
static void iax2_free_variable_datastore(void *)
Definition: chan_iax2.c:1599

Definition at line 1569 of file chan_iax2.c.

Referenced by acf_iaxvar_read(), acf_iaxvar_write(), ast_iax2_new(), authenticate_reply(), iax2_call(), and socket_process_helper().

◆ iax_peercallno_pvts

struct ao2_container* iax_peercallno_pvts
static

Another container of iax2_pvt structures.

Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.

Definition at line 1202 of file chan_iax2.c.

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_peercallno(), and store_by_peercallno().

◆ iax_transfercallno_pvts

struct ao2_container* iax_transfercallno_pvts
static

Another container of iax2_pvt structures.

Active IAX2 pvt structs used during transfering a call are stored here.

Definition at line 1218 of file chan_iax2.c.

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_transfercallno(), and store_by_transfercallno().

◆ iaxactivethreadcount

int iaxactivethreadcount = 0
static

Definition at line 724 of file chan_iax2.c.

Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().

◆ iaxcompat

int iaxcompat = 0
static

Definition at line 347 of file chan_iax2.c.

Referenced by set_config(), and socket_process_helper().

◆ iaxdebug

int iaxdebug = 0
static

◆ iaxdefaultdpcache

int iaxdefaultdpcache =10 * 60
static

Definition at line 350 of file chan_iax2.c.

Referenced by complete_dpreply(), dp_lookup(), and find_cache().

◆ iaxdefaulttimeout

int iaxdefaulttimeout = 5
static

Definition at line 352 of file chan_iax2.c.

Referenced by find_cache().

◆ iaxdynamicthreadcount

int iaxdynamicthreadcount = 0
static

Definition at line 722 of file chan_iax2.c.

Referenced by find_idle_thread(), and iax2_process_thread().

◆ iaxdynamicthreadnum

int iaxdynamicthreadnum = 0
static

Definition at line 723 of file chan_iax2.c.

Referenced by find_idle_thread().

◆ iaxmaxthreadcount

int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT
static

Definition at line 721 of file chan_iax2.c.

Referenced by find_idle_thread(), and set_config().

◆ iaxpeer_function

struct ast_custom_function iaxpeer_function
static
Initial value:
= {
.name = "IAXPEER",
}
static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: chan_iax2.c:14552

Definition at line 14624 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

◆ iaxs

struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS]
static

an array of iax2 pvt structures

The container for active chan_iax2_pvt structures is implemented as an array for extremely quick direct access to the correct pvt structure based on the local call number. The local call number is used as the index into the array where the associated pvt structure is stored.

Definition at line 1173 of file chan_iax2.c.

Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __find_callno(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), acf_channel_read(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), handle_cli_iax2_show_channels(), iax2_ack_registry(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_lock_callno_unless_destroyed(), iax2_lock_owner(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queryoption(), iax2_queue_frame(), iax2_queue_hangup(), iax2_queue_hold(), iax2_queue_unhold(), iax2_request(), iax2_setoption(), iax2_vnak(), iax2_write(), iax_pvt_callid_get(), iax_pvt_callid_set(), load_module(), log_jitterstats(), make_trunk(), register_verify(), registry_authrequest(), registry_rerequest(), resend_with_token(), save_osptoken(), save_rr(), schedule_delivery(), scheduled_destroy(), send_command_final(), send_command_locked(), send_packet(), set_hangup_source_and_cause(), socket_process_helper(), socket_process_meta(), stop_stuff(), transmit_frame(), unwrap_timestamp(), update_packet(), update_registry(), and wait_for_peercallno().

◆ iaxsl

ast_mutex_t iaxsl[ARRAY_LEN(iaxs)]
static

◆ iaxthreadcount

int iaxthreadcount = DEFAULT_THREAD_COUNT
static

Definition at line 720 of file chan_iax2.c.

Referenced by handle_cli_iax2_show_threads(), set_config(), and start_network_thread().

◆ iaxtrunkdebug

int iaxtrunkdebug = 0
static

Definition at line 463 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_debug_trunk(), and timing_read().

◆ iaxvar_function

struct ast_custom_function iaxvar_function
static
Initial value:
= {
.name = "IAXVAR",
.read = acf_iaxvar_read,
.write = acf_iaxvar_write,
}
static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
Definition: chan_iax2.c:10148
static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: chan_iax2.c:10119

Definition at line 10198 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

◆ idle_list

struct idle_list idle_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ io

struct io_context* io
static

Definition at line 456 of file chan_iax2.c.

Referenced by load_module(), network_thread(), peer_set_srcaddr(), and set_config().

◆ jittertargetextra

int jittertargetextra = 40
static

Definition at line 338 of file chan_iax2.c.

Referenced by new_iax(), and set_config().

◆ lagrq_time

int lagrq_time = 10
static

Definition at line 334 of file chan_iax2.c.

Referenced by __find_callno(), __send_lagrq(), make_trunk(), and set_config().

◆ language

char language[MAX_LANGUAGE] = ""
static

◆ last

struct iax_frame* last

Definition at line 980 of file chan_iax2.c.

Referenced by vnak_retransmit().

◆ last_authmethod

int last_authmethod = 0
static

Definition at line 348 of file chan_iax2.c.

Referenced by check_access(), register_verify(), and registry_authrequest().

◆ max_calltoken_delay

time_t max_calltoken_delay = 10
static

Definition at line 986 of file chan_iax2.c.

Referenced by handle_call_token(), and set_config().

◆ max_reg_expire

int max_reg_expire
static

Definition at line 360 of file chan_iax2.c.

Referenced by set_config(), and update_registry().

◆ max_retries

int max_retries = 4
static

Definition at line 332 of file chan_iax2.c.

Referenced by __attempt_transmit(), and load_module().

◆ maxauthreq

int maxauthreq = 3
static

Definition at line 331 of file chan_iax2.c.

Referenced by build_user(), and set_config().

◆ maxjitterbuffer

int maxjitterbuffer =1000
static

Definition at line 335 of file chan_iax2.c.

Referenced by new_iax(), and set_config().

◆ maxjitterinterps

int maxjitterinterps =10
static

Definition at line 337 of file chan_iax2.c.

Referenced by new_iax(), and set_config().

◆ min_reg_expire

int min_reg_expire
static

◆ mohinterpret

char mohinterpret[MAX_MUSICCLASS]
static

◆ mohsuggest

char mohsuggest[MAX_MUSICCLASS]
static

◆ netsock

struct ast_netsock_list* netsock
static

◆ netthreadid

pthread_t netthreadid = AST_PTHREADT_NULL
static

Definition at line 484 of file chan_iax2.c.

Referenced by __unload_module(), and start_network_thread().

◆ network_change_sched_id

int network_change_sched_id = -1
static

Definition at line 329 of file chan_iax2.c.

Referenced by network_change_sched_cb(), and network_change_stasis_cb().

◆ network_change_sub

struct stasis_subscription* network_change_sub
static

subscription id for network change events

Definition at line 327 of file chan_iax2.c.

Referenced by network_change_stasis_subscribe(), and network_change_stasis_unsubscribe().

◆ outsock

struct ast_netsock_list* outsock
static

used if sourceaddress specified and bindaddr == INADDR_ANY

Definition at line 367 of file chan_iax2.c.

Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().

◆ papp

char* papp = "IAX2Provision"
static

Definition at line 12412 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

◆ peercnts

struct ao2_container* peercnts
static

Table containing peercnt objects for every ip address consuming a callno

Definition at line 1006 of file chan_iax2.c.

Referenced by __unload_module(), handle_cli_iax2_show_callno_limits(), load_objects(), peercnt_add(), peercnt_modify(), peercnt_remove(), peercnt_remove_by_addr(), reload_config(), and sched_delay_remove().

◆ peers

struct ao2_container* peers
static

Definition at line 1000 of file chan_iax2.c.

◆ ping_time

int ping_time = 21
static

Definition at line 333 of file chan_iax2.c.

Referenced by __find_callno(), __send_ping(), make_trunk(), and set_config().

◆ prefs_global

struct iax2_codec_pref prefs_global
static

Definition at line 308 of file chan_iax2.c.

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

◆ 

struct { ... } qos

◆ randomcalltokendata

int randomcalltokendata
static

Definition at line 984 of file chan_iax2.c.

Referenced by handle_call_token(), and load_module().

◆ regcontext

char regcontext[AST_MAX_CONTEXT] = ""
static

◆ registrations

struct registrations registrations = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ resyncthreshold

int resyncthreshold =1000
static

Definition at line 336 of file chan_iax2.c.

Referenced by new_iax(), and set_config().

◆ sched

struct ast_sched_context* sched
static

Definition at line 457 of file chan_iax2.c.

◆ srvlookup

int srvlookup = 0
static

◆ tdesc

const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)"
static

Definition at line 310 of file chan_iax2.c.

◆ test_losspct

int test_losspct = 0
static

Definition at line 465 of file chan_iax2.c.

Referenced by handle_cli_iax2_test_losspct(), and socket_read().

◆ timer

struct ast_timer* timer
static

◆ tos

unsigned int tos

◆ total_nonval_callno_used

uint16_t total_nonval_callno_used = 0
static

◆ tpeers

struct tpeers tpeers = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ transmit_processor

struct ast_taskprocessor* transmit_processor
static

Definition at line 982 of file chan_iax2.c.

Referenced by __unload_module(), iax2_transmit(), and load_objects().

◆ trunk_maxmtu

int trunk_maxmtu
static

Definition at line 318 of file chan_iax2.c.

Referenced by handle_cli_iax2_show_stats(), iax2_trunk_queue(), and reload_config().

◆ trunk_nmaxmtu

int trunk_nmaxmtu
static

Trunk MTU statistics

Definition at line 318 of file chan_iax2.c.

Referenced by handle_cli_iax2_show_stats(), and reload_config().

◆ trunk_timed

int trunk_timed
static

Definition at line 318 of file chan_iax2.c.

Referenced by handle_cli_iax2_show_stats(), reload_config(), and timing_read().

◆ trunk_untimed

int trunk_untimed
static

Definition at line 318 of file chan_iax2.c.

Referenced by handle_cli_iax2_show_stats(), iax2_trunk_queue(), and reload_config().

◆ trunkfreq

int trunkfreq = 20
static

Definition at line 342 of file chan_iax2.c.

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

◆ trunkmaxsize

int trunkmaxsize = MAX_TRUNKDATA
static

Definition at line 343 of file chan_iax2.c.

Referenced by iax2_trunk_queue(), set_config(), set_config_destroy(), and timing_read().

◆ users

struct ao2_container* users
static

Definition at line 1003 of file chan_iax2.c.