Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 431 of file chan_iax2.c.

◆ CALLNO_ENTRY_GET_CALLNO

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

Definition at line 980 of file chan_iax2.c.

◆ CALLNO_ENTRY_IS_VALIDATED

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

Definition at line 979 of file chan_iax2.c.

◆ CALLNO_ENTRY_SET_VALIDATED

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

Definition at line 978 of file chan_iax2.c.

◆ CALLNO_ENTRY_TO_PTR

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

Definition at line 976 of file chan_iax2.c.

◆ CALLNO_TO_PTR

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

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

◆ DEBUG_SUPPORT

#define DEBUG_SUPPORT

Definition at line 325 of file chan_iax2.c.

◆ DEFAULT_CONTEXT

#define DEFAULT_CONTEXT   "default"

Definition at line 344 of file chan_iax2.c.

◆ DEFAULT_DROP

#define DEFAULT_DROP   3

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

◆ DEFAULT_MAX_THREAD_COUNT

#define DEFAULT_MAX_THREAD_COUNT   100

Definition at line 320 of file chan_iax2.c.

◆ DEFAULT_MAXMS

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

Definition at line 418 of file chan_iax2.c.

◆ DEFAULT_RETRY_TIME

#define DEFAULT_RETRY_TIME   1000

Definition at line 321 of file chan_iax2.c.

◆ DEFAULT_THREAD_COUNT

#define DEFAULT_THREAD_COUNT   10

Definition at line 319 of file chan_iax2.c.

◆ DEFAULT_TRUNKDATA

#define DEFAULT_TRUNKDATA   640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 734 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 330 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 662 of file chan_iax2.c.

◆ IAX_ALLOWFWDOWNLOAD

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

Allow the FWDOWNL command?

Definition at line 547 of file chan_iax2.c.

◆ IAX_ALREADYGONE

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

Already disconnected

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

◆ IAX_CAPABILITY_FULLBANDWIDTH

#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF

Definition at line 397 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:399

Definition at line 409 of file chan_iax2.c.

◆ IAX_CAPABILITY_LOWFREE

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

Definition at line 414 of file chan_iax2.c.

◆ IAX_CAPABILITY_MEDBANDWIDTH

#define IAX_CAPABILITY_MEDBANDWIDTH

Definition at line 399 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 538 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 537 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 536 of file chan_iax2.c.

◆ IAX_DEBUGDIGEST

#define IAX_DEBUGDIGEST (   msg,
  key 
)

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

◆ IAX_DELME

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

Needs to be deleted

Definition at line 523 of file chan_iax2.c.

◆ IAX_DYNAMIC

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

dynamic peer

Definition at line 528 of file chan_iax2.c.

◆ IAX_ENCRYPTED

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

Whether we should assume encrypted tx/rx

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

◆ IAX_HASCALLERID

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

CallerID has been specified

Definition at line 522 of file chan_iax2.c.

◆ IAX_IMMEDIATE

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

Allow immediate off-hook to extension s

Definition at line 548 of file chan_iax2.c.

◆ IAX_KEYPOPULATED

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

Whether we have a key populated

Definition at line 535 of file chan_iax2.c.

◆ IAX_MAXAUTHREQ

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

Maximum outstanding AUTHREQ restriction is in place

Definition at line 545 of file chan_iax2.c.

◆ IAX_NOTRANSFER

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

Don't native bridge

Definition at line 526 of file chan_iax2.c.

◆ IAX_PROVISION

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

This is a provisioning request

Definition at line 532 of file chan_iax2.c.

◆ IAX_QUELCH

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

Whether or not we quelch audio

Definition at line 533 of file chan_iax2.c.

◆ IAX_RECVCONNECTEDLINE

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

Allow receiving of connected line updates

Definition at line 550 of file chan_iax2.c.

◆ IAX_RTAUTOCLEAR

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

erase me on expire

Definition at line 541 of file chan_iax2.c.

◆ IAX_RTCACHEFRIENDS

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

let realtime stay till your reload

Definition at line 539 of file chan_iax2.c.

◆ IAX_RTIGNOREREGEXPIRE

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

When using realtime, ignore registration expiration

Definition at line 542 of file chan_iax2.c.

◆ IAX_RTSAVE_SYSNAME

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

Save Systname on Realtime Updates

Definition at line 530 of file chan_iax2.c.

◆ IAX_RTUPDATE

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

Send a realtime update

Definition at line 540 of file chan_iax2.c.

◆ IAX_SENDANI

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

Send ANI along with CallerID

Definition at line 529 of file chan_iax2.c.

◆ IAX_SENDCONNECTEDLINE

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

Allow sending of connected line updates

Definition at line 549 of file chan_iax2.c.

◆ IAX_SHRINKCALLERID

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

Turn on and off caller id shrinking

Definition at line 552 of file chan_iax2.c.

◆ IAX_TEMPONLY

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

Temporary (realtime)

Definition at line 524 of file chan_iax2.c.

◆ IAX_TRANSFERMEDIA

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

When doing IAX2 transfers, transfer media only

Definition at line 544 of file chan_iax2.c.

◆ IAX_TRUNK

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

Treat as a trunk

Definition at line 525 of file chan_iax2.c.

◆ IAX_TRUNKTIMESTAMPS

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

Send trunk timestamps

Definition at line 543 of file chan_iax2.c.

◆ IAX_USEJITTERBUF

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

Use jitter buffer

Definition at line 527 of file chan_iax2.c.

◆ MARK_IAX_SUBCLASS_TX

#define MARK_IAX_SUBCLASS_TX   0x8000

Definition at line 742 of file chan_iax2.c.

◆ MAX_JITTER_BUFFER

#define MAX_JITTER_BUFFER   50

Definition at line 731 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 entries are specified in iax.conf for matching order.

Definition at line 1023 of file chan_iax2.c.

◆ MAX_RETRY_TIME

#define MAX_RETRY_TIME   10000

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

◆ MAX_TRUNKDATA

#define MAX_TRUNKDATA   640 * 200

40ms, uncompressed linear * 200 channels

Definition at line 364 of file chan_iax2.c.

◆ MAX_USER_BUCKETS

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

Definition at line 1027 of file chan_iax2.c.

◆ MEMORY_SIZE

#define MEMORY_SIZE   100

Definition at line 322 of file chan_iax2.c.

◆ MIN_JITTER_BUFFER

#define MIN_JITTER_BUFFER   10

Definition at line 732 of file chan_iax2.c.

◆ MIN_RETRY_TIME

#define MIN_RETRY_TIME   100

Definition at line 728 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 327 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 6983 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 6982 of file chan_iax2.c.

◆ PTR_TO_CALLNO

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

Definition at line 316 of file chan_iax2.c.

◆ PTR_TO_CALLNO_ENTRY

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

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

◆ schedule_action

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

Definition at line 1750 of file chan_iax2.c.

◆ TRUNK_CALL_START

#define TRUNK_CALL_START   (IAX_MAX_CALLS / 2)

Definition at line 1247 of file chan_iax2.c.

◆ TS_GAP_FOR_JB_RESYNC

#define TS_GAP_FOR_JB_RESYNC   5000

Definition at line 739 of file chan_iax2.c.

Typedef Documentation

◆ callno_entry

typedef uint16_t callno_entry

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

1074 {
1075 /*! Extension exists */
1076 CACHE_FLAG_EXISTS = (1 << 0),
1077 /*! Extension is nonexistent */
1078 CACHE_FLAG_NONEXISTENT = (1 << 1),
1079 /*! Extension can exist */
1080 CACHE_FLAG_CANEXIST = (1 << 2),
1081 /*! Waiting to hear back response */
1082 CACHE_FLAG_PENDING = (1 << 3),
1083 /*! Timed out */
1084 CACHE_FLAG_TIMEOUT = (1 << 4),
1085 /*! Request transmitted */
1086 CACHE_FLAG_TRANSMITTED = (1 << 5),
1087 /*! Timeout */
1088 CACHE_FLAG_UNKNOWN = (1 << 6),
1089 /*! Matchmore */
1090 CACHE_FLAG_MATCHMORE = (1 << 7),
1091};
@ CACHE_FLAG_TIMEOUT
Definition: chan_iax2.c:1084
@ CACHE_FLAG_EXISTS
Definition: chan_iax2.c:1076
@ CACHE_FLAG_UNKNOWN
Definition: chan_iax2.c:1088
@ CACHE_FLAG_MATCHMORE
Definition: chan_iax2.c:1090
@ CACHE_FLAG_CANEXIST
Definition: chan_iax2.c:1080
@ CACHE_FLAG_PENDING
Definition: chan_iax2.c:1082
@ CACHE_FLAG_NONEXISTENT
Definition: chan_iax2.c:1078
@ CACHE_FLAG_TRANSMITTED
Definition: chan_iax2.c:1086

◆ anonymous enum

anonymous enum
Enumerator
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 2376 of file chan_iax2.c.

2376 {
2377 /* do not allow a new call number, only search ones in use for match */
2378 NEW_PREVENT = 0,
2379 /* search for match first, then allow a new one to be allocated */
2380 NEW_ALLOW = 1,
2381 /* do not search for match, force a new call number */
2382 NEW_FORCE = 2,
2383 /* do not search for match, force a new call number. Signifies call number
2384 * has been calltoken validated */
2386};
@ NEW_PREVENT
Definition: chan_iax2.c:2378
@ NEW_ALLOW
Definition: chan_iax2.c:2380
@ NEW_FORCE
Definition: chan_iax2.c:2382
@ NEW_ALLOW_CALLTOKEN_VALIDATED
Definition: chan_iax2.c:2385

◆ callno_type

Enumerator
CALLNO_TYPE_NORMAL 
CALLNO_TYPE_TRUNK 

Definition at line 970 of file chan_iax2.c.

970 {
973};
@ CALLNO_TYPE_TRUNK
Definition: chan_iax2.c:972
@ CALLNO_TYPE_NORMAL
Definition: chan_iax2.c:971

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

560 {
561 /*! \brief Default calltoken required unless the ip is in the ignorelist */
563 /*! \brief Require call token validation. */
564 CALLTOKEN_YES = 1,
565 /*! \brief Require call token validation after a successful registration
566 * using call token validation occurs. */
567 CALLTOKEN_AUTO = 2,
568 /*! \brief Do not require call token validation. */
569 CALLTOKEN_NO = 3,
570};
@ CALLTOKEN_DEFAULT
Default calltoken required unless the ip is in the ignorelist.
Definition: chan_iax2.c:562
@ CALLTOKEN_AUTO
Require call token validation after a successful registration using call token validation occurs.
Definition: chan_iax2.c:567
@ CALLTOKEN_NO
Do not require call token validation.
Definition: chan_iax2.c:569
@ CALLTOKEN_YES
Require call token validation.
Definition: chan_iax2.c:564

◆ iax2_state

enum iax2_state
Enumerator
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 510 of file chan_iax2.c.

510 {
511 IAX_STATE_STARTED = (1 << 0),
512 IAX_STATE_AUTHENTICATED = (1 << 1),
513 IAX_STATE_TBD = (1 << 2),
514};
@ IAX_STATE_TBD
Definition: chan_iax2.c:513
@ IAX_STATE_AUTHENTICATED
Definition: chan_iax2.c:512
@ IAX_STATE_STARTED
Definition: chan_iax2.c:511

◆ iax2_thread_iostate

Enumerator
IAX_IOSTATE_IDLE 
IAX_IOSTATE_READY 
IAX_IOSTATE_PROCESSING 
IAX_IOSTATE_SCHEDREADY 

Definition at line 1115 of file chan_iax2.c.

1115 {
1120};
@ IAX_IOSTATE_PROCESSING
Definition: chan_iax2.c:1118
@ IAX_IOSTATE_SCHEDREADY
Definition: chan_iax2.c:1119
@ IAX_IOSTATE_IDLE
Definition: chan_iax2.c:1116
@ IAX_IOSTATE_READY
Definition: chan_iax2.c:1117

◆ iax2_thread_type

Enumerator
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 1122 of file chan_iax2.c.

1122 {
1125};
@ IAX_THREAD_TYPE_DYNAMIC
Definition: chan_iax2.c:1124
@ IAX_THREAD_TYPE_POOL
Definition: chan_iax2.c:1123

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

685 {
693};
@ REG_STATE_REGSENT
Definition: chan_iax2.c:687
@ REG_STATE_TIMEOUT
Definition: chan_iax2.c:691
@ REG_STATE_AUTHSENT
Definition: chan_iax2.c:688
@ REG_STATE_NOAUTH
Definition: chan_iax2.c:692
@ REG_STATE_REGISTERED
Definition: chan_iax2.c:689
@ REG_STATE_REJECTED
Definition: chan_iax2.c:690
@ REG_STATE_UNREGISTERED
Definition: chan_iax2.c:686

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

695 {
696 TRANSFER_NONE = 0,
707};
@ TRANSFER_MEDIA
Definition: chan_iax2.c:705
@ TRANSFER_NONE
Definition: chan_iax2.c:696
@ TRANSFER_MPASSTHROUGH
Definition: chan_iax2.c:704
@ TRANSFER_MEDIAPASS
Definition: chan_iax2.c:706
@ TRANSFER_PASSTHROUGH
Definition: chan_iax2.c:700
@ TRANSFER_MRELEASED
Definition: chan_iax2.c:703
@ TRANSFER_BEGIN
Definition: chan_iax2.c:697
@ TRANSFER_MREADY
Definition: chan_iax2.c:702
@ TRANSFER_READY
Definition: chan_iax2.c:698
@ TRANSFER_MBEGIN
Definition: chan_iax2.c:701
@ TRANSFER_RELEASED
Definition: chan_iax2.c:699

Function Documentation

◆ __attempt_transmit()

static void __attempt_transmit ( const void *  data)
static

Definition at line 3621 of file chan_iax2.c.

3622{
3623 /* Attempt to transmit the frame to the remote peer...
3624 Called without iaxsl held. */
3625 struct iax_frame *f = (struct iax_frame *)data;
3626 int freeme = 0;
3627 int callno = f->callno;
3628
3629 /* Make sure this call is still active */
3630 if (callno)
3632 if (callno && iaxs[callno]) {
3633 if (f->retries < 0) {
3634 /* Already ACK'd */
3635 freeme = 1;
3636 } else if (f->retries >= max_retries) {
3637 /* Too many attempts. Record an error. */
3638 if (f->transfer) {
3639 /* Transfer timeout */
3641 } else if (f->final) {
3643 } else {
3644 if (iaxs[callno]->owner) {
3645 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %u, subclass = %d, ts=%u, seqno=%d)\n",
3648 f->af.frametype,
3649 f->af.subclass.integer,
3650 f->ts,
3651 f->oseqno);
3652 }
3653 iaxs[callno]->error = ETIMEDOUT;
3654 if (iaxs[callno]->owner) {
3656 /* Hangup the fd */
3657 iax2_queue_frame(callno, &fr); /* XXX */
3658 /* Remember, owner could disappear */
3659 if (iaxs[callno] && iaxs[callno]->owner)
3661 } else {
3662 if (iaxs[callno]->reg) {
3663 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
3664 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
3666 }
3667 iax2_destroy(callno);
3668 }
3669 }
3670 freeme = 1;
3671 } else {
3672 /* Update it if it needs it */
3673 update_packet(f);
3674 /* Attempt transmission */
3675 send_packet(f);
3676 f->retries++;
3677 /* Try again later after 10 times as long */
3678 f->retrytime *= 10;
3679 if (f->retrytime > MAX_RETRY_TIME)
3681 /* Transfer messages max out at one second */
3682 if (f->transfer && (f->retrytime > 1000))
3683 f->retrytime = 1000;
3685 }
3686 } else {
3687 /* Make sure it gets freed */
3688 f->retries = -1;
3689 freeme = 1;
3690 }
3691
3692 if (freeme) {
3693 /* Don't attempt delivery, just remove it from the queue */
3694 AST_LIST_REMOVE(&frame_queue[callno], f, list);
3695 ast_mutex_unlock(&iaxsl[callno]);
3696 f->retrans = -1; /* this is safe because this is the scheduled function */
3697 /* Free the IAX frame */
3698 iax2_frame_free(f);
3699 } else if (callno) {
3700 ast_mutex_unlock(&iaxsl[callno]);
3701 }
3702}
#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:3594
static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)]
chan_iax2_pvt structure locks
Definition: chan_iax2.c:1236
static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
Definition: chan_iax2.c:7871
static int attempt_transmit(const void *data)
Definition: chan_iax2.c:3704
#define MAX_RETRY_TIME
Definition: chan_iax2.c:729
static void iax2_destroy(int callno)
Definition: chan_iax2.c:3532
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:1759
static int max_retries
Definition: chan_iax2.c:356
static struct chan_iax2_pvt * iaxs[IAX_MAX_CALLS]
an array of iax2 pvt structures
Definition: chan_iax2.c:1198
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:3326
static int send_packet(struct iax_frame *f)
Definition: chan_iax2.c:3475
static void iax2_frame_free(struct iax_frame *fr)
Definition: chan_iax2.c:2203
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:197
#define ast_mutex_lock(a)
Definition: lock.h:196
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:800
struct ast_channel * owner
Definition: chan_iax2.c:833
struct iax2_registry * reg
Definition: chan_iax2.c:907
enum iax_reg_state regstate
Definition: chan_iax2.c:715
struct ast_sockaddr us
Definition: chan_iax2.c:718
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 9464 of file chan_iax2.c.

9465{
9466 /* Called from IAX thread only, without iaxs lock */
9467 int callno = (int)(long)(nothing);
9468 struct iax_ie_data ied;
9469 ast_mutex_lock(&iaxsl[callno]);
9470 if (iaxs[callno]) {
9471 memset(&ied, 0, sizeof(ied));
9472 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
9473 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
9475 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
9476 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
9478 }
9479 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
9480 }
9481 ast_mutex_unlock(&iaxsl[callno]);
9482}
#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:7896
@ 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 4822 of file chan_iax2.c.

4823{
4824 int callno = PTR_TO_CALLNO(nothing);
4826 ast_mutex_lock(&iaxsl[callno]);
4827 if (iaxs[callno]) {
4828 iaxs[callno]->initid = -1;
4829 iax2_queue_frame(callno, &f);
4830 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
4831 }
4832 ast_mutex_unlock(&iaxsl[callno]);
4833}
#define PTR_TO_CALLNO(a)
Definition: chan_iax2.c:316
@ 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 9513 of file chan_iax2.c.

9514{
9515 /* Called from IAX thread only, without iaxs lock */
9516 int callno = (int)(long)(nothing);
9517 struct iax_ie_data ied;
9518 ast_mutex_lock(&iaxsl[callno]);
9519 if (iaxs[callno]) {
9520 memset(&ied, 0, sizeof(ied));
9521 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
9523 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
9524 }
9525 ast_mutex_unlock(&iaxsl[callno]);
9526}
#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 3413 of file chan_iax2.c.

3414{
3415 /* Just deliver the packet by using queueing. This is called by
3416 the IAX thread with the iaxsl lock held. */
3417 struct iax_frame *fr = data;
3418 fr->retrans = -1;
3421 iax2_queue_frame(fr->callno, &fr->af);
3422 /* Free our iax frame */
3423 iax2_frame_free(fr);
3424 /* And don't run again */
3425 return 0;
3426}
#define IAX_ALREADYGONE
Definition: chan_iax2.c:531
@ 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 9080 of file chan_iax2.c.

9081{
9082 struct iax2_peer *peer = (struct iax2_peer *) data;
9083 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
9084
9085 if (!peer)
9086 return;
9087 if (peer->expire == -1) {
9088 /* Removed already (possibly through CLI), ignore */
9089 return;
9090 }
9091
9092 peer->expire = -1;
9093
9094 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
9096 realtime_update_peer(peer->name, &peer->addr, 0);
9098 blob = ast_json_pack("{s: s, s: s}",
9099 "peer_status", "Unregistered",
9100 "cause", "Expired");
9102 /* modify entry in peercnts table as _not_ registered */
9103 peercnt_modify((unsigned char) 0, 0, &peer->addr);
9104 /* Reset the address */
9105 ast_sockaddr_setnull(&peer->addr);
9106 /* Reset expiry value */
9107 peer->expiry = min_reg_expire;
9108 if (!ast_test_flag64(peer, IAX_TEMPONLY))
9109 ast_db_del("IAX/Registry", peer->name);
9110 register_peer_exten(peer, 0);
9111 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
9112 if (iax2_regfunk)
9113 iax2_regfunk(peer->name, 0);
9114
9116 unlink_peer(peer);
9117
9118 peer_unref(peer);
9119}
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Definition: db.c:472
static void peercnt_modify(unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
Definition: chan_iax2.c:2676
static int min_reg_expire
Definition: chan_iax2.c:383
static void register_peer_exten(struct iax2_peer *peer, int onoff)
Definition: chan_iax2.c:9042
#define IAX_RTUPDATE
Definition: chan_iax2.c:540
static int(* iax2_regfunk)(const char *username, int onoff)
Definition: chan_iax2.c:394
#define IAX_RTCACHEFRIENDS
Definition: chan_iax2.c:539
static void unlink_peer(struct iax2_peer *peer)
Definition: chan_iax2.c:9061
static struct iax2_peer * peer_unref(struct iax2_peer *peer)
Definition: chan_iax2.c:2101
static struct ast_flags64 globalflags
Definition: chan_iax2.c:506
static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
Definition: chan_iax2.c:4664
#define IAX_RTAUTOCLEAR
Definition: chan_iax2.c:541
#define IAX_TEMPONLY
Definition: chan_iax2.c:524
@ 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:513
@ 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:626
int expire
Definition: chan_iax2.c:638
struct ast_endpoint * endpoint
Definition: chan_iax2.c:659
int expiry
Definition: chan_iax2.c:639
const ast_string_field name
Definition: chan_iax2.c:623
#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 3181 of file chan_iax2.c.

3182{
3183 int res = 0;
3184 int x;
3185 /* this call is calltoken validated as long as it is either NEW_FORCE
3186 * or NEW_ALLOW_CALLTOKEN_VALIDATED */
3187 int validated = (new > NEW_ALLOW) ? 1 : 0;
3188 char host[80];
3189
3190 if (new <= NEW_ALLOW) {
3191 if (callno) {
3192 struct chan_iax2_pvt *pvt;
3193 struct chan_iax2_pvt tmp_pvt = {
3194 .callno = dcallno,
3195 .peercallno = callno,
3196 .transfercallno = callno,
3197 /* hack!! */
3198 .frames_received = check_dcallno,
3199 };
3200
3201 ast_sockaddr_copy(&tmp_pvt.addr, addr);
3202 /* this works for finding normal call numbers not involving transferring */
3203 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
3204 if (return_locked) {
3205 ast_mutex_lock(&iaxsl[pvt->callno]);
3206 }
3207 res = pvt->callno;
3208 ao2_ref(pvt, -1);
3209 pvt = NULL;
3210 return res;
3211 }
3212 /* this searches for transfer call numbers that might not get caught otherwise */
3213 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
3214 ast_sockaddr_copy(&tmp_pvt.transfer, addr);
3215 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
3216 if (return_locked) {
3217 ast_mutex_lock(&iaxsl[pvt->callno]);
3218 }
3219 res = pvt->callno;
3220 ao2_ref(pvt, -1);
3221 pvt = NULL;
3222 return res;
3223 }
3224 }
3225 /* This will occur on the first response to a message that we initiated,
3226 * such as a PING. */
3227 if (dcallno) {
3228 ast_mutex_lock(&iaxsl[dcallno]);
3229 }
3230 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(addr, callno, dcallno, iaxs[dcallno], check_dcallno)) {
3231 iaxs[dcallno]->peercallno = callno;
3232 res = dcallno;
3233 store_by_peercallno(iaxs[dcallno]);
3234 if (!res || !return_locked) {
3235 ast_mutex_unlock(&iaxsl[dcallno]);
3236 }
3237 return res;
3238 }
3239 if (dcallno) {
3240 ast_mutex_unlock(&iaxsl[dcallno]);
3241 }
3242 }
3243 if (!res && (new >= NEW_ALLOW)) {
3244 callno_entry entry;
3245
3246 /* It may seem odd that we look through the peer list for a name for
3247 * this *incoming* call. Well, it is weird. However, users don't
3248 * have an IP address/port number that we can match against. So,
3249 * this is just checking for a peer that has that IP/port and
3250 * assuming that we have a user of the same name. This isn't always
3251 * correct, but it will be changed if needed after authentication. */
3252 if (!iax2_getpeername(*addr, host, sizeof(host)))
3253 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(addr));
3254
3255 if (peercnt_add(addr)) {
3256 /* This address has hit its callnumber limit. When the limit
3257 * is reached, the connection is not added to the peercnts table.*/
3258 return 0;
3259 }
3260
3261 if (get_unused_callno(CALLNO_TYPE_NORMAL, validated, &entry)) {
3262 /* since we ran out of space, remove the peercnt
3263 * entry we added earlier */
3265 ast_log(LOG_WARNING, "No more space\n");
3266 return 0;
3267 }
3268 x = CALLNO_ENTRY_GET_CALLNO(entry);
3269 ast_mutex_lock(&iaxsl[x]);
3270
3271 iaxs[x] = new_iax(addr, host);
3272 if (iaxs[x]) {
3273 if (iaxdebug)
3274 ast_debug(1, "Creating new call structure %d\n", x);
3275 iaxs[x]->callno_entry = entry;
3276 iaxs[x]->sockfd = sockfd;
3278 iaxs[x]->peercallno = callno;
3279 iaxs[x]->callno = x;
3282 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
3283 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
3284 iaxs[x]->amaflags = amaflags;
3290
3291 if (iaxs[x]->peercallno) {
3293 }
3294 } else {
3295 ast_log(LOG_WARNING, "Out of resources\n");
3298 return 0;
3299 }
3300 if (!return_locked)
3302 res = x;
3303 }
3304 return res;
3305}
#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:1813
static int replace_callno(const void *obj)
Definition: chan_iax2.c:3055
static struct chan_iax2_pvt * new_iax(struct ast_sockaddr *addr, const char *host)
Definition: chan_iax2.c:2316
static char default_parkinglot[AST_MAX_CONTEXT]
Definition: chan_iax2.c:346
static int ping_time
Definition: chan_iax2.c:357
#define IAX_NOTRANSFER
Definition: chan_iax2.c:526
static int iax2_getpeername(struct ast_sockaddr addr, char *host, int len)
Definition: chan_iax2.c:2118
#define CALLNO_ENTRY_GET_CALLNO(a)
Definition: chan_iax2.c:980
static struct ao2_container * iax_transfercallno_pvts
Another container of iax2_pvt structures.
Definition: chan_iax2.c:1243
#define IAX_RECVCONNECTEDLINE
Definition: chan_iax2.c:550
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:2388
#define IAX_FORCE_ENCRYPT
Definition: chan_iax2.c:551
#define IAX_SENDCONNECTEDLINE
Definition: chan_iax2.c:549
static int get_unused_callno(enum callno_type type, int validated, callno_entry *entry)
Definition: chan_iax2.c:2978
static int send_lagrq(const void *data)
Definition: chan_iax2.c:1877
static int peercnt_add(struct ast_sockaddr *addr)
Definition: chan_iax2.c:2704
#define DEFAULT_RETRY_TIME
Definition: chan_iax2.c:321
static int lagrq_time
Definition: chan_iax2.c:358
static void store_by_peercallno(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:2491
static int peercnt_remove_by_addr(struct ast_sockaddr *addr)
Definition: chan_iax2.c:2795
#define CALLNO_ENTRY_TO_PTR(a)
Definition: chan_iax2.c:976
#define IAX_USEJITTERBUF
Definition: chan_iax2.c:527
#define IAX_TRANSFERMEDIA
Definition: chan_iax2.c:544
static int iaxdebug
Definition: chan_iax2.c:485
uint16_t callno_entry
Definition: chan_iax2.c:764
static int amaflags
Definition: chan_iax2.c:500
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:497
static char mohsuggest[MAX_MUSICCLASS]
Definition: chan_iax2.c:499
static char mohinterpret[MAX_MUSICCLASS]
Definition: chan_iax2.c:498
static struct ao2_container * iax_peercallno_pvts
Another container of iax2_pvt structures.
Definition: chan_iax2.c:1227
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:796
struct ast_sockaddr transfer
Definition: chan_iax2.c:919
unsigned short peercallno
Definition: chan_iax2.c:810
unsigned short callno
Definition: chan_iax2.c:806
const ast_string_field parkinglot
Definition: chan_iax2.c:886
const ast_string_field host
Definition: chan_iax2.c:886
callno_entry callno_entry
Definition: chan_iax2.c:808
#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 4198 of file chan_iax2.c.

4199{
4200 int callno = PTR_TO_CALLNO(p);
4201 struct chan_iax2_pvt *pvt = NULL;
4202 struct iax_frame *fr;
4203 jb_frame frame;
4204 int ret;
4205 long ms;
4206 long next;
4207 struct timeval now = ast_tvnow();
4208 struct ast_format *voicefmt;
4209
4210 /* Make sure we have a valid private structure before going on */
4211 ast_mutex_lock(&iaxsl[callno]);
4212 pvt = iaxs[callno];
4213 if (!pvt) {
4214 /* No go! */
4215 ast_mutex_unlock(&iaxsl[callno]);
4216 return;
4217 }
4218
4219 pvt->jbid = -1;
4220
4221 /* round up a millisecond since ast_sched_runq does; */
4222 /* prevents us from spinning while waiting for our now */
4223 /* to catch up with runq's now */
4224 now.tv_usec += 1000;
4225
4226 ms = ast_tvdiff_ms(now, pvt->rxcore);
4227 if (ms >= (next = jb_next(pvt->jb))) {
4229 if (!voicefmt) {
4230 /* pvt->voiceformat won't be set if we haven't received any voice frames yet.
4231 * In this case, fall back to using the format negotiated during call setup,
4232 * so we don't stall the jitterbuffer completely. */
4234 if (!voicefmt) {
4235 /* As a last resort, we can use pvt->chosenformat.
4236 * This is set when we receive a call (either authenticated or unauthenticated),
4237 * so even if we haven't received any voice frames yet, we can still use the
4238 * right format.
4239 *
4240 * If we have to do this, in most cases, we aren't even processing voice frames
4241 * anyways, it's likely a non-voice frame. In that case, the format doesn't
4242 * really matter so much, because we could just pass 20 to jb_get instead
4243 * of calling ast_format_get_default_ms. However, until jb_get returns,
4244 * we don't actually know what kind of frame it is for sure, so use
4245 * the right format just to be safe. */
4247 }
4248 }
4249 if (!voicefmt) {
4250 /* This should never happen, since we should always be able to have an acceptable format to use. */
4251 ast_log(LOG_ERROR, "No voice, peer, or chosen format available on %s, backlogging frame\n", ast_channel_name(pvt->owner));
4252 goto cleanup; /* Don't crash if there's no voice format */
4253 }
4254 ret = jb_get(pvt->jb, &frame, ms, ast_format_get_default_ms(voicefmt));
4255 switch(ret) {
4256 case JB_OK:
4257 fr = frame.data;
4258 __do_deliver(fr);
4259 /* __do_deliver() can cause the call to disappear */
4260 pvt = iaxs[callno];
4261 break;
4262 case JB_INTERP:
4263 {
4264 struct ast_frame af = { 0, };
4265
4266 /* create an interpolation frame */
4268 af.subclass.format = voicefmt;
4269 af.samples = frame.ms * (ast_format_get_sample_rate(voicefmt) / 1000);
4270 af.src = "IAX2 JB interpolation";
4271 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
4273
4274 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
4275 * which we'd need to malloc, and then it would free it. That seems like a drag */
4276 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
4277 iax2_queue_frame(callno, &af);
4278 /* iax2_queue_frame() could cause the call to disappear */
4279 pvt = iaxs[callno];
4280 }
4281 }
4282 break;
4283 case JB_DROP:
4284 iax2_frame_free(frame.data);
4285 break;
4286 case JB_NOFRAME:
4287 case JB_EMPTY:
4288 /* do nothing */
4289 break;
4290 default:
4291 /* shouldn't happen */
4292 break;
4293 }
4294 }
4295cleanup:
4296 if (pvt)
4297 update_jbsched(pvt);
4298 ast_mutex_unlock(&iaxsl[callno]);
4299}
static int __do_deliver(void *data)
Definition: chan_iax2.c:3413
static void update_jbsched(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:4181
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
#define LOG_ERROR
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:823
iax2_format voiceformat
Definition: chan_iax2.c:772
iax2_format peerformat
Definition: chan_iax2.c:817
jitterbuf * jb
Definition: chan_iax2.c:825
iax2_format chosenformat
Definition: chan_iax2.c:815
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(), chan_iax2_pvt::chosenformat, 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_ERROR, 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 8723 of file chan_iax2.c.

8724{
8725 struct iax2_registry *reg = (struct iax2_registry *)data;
8726
8727 if (ast_sockaddr_isnull(&reg->addr)) {
8728 reg->addr.ss.ss_family = AST_AF_UNSPEC;
8729 ast_dnsmgr_lookup(reg->hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL);
8730 if (!ast_sockaddr_port(&reg->addr)) {
8731 ast_sockaddr_set_port(&reg->addr, reg->port);
8732 } else {
8733 reg->port = ast_sockaddr_port(&reg->addr);
8734 }
8735 }
8736
8737 reg->expire = -1;
8738 iax2_do_register(reg);
8739}
static int iax2_do_register(struct iax2_registry *reg)
Definition: chan_iax2.c:12354
static int srvlookup
Definition: chan_iax2.c:386
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
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
@ AST_AF_UNSPEC
Definition: netsock2.h:54
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:710
struct ast_dnsmgr_entry * dnsmgr
Definition: chan_iax2.c:719
char hostname[]
Definition: chan_iax2.c:722

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

12536{
12537 struct iax2_peer *peer = (struct iax2_peer *)data;
12538 int callno;
12539
12540 if (peer->lastms > -1) {
12541 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
12542
12543 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
12545 blob = ast_json_pack("{s: s, s: i}",
12546 "peer_status", "Unreachable",
12547 "time", peer->lastms);
12549 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
12550 }
12551 if ((callno = peer->callno) > 0) {
12555 }
12556 peer->callno = 0;
12557 peer->lastms = -1;
12558 /* Try again quickly */
12560 if (peer->pokeexpire == -1)
12561 peer_unref(peer);
12562}
static int iax2_poke_peer_s(const void *data)
Definition: chan_iax2.c:9580
static struct iax2_peer * peer_ref(struct iax2_peer *peer)
Definition: chan_iax2.c:2095
int callno
Definition: chan_iax2.c:643
int pokefreqnotok
Definition: chan_iax2.c:649
int lastms
Definition: chan_iax2.c:645
int pokeexpire
Definition: chan_iax2.c:644

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

9574{
9575 struct iax2_peer *peer = (struct iax2_peer *)data;
9576 iax2_poke_peer(peer, 0);
9577 peer_unref(peer);
9578}
static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
Definition: chan_iax2.c:12585

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

7087{
7088 struct show_peers_context cont = {
7089 .havepattern = 0,
7090 .idtext = "",
7091 .registeredonly = 0,
7092
7093 .peerlist = 0,
7094
7095 .total_peers = 0,
7096 .online_peers = 0,
7097 .offline_peers = 0,
7098 .unmonitored_peers = 0,
7099 };
7100
7101 struct ao2_iterator i;
7102
7103 struct iax2_peer *peer = NULL;
7104
7105 switch (argc) {
7106 case 6:
7107 if (!strcasecmp(argv[3], "registered"))
7108 cont.registeredonly = 1;
7109 else
7110 return RESULT_SHOWUSAGE;
7111 if (!strcasecmp(argv[4], "like")) {
7112 if (regcomp(&cont.regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
7113 return RESULT_SHOWUSAGE;
7114 cont.havepattern = 1;
7115 } else
7116 return RESULT_SHOWUSAGE;
7117 break;
7118 case 5:
7119 if (!strcasecmp(argv[3], "like")) {
7120 if (regcomp(&cont.regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
7121 return RESULT_SHOWUSAGE;
7122 cont.havepattern = 1;
7123 } else
7124 return RESULT_SHOWUSAGE;
7125 break;
7126 case 4:
7127 if (!strcasecmp(argv[3], "registered")) {
7128 cont.registeredonly = 1;
7129 } else {
7130 return RESULT_SHOWUSAGE;
7131 }
7132 break;
7133 case 3:
7134 break;
7135 default:
7136 return RESULT_SHOWUSAGE;
7137 }
7138
7139
7140 if (!s) {
7141 ast_cli(fd, PEERS_FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", "Description");
7142 }
7143
7144 i = ao2_iterator_init(peers, 0);
7145 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
7146
7147 if (cont.registeredonly && ast_sockaddr_isnull(&peer->addr)) {
7148 continue;
7149 }
7150 if (cont.havepattern && regexec(&cont.regexbuf, peer->name, 0, NULL, 0)) {
7151 continue;
7152 }
7153
7154 _iax2_show_peers_one(fd, s, &cont, peer);
7155
7156 }
7158
7159 if (!s) {
7160 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
7162 }
7163
7164 if (cont.havepattern) {
7165 regfree(&cont.regexbuf);
7166 }
7167
7168 if (total) {
7169 *total = cont.total_peers;
7170 }
7171
7172 return RESULT_SUCCESS;
7173
7174}
#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:6982
static void _iax2_show_peers_one(int fd, struct mansession *s, struct show_peers_context *cont, struct iax2_peer *peer)
Definition: chan_iax2.c:6985
#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 15186 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 1725 of file chan_iax2.c.

1726{
1727 struct iax2_thread *thread;
1728 static time_t lasterror;
1729 time_t t;
1730
1732 if (thread != NULL) {
1733 thread->schedfunc = func;
1734 thread->scheddata = data;
1735 thread->iostate = IAX_IOSTATE_SCHEDREADY;
1736#ifdef DEBUG_SCHED_MULTITHREAD
1737 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
1738#endif
1739 signal_condition(&thread->lock, &thread->cond);
1740 return 0;
1741 }
1742 time(&t);
1743 if (t != lasterror) {
1744 lasterror = t;
1745 ast_debug(1, "Out of idle IAX2 threads for scheduling! (%s)\n", funcname);
1746 }
1747
1748 return -1;
1749}
pthread_t thread
Definition: app_sla.c:335
static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
Definition: chan_iax2.c:1183
static struct iax2_thread * find_idle_thread(void)
Definition: chan_iax2.c:1658
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 7852 of file chan_iax2.c.

7854{
7855 struct ast_frame f = { 0, };
7856 int res = 0;
7857
7858 f.frametype = type;
7859 f.subclass.integer = command;
7860 f.datalen = datalen;
7861 f.src = __FUNCTION__;
7862 f.data.ptr = (void *) data;
7863
7864 if ((res = queue_signalling(i, &f)) <= 0) {
7865 return res;
7866 }
7867
7868 return iax2_send(i, &f, ts, seqno, now, transfer, final);
7869}
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:2244
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:6683
static const char type[]
Definition: chan_ooh323.c:109
static int transfer(void *data)
Definition: chan_pjsip.c:2133
union ast_frame::@228 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 1853 of file chan_iax2.c.

1854{
1855 int callno = PTR_TO_CALLNO(data);
1856
1857 if (iax2_lock_callno_unless_destroyed(callno) == 0) {
1858 ast_debug(3, "Hangup initiated on call %d, aborting __send_lagrq\n", callno);
1859 return;
1860 }
1861
1862 /* Mark lagid as invalid scheduler id. */
1863 iaxs[callno]->lagid = -1;
1864
1865 /* callno is now locked. */
1866 if (iaxs[callno]->peercallno) {
1867 /* Send LAGRQ packet. */
1869
1870 /* Schedule sending next lagrq. */
1871 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
1872 }
1873
1874 ast_mutex_unlock(&iaxsl[callno]);
1875}
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:1771
@ 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 1789 of file chan_iax2.c.

1790{
1791 int callno = PTR_TO_CALLNO(data);
1792
1793 if (iax2_lock_callno_unless_destroyed(callno) == 0) {
1794 ast_debug(3, "Hangup initiated on call %d, aborting __send_ping\n", callno);
1795 return;
1796 }
1797
1798 /* Mark pingid as invalid scheduler id. */
1799 iaxs[callno]->pingid = -1;
1800
1801 /* callno is now locked. */
1802 if (iaxs[callno]->peercallno) {
1803 /* Send PING packet. */
1804 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
1805
1806 /* Schedule sending next ping. */
1807 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
1808 }
1809
1810 ast_mutex_unlock(&iaxsl[callno]);
1811}
@ 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 14813 of file chan_iax2.c.

14814{
14815 int x;
14816
14819
14820 ast_manager_unregister("IAXpeers");
14821 ast_manager_unregister("IAXpeerlist");
14822 ast_manager_unregister("IAXnetstats");
14823 ast_manager_unregister("IAXregistry");
14828
14830 pthread_cancel(netthreadid);
14831 pthread_kill(netthreadid, SIGURG);
14832 pthread_join(netthreadid, NULL);
14833 }
14834
14835 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14836 if (iaxs[x]) {
14837 iax2_destroy(x);
14838 }
14839 }
14840
14841 /* Call for all threads to halt */
14845
14848 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14849 if (iaxs[x]) {
14850 iax2_destroy(x);
14851 }
14852 }
14853 ast_manager_unregister( "IAXpeers" );
14854 ast_manager_unregister( "IAXpeerlist" );
14855 ast_manager_unregister( "IAXnetstats" );
14856 ast_manager_unregister( "IAXregistry" );
14861 delete_users();
14864
14865 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14867 }
14868
14869 ao2_ref(peers, -1);
14870 ao2_ref(users, -1);
14875 if (timer) {
14877 timer = NULL;
14878 }
14880
14883 sched = NULL;
14884 ao2_ref(peercnts, -1);
14885
14887 ast_unload_realtime("iaxpeers");
14888
14891 return 0;
14892}
static struct ao2_container * peercnts
Definition: chan_iax2.c:1031
static struct ast_channel_tech iax2_tech
Definition: chan_iax2.c:1366
static int peercnt_remove_cb(const void *obj)
Definition: chan_iax2.c:2781
static char regcontext[AST_MAX_CONTEXT]
Definition: chan_iax2.c:349
static struct ao2_container * callno_limits
Definition: chan_iax2.c:1034
static struct ast_netsock_list * netsock
Definition: chan_iax2.c:390
static struct ast_netsock_list * outsock
Definition: chan_iax2.c:391
static void acl_change_stasis_unsubscribe(void)
Definition: chan_iax2.c:1552
static struct ast_switch iax2_switch
Definition: chan_iax2.c:14755
static char * papp
Definition: chan_iax2.c:12462
static struct ast_taskprocessor * transmit_processor
Definition: chan_iax2.c:1007
static struct ast_timer * timer
Definition: chan_iax2.c:388
static pthread_t netthreadid
Definition: chan_iax2.c:508
static void network_change_stasis_unsubscribe(void)
Definition: chan_iax2.c:1537
static struct ao2_container * calltoken_ignores
Definition: chan_iax2.c:1037
static void delete_users(void)
Definition: chan_iax2.c:13619
static void cleanup_thread_list(void *head)
Definition: chan_iax2.c:14793
static struct ast_cli_entry cli_iax2[]
Definition: chan_iax2.c:14765
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:569
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:7697
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
Definition: main/config.c:3796
#define AST_PTHREADT_NULL
Definition: lock.h:73
#define ast_mutex_destroy(a)
Definition: lock.h:195
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:8220
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:652
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 15186 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 6985 of file chan_iax2.c.

6986{
6987 char name[256] = "";
6988 char status[64];
6989 int retstatus;
6990 struct ast_str *encmethods = ast_str_alloca(256);
6991
6992 char *tmp_host, *tmp_mask, *tmp_port;
6993
6994 tmp_host = ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr));
6995 tmp_mask = ast_strdupa(ast_sockaddr_stringify_addr(&peer->mask));
6996 tmp_port = ast_strdupa(ast_sockaddr_stringify_port(&peer->addr));
6997
6998 if (!ast_strlen_zero(peer->username)) {
6999 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
7000 } else {
7001 ast_copy_string(name, peer->name, sizeof(name));
7002 }
7003
7004 encmethods_to_str(peer->encmethods, &encmethods);
7005 retstatus = peer_status(peer, status, sizeof(status));
7006 if (retstatus > 0) {
7007 cont->online_peers++;
7008 } else if (!retstatus) {
7009 cont->offline_peers++;
7010 } else {
7011 cont->unmonitored_peers++;
7012 }
7013
7014 if (s) {
7015 if (cont->peerlist) { /* IAXpeerlist */
7016 astman_append(s,
7017 "Event: PeerEntry\r\n%s"
7018 "Channeltype: IAX\r\n",
7019 cont->idtext);
7020 if (!ast_strlen_zero(peer->username)) {
7021 astman_append(s,
7022 "ObjectName: %s\r\n"
7023 "ObjectUsername: %s\r\n",
7024 peer->name,
7025 peer->username);
7026 } else {
7027 astman_append(s,
7028 "ObjectName: %s\r\n",
7029 name);
7030 }
7031 } else { /* IAXpeers */
7032 astman_append(s,
7033 "Event: PeerEntry\r\n%s"
7034 "Channeltype: IAX2\r\n"
7035 "ObjectName: %s\r\n",
7036 cont->idtext,
7037 name);
7038 }
7039 astman_append(s,
7040 "ChanObjectType: peer\r\n"
7041 "IPaddress: %s\r\n",
7042 tmp_host);
7043 if (cont->peerlist) { /* IAXpeerlist */
7044 astman_append(s,
7045 "Mask: %s\r\n"
7046 "Port: %s\r\n",
7047 tmp_mask,
7048 tmp_port);
7049 } else { /* IAXpeers */
7050 astman_append(s,
7051 "IPport: %s\r\n",
7052 tmp_port);
7053 }
7054 astman_append(s,
7055 "Dynamic: %s\r\n"
7056 "Trunk: %s\r\n"
7057 "Encryption: %s\r\n"
7058 "Status: %s\r\n",
7059 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
7060 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
7061 peer->encmethods ? ast_str_buffer(encmethods) : "no",
7062 status);
7063 if (cont->peerlist) { /* IAXpeerlist */
7064 astman_append(s, "\r\n");
7065 } else { /* IAXpeers */
7066 astman_append(s,
7067 "Description: %s\r\n\r\n",
7068 peer->description);
7069 }
7070 } else {
7072 name,
7073 tmp_host,
7074 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
7075 tmp_mask,
7076 tmp_port,
7077 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ",
7078 peer->encmethods ? "(E)" : " ",
7079 status,
7080 peer->description);
7081 }
7082
7083 cont->total_peers++;
7084}
jack_status_t status
Definition: app_jack.c:149
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define IAX_TRUNK
Definition: chan_iax2.c:525
static void encmethods_to_str(int e, struct ast_str **buf)
Definition: chan_iax2.c:1823
static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
peer_status: Report Peer status in character string
Definition: chan_iax2.c:3865
#define IAX_DYNAMIC
Definition: chan_iax2.c:528
#define PEERS_FORMAT
Definition: chan_iax2.c:6983
static const char name[]
Definition: format_mp3.c:68
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1907
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:623
const ast_string_field description
Definition: chan_iax2.c:623
struct ast_sockaddr mask
Definition: chan_iax2.c:629
int encmethods
Definition: chan_iax2.c:636
char idtext[256]
Definition: chan_iax2.c:6973

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

14680{
14681 struct chan_iax2_pvt *pvt;
14682 unsigned int callno;
14683 int res = 0;
14684
14685 if (!chan || ast_channel_tech(chan) != &iax2_tech) {
14686 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
14687 return -1;
14688 }
14689
14692 if (!(pvt = iaxs[callno])) {
14694 return -1;
14695 }
14696
14697 if (!strcasecmp(args, "osptoken")) {
14698 ast_copy_string(buf, pvt->osptoken, buflen);
14699 } else if (!strcasecmp(args, "peerip")) {
14701 } else if (!strcasecmp(args, "peername")) {
14702 ast_copy_string(buf, pvt->username, buflen);
14703 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
14704 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
14705 } else {
14706 res = -1;
14707 }
14708
14710
14711 return res;
14712}
#define IAX_CALLENCRYPTED(pvt)
Definition: chan_iax2.c:464
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
const ast_string_field username
Definition: chan_iax2.c:886
const ast_string_field osptoken
Definition: chan_iax2.c:886
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 10159 of file chan_iax2.c.

10160{
10161 struct ast_datastore *variablestore;
10162 AST_LIST_HEAD(, ast_var_t) *varlist;
10163 struct ast_var_t *var;
10164
10165 if (!chan) {
10166 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
10167 return -1;
10168 }
10169
10171 if (!variablestore) {
10172 *buf = '\0';
10173 return 0;
10174 }
10175 varlist = variablestore->data;
10176
10177 AST_LIST_LOCK(varlist);
10178 AST_LIST_TRAVERSE(varlist, var, entries) {
10179 if (strcmp(var->name, data) == 0) {
10180 ast_copy_string(buf, var->value, len);
10181 break;
10182 }
10183 }
10184 AST_LIST_UNLOCK(varlist);
10185 return 0;
10186}
#define var
Definition: ast_expr2f.c:605
static const struct ast_datastore_info iax2_variable_datastore_info
Definition: chan_iax2.c:1595
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:2368
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::@213 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 10188 of file chan_iax2.c.

10189{
10190 struct ast_datastore *variablestore;
10191 AST_LIST_HEAD(, ast_var_t) *varlist;
10192 struct ast_var_t *var;
10193
10194 if (!chan) {
10195 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
10196 return -1;
10197 }
10198
10200 if (!variablestore) {
10202 if (!variablestore) {
10203 ast_log(LOG_ERROR, "Memory allocation error\n");
10204 return -1;
10205 }
10206 varlist = ast_calloc(1, sizeof(*varlist));
10207 if (!varlist) {
10208 ast_datastore_free(variablestore);
10209 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
10210 return -1;
10211 }
10212
10213 AST_LIST_HEAD_INIT(varlist);
10214 variablestore->data = varlist;
10215 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10216 ast_channel_datastore_add(chan, variablestore);
10217 } else
10218 varlist = variablestore->data;
10219
10220 AST_LIST_LOCK(varlist);
10222 if (strcmp(var->name, data) == 0) {
10225 break;
10226 }
10227 }
10229 var = ast_var_assign(data, value);
10230 if (var)
10231 AST_LIST_INSERT_TAIL(varlist, var, entries);
10232 else
10233 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
10234 AST_LIST_UNLOCK(varlist);
10235 return 0;
10236}
#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:2354
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:194
#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 1584 of file chan_iax2.c.

1586{
1588 return;
1589 }
1590
1591 ast_log(LOG_NOTICE, "Reloading chan_iax2 in response to ACL change event.\n");
1592 reload_config(1);
1593}
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:14230
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 1542 of file chan_iax2.c.

1543{
1544 if (!acl_change_sub) {
1549 }
1550}
static struct stasis_subscription * acl_change_sub
Definition: chan_iax2.c:352
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: chan_iax2.c:1584
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:1050
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:1104
#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 1552 of file chan_iax2.c.

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

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

2869{
2870 struct addr_range tmp;
2871 struct addr_range *addr_range = NULL;
2872 struct ast_ha *ha = NULL;
2873 int error = 0;
2874
2875 if (ast_strlen_zero(addr)) {
2876 ast_log(LOG_WARNING, "invalid calltokenoptional (null)\n");
2877 return -1;
2878 }
2879
2880 ha = ast_append_ha("permit", addr, NULL, &error);
2881
2882 /* check for valid config information */
2883 if (error) {
2884 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
2885 return -1;
2886 }
2887
2888 ast_copy_ha(ha, &tmp.ha);
2889 /* find or create the addr_range */
2892 addr_range->delme = 0;
2894 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
2895 /* copy over config data into addr_range object */
2896 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
2898 } else {
2899 ast_free_ha(ha);
2900 return -1;
2901 }
2902
2903 ast_free_ha(ha);
2904 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
2905
2906 return 0;
2907}
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
struct ast_ha ha
Definition: chan_iax2.c:1067
unsigned char delme
Definition: chan_iax2.c:1071
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, and OBJ_POINTER.

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

4899{
4900 /* first make sure their are two empty bytes left in ied->buf */
4901 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
4902 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */
4903 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */
4904 pvt->calltoken_ie_len = 2;
4905 }
4906}
#define IAX_IE_CALLTOKEN
Definition: iax2.h:185
unsigned char calltoken_ie_len
Definition: chan_iax2.c:958
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 2524 of file chan_iax2.c.

2525{
2526 struct addr_range *lim1 = obj, *lim2 = arg;
2527 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
2528 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
2529 CMP_MATCH | CMP_STOP : 0;
2530}
@ 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 2511 of file chan_iax2.c.

2512{
2513 struct addr_range *lim = obj;
2514 lim->delme = 1;
2515 return 0;
2516}

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

2519{
2520 const struct addr_range *lim = obj;
2521 return abs(ast_sockaddr_hash(&lim->ha.addr));
2522}
#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 2548 of file chan_iax2.c.

2549{
2550 struct addr_range *addr_range = obj;
2551 struct ast_sockaddr *addr = arg;
2552 struct ast_sockaddr tmp_addr;
2553
2554 ast_sockaddr_apply_netmask(addr, &addr_range->ha.netmask, &tmp_addr);
2555
2556 if (!ast_sockaddr_cmp_addr(&tmp_addr, &addr_range->ha.addr)) {
2557 return CMP_MATCH | CMP_STOP;
2558 }
2559 return 0;
2560}
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 7916 of file chan_iax2.c.

7917{
7918 while(con) {
7919 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
7920 return -1;
7921 con = con->next;
7922 }
7923 return 0;
7924}
char context[AST_MAX_CONTEXT]
Definition: chan_iax2.c:517
struct iax2_context * next
Definition: chan_iax2.c:518

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

7618{
7619 int x;
7620 int numchans = 0;
7621 char first_message[10] = { 0, };
7622 char last_message[10] = { 0, };
7623#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"
7624#define ACN_FORMAT2 "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
7625 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
7626 ast_mutex_lock(&iaxsl[x]);
7627 if (iaxs[x]) {
7628 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
7629 jb_info jbinfo;
7630 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
7631 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
7632
7634 jb_getinfo(iaxs[x]->jb, &jbinfo);
7635 localjitter = jbinfo.jitter;
7636 localdelay = jbinfo.current - jbinfo.min;
7637 locallost = jbinfo.frames_lost;
7638 locallosspct = jbinfo.losspct/1000;
7639 localdropped = jbinfo.frames_dropped;
7640 localooo = jbinfo.frames_ooo;
7641 } else {
7642 localjitter = -1;
7643 localdelay = 0;
7644 locallost = -1;
7645 locallosspct = -1;
7646 localdropped = 0;
7647 localooo = -1;
7648 }
7649 if (s)
7650 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
7651 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
7652 iaxs[x]->pingtime,
7653 localjitter,
7654 localdelay,
7655 locallost,
7656 locallosspct,
7657 localdropped,
7658 localooo,
7659 iaxs[x]->frames_received/1000,
7660 iaxs[x]->remote_rr.jitter,
7661 iaxs[x]->remote_rr.delay,
7665 iaxs[x]->remote_rr.ooo,
7666 iaxs[x]->remote_rr.packets/1000,
7667 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7668 first_message,
7669 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7670 last_message);
7671 else
7672 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
7673 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
7674 iaxs[x]->pingtime,
7675 localjitter,
7676 localdelay,
7677 locallost,
7678 locallosspct,
7679 localdropped,
7680 localooo,
7681 iaxs[x]->frames_received/1000,
7682 iaxs[x]->remote_rr.jitter,
7683 iaxs[x]->remote_rr.delay,
7687 iaxs[x]->remote_rr.ooo,
7688 iaxs[x]->remote_rr.packets/1000,
7689 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7690 first_message,
7691 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7692 last_message);
7693 numchans++;
7694 }
7696 }
7697
7698 return numchans;
7699}
#define MARK_IAX_SUBCLASS_TX
Definition: chan_iax2.c:742
#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:790
struct iax_rr remote_rr
Definition: chan_iax2.c:948
int last_iax_message
Definition: chan_iax2.c:792
int ooo
Definition: chan_iax2.c:757
int losscnt
Definition: chan_iax2.c:753
int delay
Definition: chan_iax2.c:755
int losspct
Definition: chan_iax2.c:752
int dropped
Definition: chan_iax2.c:756
int packets
Definition: chan_iax2.c:754
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 5946 of file chan_iax2.c.

5949{
5950 struct ast_channel *tmp = NULL;
5951 struct chan_iax2_pvt *i;
5952 struct iax2_peer *peer;
5953 struct ast_variable *v = NULL;
5954 struct ast_format_cap *native;
5955 struct ast_format *tmpfmt;
5956 ast_callid callid;
5957 char *peer_name = NULL;
5958
5959 if (!(i = iaxs[callno])) {
5960 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
5961 return NULL;
5962 }
5963
5964 if (!capability) {
5965 ast_log(LOG_WARNING, "No formats specified for call to: IAX2/%s-%d\n",
5966 i->host, i->callno);
5967 return NULL;
5968 }
5970 if (!native) {
5971 return NULL;
5972 }
5973 if (iax2_codec_pref_best_bitfield2cap(capability, prefs, native)
5974 || !ast_format_cap_count(native)) {
5975 ast_log(LOG_WARNING, "No requested formats available for call to: IAX2/%s-%d\n",
5976 i->host, i->callno);
5977 ao2_ref(native, -1);
5978 return NULL;
5979 }
5980
5981 if (!ast_strlen_zero(i->peer)) {
5982 peer_name = ast_strdupa(i->peer);
5983 } else if (!ast_strlen_zero(i->host)) {
5984 peer_name = ast_strdupa(i->host);
5985 }
5986
5987 /* Don't hold call lock while making a channel or looking up a peer */
5988 ast_mutex_unlock(&iaxsl[callno]);
5989
5990 if (!ast_strlen_zero(peer_name)) {
5991 peer = find_peer(peer_name, 1);
5992 if (peer && peer->endpoint) {
5994 i->accountcode, i->exten, i->context, assignedids, requestor,
5995 i->amaflags, peer->endpoint, "IAX2/%s-%d", i->host, i->callno);
5996 }
5997 ao2_cleanup(peer);
5998 }
5999
6000 if (!tmp) {
6001 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode,
6002 i->exten, i->context, assignedids, requestor, i->amaflags, "IAX2/%s-%d",
6003 i->host, i->callno);
6004 }
6005
6006 ast_mutex_lock(&iaxsl[callno]);
6007 if (i != iaxs[callno]) {
6008 if (tmp) {
6009 /* unlock and relock iaxsl[callno] to preserve locking order */
6010 ast_mutex_unlock(&iaxsl[callno]);
6011 ast_channel_unlock(tmp);
6012 tmp = ast_channel_release(tmp);
6013 ast_mutex_lock(&iaxsl[callno]);
6014 }
6015 ao2_ref(native, -1);
6016 return NULL;
6017 }
6018 if (!tmp) {
6019 ao2_ref(native, -1);
6020 return NULL;
6021 }
6022
6024
6025 if ((callid = iaxs[callno]->callid)) {
6026 ast_channel_callid_set(tmp, callid);
6027 }
6028
6030
6031 /* We can support any format by default, until we get restricted */
6032 ast_channel_nativeformats_set(tmp, native);
6033 tmpfmt = ast_format_cap_get_format(native, 0);
6034
6035 ast_channel_set_readformat(tmp, tmpfmt);
6036 ast_channel_set_rawreadformat(tmp, tmpfmt);
6037 ast_channel_set_writeformat(tmp, tmpfmt);
6038 ast_channel_set_rawwriteformat(tmp, tmpfmt);
6039
6040 ao2_ref(tmpfmt, -1);
6041 ao2_ref(native, -1);
6042
6044
6045 if (!ast_strlen_zero(i->parkinglot))
6046 ast_channel_parkinglot_set(tmp, i->parkinglot);
6047 /* Don't use ast_set_callerid() here because it will
6048 * generate a NewCallerID event before the NewChannel event */
6049 if (!ast_strlen_zero(i->ani)) {
6052 } else if (!ast_strlen_zero(i->cid_num)) {
6055 }
6057 if (!ast_strlen_zero(i->rdnis)) {
6060 }
6066 if (!ast_strlen_zero(i->language))
6067 ast_channel_language_set(tmp, i->language);
6069 ast_channel_accountcode_set(tmp, i->accountcode);
6070 if (i->amaflags)
6074 if (i->adsi)
6076 else
6078 i->owner = tmp;
6079 i->capability = capability;
6080
6081 if (!cachable) {
6083 }
6084
6085 /* Set inherited variables */
6086 if (i->vars) {
6087 for (v = i->vars ; v ; v = v->next)
6089 }
6090 if (i->iaxvars) {
6091 struct ast_datastore *variablestore;
6092 struct ast_variable *var, *prev = NULL;
6093 AST_LIST_HEAD(, ast_var_t) *varlist;
6094 ast_debug(1, "Loading up the channel with IAXVARs\n");
6095 varlist = ast_calloc(1, sizeof(*varlist));
6097 if (variablestore && varlist) {
6098 variablestore->data = varlist;
6099 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
6100 AST_LIST_HEAD_INIT(varlist);
6101 for (var = i->iaxvars; var; var = var->next) {
6102 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
6103 if (prev)
6104 ast_free(prev);
6105 prev = var;
6106 if (!newvar) {
6107 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
6108 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
6109 } else {
6110 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
6111 }
6112 }
6113 if (prev)
6114 ast_free(prev);
6115 i->iaxvars = NULL;
6116 ast_channel_datastore_add(i->owner, variablestore);
6117 } else {
6118 if (variablestore) {
6119 ast_datastore_free(variablestore);
6120 }
6121 if (varlist) {
6122 ast_free(varlist);
6123 }
6124 }
6125 }
6126
6128 ast_channel_unlock(tmp);
6129
6130 if (state != AST_STATE_DOWN) {
6131 if (ast_pbx_start(tmp)) {
6132 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
6133 /* unlock and relock iaxsl[callno] to preserve locking order */
6134 ast_mutex_unlock(&iaxsl[callno]);
6135 ast_hangup(tmp);
6136 ast_mutex_lock(&iaxsl[callno]);
6137 return NULL;
6138 }
6139 }
6140
6142 return tmp;
6143}
#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:317
static struct iax2_peer * find_peer(const char *name, int realtime)
Definition: chan_iax2.c:2082
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:1303
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2510
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1299
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:891
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:1551
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
@ AST_FLAG_DISABLE_DEVSTATE_CACHE
Definition: channel.h:1049
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)
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:2973
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:457
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:4723
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:356
struct ast_party_id id
Caller party ID.
Definition: channel.h:422
int ani2
Automatic Number Identification 2 (Info Digits)
Definition: channel.h:435
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:429
struct ast_party_dialed::@210 number
Dialed/Called number.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:388
int transit_network_select
Transit Network Select.
Definition: channel.h:399
struct ast_party_name name
Subscriber name.
Definition: channel.h:342
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:344
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:279
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:297
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:299
char * str
Subscriber phone number (Malloced)
Definition: channel.h:293
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:295
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:529
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
struct ast_variable * vars
Definition: chan_iax2.c:944
const ast_string_field language
Definition: chan_iax2.c:886
int calling_ani2
Definition: chan_iax2.c:940
const ast_string_field cid_num
Definition: chan_iax2.c:886
iax2_format capability
Definition: chan_iax2.c:780
const ast_string_field accountcode
Definition: chan_iax2.c:886
struct ast_variable * iaxvars
Definition: chan_iax2.c:946
const ast_string_field context
Definition: chan_iax2.c:886
const ast_string_field rdnis
Definition: chan_iax2.c:886
int calling_pres
Definition: chan_iax2.c:939
const ast_string_field exten
Definition: chan_iax2.c:886
const ast_string_field ani
Definition: chan_iax2.c:886
const ast_string_field cid_name
Definition: chan_iax2.c:886
const ast_string_field dnid
Definition: chan_iax2.c:886
const ast_string_field peer
Definition: chan_iax2.c:886
#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, 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 15186 of file chan_iax2.c.

◆ attempt_transmit()

static int attempt_transmit ( const void *  data)
static

Definition at line 3704 of file chan_iax2.c.

3705{
3706#ifdef SCHED_MULTITHREADED
3708#endif
3709 __attempt_transmit(data);
3710 return 0;
3711}
#define schedule_action(func, data)
Definition: chan_iax2.c:1750
static void __attempt_transmit(const void *data)
Definition: chan_iax2.c:3621

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

9499{
9500 /* Schedule sending the authentication failure in one second, to prevent
9501 guessing */
9502 if (iaxs[callno]) {
9503 iaxs[callno]->authfail = failcode;
9504 if (delayreject) {
9505 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
9506 sched, 1000, auth_reject, (void *)(long)callno);
9507 } else
9508 auth_reject((void *)(long)callno);
9509 }
9510 return 0;
9511}
static int delayreject
Definition: chan_iax2.c:502
static int auth_reject(const void *data)
Definition: chan_iax2.c:9484
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:1753

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

440{
441 char *pos = buf;
442
443 *pos = '\0';
444
445 if (authmethods & IAX_AUTH_RSA) {
446 pos += sprintf(pos, "|RSA");
447 }
448 if (authmethods & IAX_AUTH_MD5) {
449 pos += sprintf(pos, "|MD5");
450 }
451 if (authmethods & IAX_AUTH_PLAINTEXT) {
452 pos += sprintf(pos, "|plaintext");
453 }
454
455 if (pos == buf) { /* No auth methods */
456 strcpy(buf, "none");
457 return buf;
458 }
459
460 return buf + 1; /* Skip leading | */
461}
#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 9484 of file chan_iax2.c.

9485{
9486 int callno = (int)(long)(data);
9487 ast_mutex_lock(&iaxsl[callno]);
9488 if (iaxs[callno])
9489 iaxs[callno]->authid = -1;
9490 ast_mutex_unlock(&iaxsl[callno]);
9491#ifdef SCHED_MULTITHREADED
9492 if (schedule_action(__auth_reject, data))
9493#endif
9494 __auth_reject(data);
9495 return 0;
9496}
static void __auth_reject(const void *nothing)
Definition: chan_iax2.c:9464

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

8506{
8507 int res = -1;
8508 int x;
8509 if (!ast_strlen_zero(keyn)) {
8510 if (!(authmethods & IAX_AUTH_RSA)) {
8511 if (ast_strlen_zero(secret)) {
8512 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));
8513 }
8514 } else if (ast_strlen_zero(challenge)) {
8515 ast_log(LOG_WARNING, "No challenge provided for RSA authentication to %s\n", ast_sockaddr_stringify_addr(addr));
8516 } else {
8517 char sig[256];
8518 struct ast_key *key;
8519 key = ast_key_get(keyn, AST_KEY_PRIVATE);
8520 if (!key) {
8521 ast_log(LOG_WARNING, "Unable to find private key '%s'\n", keyn);
8522 } else {
8523 if (ast_sign(key, (char*)challenge, sig)) {
8524 ast_log(LOG_WARNING, "Unable to sign challenge with key\n");
8525 res = -1;
8526 } else {
8528 if (pvt) {
8530 }
8531 res = 0;
8532 }
8533 }
8534
8535 if (pvt && !ast_strlen_zero(secret)) {
8536 struct MD5Context md5;
8537 unsigned char digest[16];
8538
8539 MD5Init(&md5);
8540 MD5Update(&md5, (unsigned char *) challenge, strlen(challenge));
8541 MD5Update(&md5, (unsigned char *) secret, strlen(secret));
8542 MD5Final(digest, &md5);
8543
8544 build_encryption_keys(digest, pvt);
8545 }
8546 }
8547 }
8548 /* Fall back */
8549 if (res && !ast_strlen_zero(secret)) {
8550 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
8551 struct MD5Context md5;
8552 unsigned char digest[16];
8553 char digres[128];
8554 MD5Init(&md5);
8555 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
8556 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
8557 MD5Final(digest, &md5);
8558 /* If they support md5, authenticate with it. */
8559 for (x=0;x<16;x++)
8560 sprintf(digres + (x << 1), "%02hhx", digest[x]); /* safe */
8561 if (pvt) {
8562 build_encryption_keys(digest, pvt);
8564 }
8566 res = 0;
8567 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
8568 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
8569 if (pvt) {
8571 }
8572 res = 0;
8573 } else
8574 ast_log(LOG_WARNING, "No way to send secret to peer '%s' (their methods: %d)\n", ast_sockaddr_stringify_addr(addr), authmethods);
8575 }
8576 return res;
8577}
static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:6499
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:55
#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[MD5_DIGEST_LENGTH], struct MD5Context *context)
Definition: md5.c:120
static void challenge(const char *endpoint_id, struct ast_sip_auth *auth, pjsip_tx_data *tdata, const pjsip_rx_data *rdata, int is_stale, const pjsip_auth_algorithm *algorithm)
Send a WWW-Authenticate challenge.
Definition: md5.h:30
int eff_auth_method
Definition: chan_iax2.c:892

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

8584{
8585 struct iax2_peer *peer = NULL;
8586 /* Start pessimistic */
8587 int res = -1;
8588 int authmethods = 0;
8589 struct iax_ie_data ied;
8590 uint16_t callno = p->callno;
8591
8592 memset(&ied, 0, sizeof(ied));
8593
8594 if (ies->username)
8595 ast_string_field_set(p, username, ies->username);
8596 if (ies->challenge)
8598 if (ies->authmethods)
8599 authmethods = ies->authmethods;
8600 if (authmethods & IAX_AUTH_MD5)
8602 else
8603 p->encmethods = 0;
8604
8605 /* Check for override RSA authentication first */
8606 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
8607 /* Normal password authentication */
8608 res = authenticate(p->challenge, override, okey, authmethods, &ied, addr, p);
8609 } else {
8610 struct ao2_iterator i = ao2_iterator_init(peers, 0);
8611 while ((peer = ao2_iterator_next(&i))) {
8612 struct ast_sockaddr peer_addr;
8613 struct ast_sockaddr tmp_sockaddr1;
8614 struct ast_sockaddr tmp_sockaddr2;
8615
8616 ast_sockaddr_copy(&peer_addr, &peer->addr);
8617
8618 ast_sockaddr_apply_netmask(addr, &peer->mask, &tmp_sockaddr1);
8619 ast_sockaddr_apply_netmask(&peer_addr, &peer->mask, &tmp_sockaddr2);
8620
8621 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
8622 /* No peer specified at our end, or this is the peer */
8623 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
8624 /* No username specified in peer rule, or this is the right username */
8625 && (ast_sockaddr_isnull(&peer_addr) || !(ast_sockaddr_cmp_addr(&tmp_sockaddr1, &tmp_sockaddr2)))
8626 /* No specified host, or this is our host */
8627 ) {
8628 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, addr, p);
8629 if (!res) {
8630 peer_unref(peer);
8631 break;
8632 }
8633 }
8634 peer_unref(peer);
8635 }
8637 if (!peer) {
8638 /* We checked our list and didn't find one. It's unlikely, but possible,
8639 that we're trying to authenticate *to* a realtime peer */
8640 const char *peer_name = ast_strdupa(p->peer);
8641 ast_mutex_unlock(&iaxsl[callno]);
8642 if ((peer = realtime_peer(peer_name, NULL))) {
8643 ast_mutex_lock(&iaxsl[callno]);
8644 if (!(p = iaxs[callno])) {
8645 peer_unref(peer);
8646 return -1;
8647 }
8648 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, addr, p);
8649 peer_unref(peer);
8650 }
8651 if (!peer) {
8652 ast_mutex_lock(&iaxsl[callno]);
8653 if (!(p = iaxs[callno]))
8654 return -1;
8655 }
8656 }
8657 }
8658
8659 if (!(ies->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT)) && (ies->authmethods & IAX_AUTH_RSA) && ast_strlen_zero(okey)) {
8660 /* If the only thing available is RSA, and we don't have an outkey, we can't do it... */
8661 ast_log(LOG_WARNING, "Call terminated. RSA authentication requires an outkey\n");
8662 return -1;
8663 }
8664
8665 if (ies->encmethods) {
8666 if (ast_strlen_zero(p->secret) &&
8668 ast_log(LOG_WARNING, "Call terminated. Encryption requested by peer but no secret available locally\n");
8669 return -1;
8670 }
8671 /* Don't even THINK about trying to encrypt or decrypt anything if we don't have valid keys, for some reason... */
8672 /* If either of these happens, it's our fault, not the user's. But we should abort rather than crash. */
8676 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
8677 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n");
8678 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */
8679 }
8680 if (!res) {
8681 struct ast_datastore *variablestore;
8682 struct ast_variable *var, *prev = NULL;
8683 AST_LIST_HEAD(, ast_var_t) *varlist;
8684 varlist = ast_calloc(1, sizeof(*varlist));
8686 if (variablestore && varlist && p->owner) {
8687 variablestore->data = varlist;
8688 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
8689 AST_LIST_HEAD_INIT(varlist);
8690 for (var = ies->vars; var; var = var->next) {
8691 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
8692 if (prev)
8693 ast_free(prev);
8694 prev = var;
8695 if (!newvar) {
8696 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */
8697 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
8698 } else {
8699 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
8700 }
8701 }
8702 if (prev)
8703 ast_free(prev);
8704 ies->vars = NULL;
8705 ast_channel_datastore_add(p->owner, variablestore);
8706 } else {
8707 if (p->owner)
8708 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
8709 if (variablestore)
8710 ast_datastore_free(variablestore);
8711 if (varlist)
8712 ast_free(varlist);
8713 }
8714 }
8715
8716 if (!res)
8717 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
8718 return res;
8719}
static struct iax2_peer * realtime_peer(const char *peername, struct ast_sockaddr *addr)
Definition: chan_iax2.c:4457
#define IAX_ENCRYPTED
Definition: chan_iax2.c:534
static int invalid_key(ast_aes_decrypt_key *ecx)
Definition: chan_iax2.c:6483
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:8505
#define IAX_KEYPOPULATED
Definition: chan_iax2.c:535
static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
Definition: chan_iax2.c:8176
@ IAX_COMMAND_AUTHREP
Definition: iax2.h:60
const ast_string_field challenge
Definition: chan_iax2.c:886
ast_aes_decrypt_key dcx
Definition: chan_iax2.c:900
const ast_string_field secret
Definition: chan_iax2.c:886
ast_aes_encrypt_key ecx
Definition: chan_iax2.c:896
const ast_string_field outkey
Definition: chan_iax2.c:623
int authmethods
Definition: chan_iax2.c:635
const ast_string_field secret
Definition: chan_iax2.c:623
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 8197 of file chan_iax2.c.

8198{
8199 struct iax_ie_data ied;
8200 int res = -1, authreq_restrict = 0;
8201 char challenge[10];
8202 struct chan_iax2_pvt *p = iaxs[call_num];
8203
8204 memset(&ied, 0, sizeof(ied));
8205
8206 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
8208 struct iax2_user *user;
8209
8211 if (user) {
8212 if (user->curauthreq == user->maxauthreq)
8213 authreq_restrict = 1;
8214 else
8215 user->curauthreq++;
8216 user = user_unref(user);
8217 }
8218 }
8219
8220 /* If the AUTHREQ limit test failed, send back an error */
8221 if (authreq_restrict) {
8222 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
8224 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
8225 return 0;
8226 }
8227
8229 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
8230 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
8232 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
8234 }
8235 if (p->encmethods)
8237
8239
8240 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
8241
8242 if (p->encmethods)
8244
8245 return res;
8246}
#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:2112
#define IAX_MAXAUTHREQ
Definition: chan_iax2.c:545
@ 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 8248 of file chan_iax2.c.

8249{
8250 char requeststr[256];
8251 char md5secret[256] = "";
8252 char secret[256] = "";
8253 char rsasecret[256] = "";
8254 int res = -1;
8255 int x;
8256 struct iax2_user *user;
8257
8258 if (p->authrej) {
8259 return res;
8260 }
8261
8263 if (user) {
8265 ast_atomic_fetchadd_int(&user->curauthreq, -1);
8267 }
8268 ast_string_field_set(p, host, user->name);
8269 user = user_unref(user);
8270 }
8272 ast_log(LOG_WARNING, "Call Terminated, incoming call is unencrypted while force encrypt is enabled.\n");
8273 return res;
8274 }
8276 return res;
8277 if (ies->password)
8278 ast_copy_string(secret, ies->password, sizeof(secret));
8279 if (ies->md5_result)
8280 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
8281 if (ies->rsa_result)
8282 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
8283 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
8284 struct ast_key *key;
8285 char *keyn;
8286 char *tmpkey;
8287 char *stringp=NULL;
8288 if (!(tmpkey = ast_strdup(p->inkeys))) {
8289 ast_log(LOG_ERROR, "Unable to create a temporary string for parsing stored 'inkeys'\n");
8290 return res;
8291 }
8292 stringp = tmpkey;
8293 keyn = strsep(&stringp, ":");
8294 while(keyn) {
8295 key = ast_key_get(keyn, AST_KEY_PUBLIC);
8296 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
8297 res = 0;
8299 break;
8300 } else if (!key) {
8301 ast_log(LOG_WARNING, "Requested inkey '%s' for RSA authentication does not exist\n", keyn);
8302 }
8303 keyn = strsep(&stringp, ":");
8304 }
8305 ast_free(tmpkey);
8306 if (res && authdebug) {
8307 ast_log(LOG_WARNING, "No RSA public keys on file matched incoming call\n");
8308 }
8309 } else if (p->authmethods & IAX_AUTH_MD5) {
8310 struct MD5Context md5;
8311 unsigned char digest[16];
8312 char *tmppw, *stringp;
8313 tmppw = ast_strdupa(p->secret);
8314 stringp = tmppw;
8315 while((tmppw = strsep(&stringp, ";"))) {
8316 MD5Init(&md5);
8317 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
8318 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
8319 MD5Final(digest, &md5);
8320 /* If they support md5, authenticate with it. */
8321 for (x=0;x<16;x++)
8322 sprintf(requeststr + (x << 1), "%02hhx", digest[x]); /* safe */
8323 if (!strcasecmp(requeststr, md5secret)) {
8324 res = 0;
8326 break;
8327 } else if (authdebug) {
8328 ast_log(LOG_WARNING, "MD5 secret mismatch\n");
8329 }
8330 }
8331 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
8332 if (!strcmp(secret, p->secret)) {
8333 res = 0;
8335 } else if (authdebug) {
8336 ast_log(LOG_WARNING, "Plaintext secret mismatch\n");
8337 }
8338 }
8339 return res;
8340}
char * strsep(char **str, const char *delims)
static int authdebug
Definition: chan_iax2.c:369
#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
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:764
const ast_string_field inkeys
Definition: chan_iax2.c:886
struct ast_flags state
Definition: chan_iax2.c:835
const ast_string_field secret
Definition: chan_iax2.c:585
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 4835 of file chan_iax2.c.

4836{
4837#ifdef SCHED_MULTITHREADED
4839#endif
4840 __auto_congest(data);
4841 return 0;
4842}
static void __auto_congest(const void *nothing)
Definition: chan_iax2.c:4822

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

9529{
9530 int callno = (int)(long)(data);
9531 ast_mutex_lock(&iaxsl[callno]);
9532 if (iaxs[callno]) {
9533 iaxs[callno]->autoid = -1;
9534 }
9535 ast_mutex_unlock(&iaxsl[callno]);
9536#ifdef SCHED_MULTITHREADED
9537 if (schedule_action(__auto_hangup, data))
9538#endif
9539 __auto_hangup(data);
9540 return 0;
9541}
static void __auto_hangup(const void *nothing)
Definition: chan_iax2.c:9513

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

2814{
2815 struct addr_range *addr_range = NULL;
2816 struct addr_range tmp;
2817 struct ast_ha *ha;
2818 int limit;
2819 int error;
2820 int found;
2821
2822 for (; v; v = v->next) {
2823 limit = -1;
2824 error = 0;
2825 found = 0;
2826 ha = ast_append_ha("permit", v->name, NULL, &error);
2827
2828 /* check for valid config information */
2829 if (error) {
2830 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
2831 continue;
2832 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
2833 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
2834 ast_free_ha(ha);
2835 continue;
2836 }
2837
2838 ast_copy_ha(ha, &tmp.ha);
2839 /* find or create the addr_range */
2840 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
2842 found = 1;
2843 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
2844 ast_free_ha(ha);
2845 return; /* out of memory */
2846 }
2847
2848 /* copy over config data into addr_range object */
2849 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
2850 ast_free_ha(ha); /* cleanup the tmp ha */
2851 addr_range->limit = limit;
2852 addr_range->delme = 0;
2853
2854 /* cleanup */
2855 if (found) {
2857 } else {
2859 }
2860 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
2861 }
2862}
uint16_t limit
Definition: chan_iax2.c:1069

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, and ast_variable::value.

Referenced by set_config().

◆ build_context()

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

Definition at line 12865 of file chan_iax2.c.

12866{
12867 struct iax2_context *con;
12868
12869 if ((con = ast_calloc(1, sizeof(*con))))
12870 ast_copy_string(con->context, context, sizeof(con->context));
12871
12872 return con;
12873}

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

6506{
6507 /* it is required to hold the corresponding decrypt key to our encrypt key
6508 * in the pvt struct because queued frames occasionally need to be decrypted and
6509 * re-encrypted when updated for a retransmission */
6510 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
6511 ast_aes_set_encrypt_key(digest, &pvt->ecx);
6512 ast_aes_set_decrypt_key(digest, &pvt->mydcx);
6513}
static void build_rand_pad(unsigned char *buf, ssize_t len)
Definition: chan_iax2.c:6473
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:905
ast_aes_decrypt_key mydcx
Definition: chan_iax2.c:898

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

6500{
6501 build_ecx_key(digest, pvt);
6502 ast_aes_set_decrypt_key(digest, &pvt->dcx);
6503}
static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:6505

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

13015{
13016 struct iax2_peer *peer = NULL;
13017 struct ast_acl_list *oldacl = NULL;
13018 int maskfound = 0;
13019 int found = 0;
13020 int firstpass = 1;
13021 int subscribe_acl_change = 0;
13022
13023 if (!temponly) {
13024 peer = ao2_find(peers, name, OBJ_KEY);
13025 if (peer && !ast_test_flag64(peer, IAX_DELME))
13026 firstpass = 0;
13027 }
13028
13029 if (peer) {
13030 found++;
13031 if (firstpass) {
13032 oldacl = peer->acl;
13033 peer->acl = NULL;
13034 }
13035 unlink_peer(peer);
13036 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
13037 peer->expire = -1;
13038 peer->pokeexpire = -1;
13039 peer->sockfd = defaultsockfd;
13040 if (ast_string_field_init(peer, 32))
13041 peer = peer_unref(peer);
13042 if (!(peer->endpoint = ast_endpoint_create("IAX2", name))) {
13043 peer = peer_unref(peer);
13044 }
13045 }
13046
13047 if (peer) {
13048 if (firstpass) {
13052 peer->adsi = adsi;
13053 ast_string_field_set(peer, secret, "");
13054 if (!found) {
13056 ast_sockaddr_parse(&peer->addr, "0.0.0.0", 0);
13058 peer->expiry = min_reg_expire;
13059 }
13060 peer->prefs = prefs_global;
13062 peer->smoothing = 0;
13065 peer->maxcallno = 0;
13066 peercnt_modify((unsigned char) 0, 0, &peer->addr);
13069 ast_string_field_set(peer,peercontext,"");
13071 ast_string_field_set(peer, cid_name, "");
13072 ast_string_field_set(peer, cid_num, "");
13075 }
13076
13077 if (!v) {
13078 v = alt;
13079 alt = NULL;
13080 }
13081 while(v) {
13082 if (!strcasecmp(v->name, "secret")) {
13083 ast_string_field_set(peer, secret, v->value);
13084 } else if (!strcasecmp(v->name, "mailbox")) {
13086 } else if (!strcasecmp(v->name, "hasvoicemail")) {
13087 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
13088 /*
13089 * hasvoicemail is a users.conf legacy voicemail enable method.
13090 * hasvoicemail is only going to work for app_voicemail mailboxes.
13091 */
13092 if (strchr(name, '@')) {
13094 } else {
13095 ast_string_field_build(peer, mailbox, "%s@default", name);
13096 }
13097 }
13098 } else if (!strcasecmp(v->name, "mohinterpret")) {
13100 } else if (!strcasecmp(v->name, "mohsuggest")) {
13102 } else if (!strcasecmp(v->name, "dbsecret")) {
13103 ast_string_field_set(peer, dbsecret, v->value);
13104 } else if (!strcasecmp(v->name, "description")) {
13105 ast_string_field_set(peer, description, v->value);
13106 } else if (!strcasecmp(v->name, "trunk")) {
13108 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
13109 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
13111 }
13112 } else if (!strcasecmp(v->name, "auth")) {
13114 if (peer->authmethods & IAX_AUTH_PLAINTEXT) {
13115 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);
13116 }
13117 } else if (!strcasecmp(v->name, "encryption")) {
13119 if (!peer->encmethods) {
13121 }
13122 } else if (!strcasecmp(v->name, "forceencryption")) {
13123 if (ast_false(v->value)) {
13125 } else {
13127 if (peer->encmethods) {
13129 }
13130 }
13131 } else if (!strcasecmp(v->name, "transfer")) {
13132 if (!strcasecmp(v->value, "mediaonly")) {
13134 } else if (ast_true(v->value)) {
13136 } else
13138 } else if (!strcasecmp(v->name, "jitterbuffer")) {
13140 } else if (!strcasecmp(v->name, "host")) {
13141 if (!strcasecmp(v->value, "dynamic")) {
13142 /* They'll register with us */
13144 if (!found) {
13145 int peer_port = ast_sockaddr_port(&peer->addr);
13146 if (peer_port) {
13147 ast_sockaddr_set_port(&peer->defaddr, peer_port);
13148 }
13149 ast_sockaddr_setnull(&peer->addr);
13150 }
13151 } else {
13152 /* Non-dynamic. Make sure we become that way if we're not */
13153 AST_SCHED_DEL(sched, peer->expire);
13155 if (peer->dnsmgr) {
13156 // Make sure we refresh dnsmgr if we're using it
13158 } else {
13159 // Or just invalidate the address
13160 peer->addr.ss.ss_family = AST_AF_UNSPEC;
13161 }
13162 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) {
13163 return peer_unref(peer);
13164 }
13165 if (!ast_sockaddr_port(&peer->addr)) {
13167 }
13168 }
13169 } else if (!strcasecmp(v->name, "defaultip")) {
13170 struct ast_sockaddr peer_defaddr_tmp;
13171 peer_defaddr_tmp.ss.ss_family = AF_UNSPEC;
13172 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
13173 return peer_unref(peer);
13174 }
13175 ast_sockaddr_set_port(&peer_defaddr_tmp, ast_sockaddr_port(&peer->defaddr));
13176 ast_sockaddr_copy(&peer->defaddr, &peer_defaddr_tmp);
13177 } else if (!strcasecmp(v->name, "sourceaddress")) {
13178 peer_set_srcaddr(peer, v->value);
13179 } else if (!strcasecmp(v->name, "permit") ||
13180 !strcasecmp(v->name, "deny") ||
13181 !strcasecmp(v->name, "acl")) {
13182 ast_append_acl(v->name, v->value, &peer->acl, NULL, &subscribe_acl_change);
13183 } else if (!strcasecmp(v->name, "mask")) {
13184 maskfound++;
13185 ast_sockaddr_parse(&peer->mask, v->value, 0);
13186 } else if (!strcasecmp(v->name, "context")) {
13188 } else if (!strcasecmp(v->name, "regexten")) {
13189 ast_string_field_set(peer, regexten, v->value);
13190 } else if (!strcasecmp(v->name, "peercontext")) {
13191 ast_string_field_set(peer, peercontext, v->value);
13192 } else if (!strcasecmp(v->name, "port")) {
13193 int bindport;
13194 if (ast_parse_arg(v->value, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535)) {
13195 bindport = IAX_DEFAULT_PORTNO;
13196 }
13197 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
13198 ast_sockaddr_set_port(&peer->defaddr, bindport);
13199 } else {
13200 ast_sockaddr_set_port(&peer->addr, bindport);
13201 }
13202 } else if (!strcasecmp(v->name, "username")) {
13203 ast_string_field_set(peer, username, v->value);
13204 } else if (!strcasecmp(v->name, "allow")) {
13205 iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
13206 } else if (!strcasecmp(v->name, "disallow")) {
13207 iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
13208 } else if (!strcasecmp(v->name, "callerid")) {
13209 if (!ast_strlen_zero(v->value)) {
13210 char name2[80];
13211 char num2[80];
13212 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
13213 ast_string_field_set(peer, cid_name, name2);
13214 ast_string_field_set(peer, cid_num, num2);
13215 } else {
13216 ast_string_field_set(peer, cid_name, "");
13217 ast_string_field_set(peer, cid_num, "");
13218 }
13220 } else if (!strcasecmp(v->name, "fullname")) {
13221 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
13223 } else if (!strcasecmp(v->name, "cid_number")) {
13224 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
13226 } else if (!strcasecmp(v->name, "sendani")) {
13228 } else if (!strcasecmp(v->name, "inkeys")) {
13229 ast_string_field_set(peer, inkeys, v->value);
13230 } else if (!strcasecmp(v->name, "outkey")) {
13231 ast_string_field_set(peer, outkey, v->value);
13232 } else if (!strcasecmp(v->name, "qualify")) {
13233 if (!strcasecmp(v->value, "no")) {
13234 peer->maxms = 0;
13235 } else if (!strcasecmp(v->value, "yes")) {
13236 peer->maxms = DEFAULT_MAXMS;
13237 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
13238 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);
13239 peer->maxms = 0;
13240 }
13241 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
13242 peer->smoothing = ast_true(v->value);
13243 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
13244 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
13245 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);
13246 }
13247 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
13248 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
13249 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);
13250 }
13251 } else if (!strcasecmp(v->name, "timezone")) {
13253 } else if (!strcasecmp(v->name, "adsi")) {
13254 peer->adsi = ast_true(v->value);
13255 } else if (!strcasecmp(v->name, "connectedline")) {
13256 if (ast_true(v->value)) {
13258 } else if (!strcasecmp(v->value, "send")) {
13261 } else if (!strcasecmp(v->value, "receive")) {
13264 } else {
13266 }
13267 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13268 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
13269 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
13270 } else {
13271 peercnt_modify((unsigned char) 1, peer->maxcallno, &peer->addr);
13272 }
13273 } else if (!strcasecmp(v->name, "requirecalltoken")) {
13274 /* default is required unless in optional ip list */
13275 if (ast_false(v->value)) {
13277 } else if (!strcasecmp(v->value, "auto")) {
13279 } else if (ast_true(v->value)) {
13281 } else {
13282 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13283 }
13284 } /* else if (strcasecmp(v->name,"type")) */
13285 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13286 v = v->next;
13287 if (!v) {
13288 v = alt;
13289 alt = NULL;
13290 }
13291 }
13292 if (!peer->authmethods)
13293 peer->authmethods = IAX_AUTH_MD5;
13295 }
13296
13297 if (!maskfound && !ast_sockaddr_isnull(&peer->addr)) {
13298 if (ast_sockaddr_is_ipv4_mapped(&peer->addr)) {
13299 ast_sockaddr_parse(&peer->mask, "::ffff:ffff:ffff", 0);
13300 } else if (ast_sockaddr_is_ipv6(&peer->addr)) {
13301 ast_sockaddr_parse(&peer->mask, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0);
13302 } else {
13303 ast_sockaddr_parse(&peer->mask, "255.255.255.255", 0);
13304 }
13305 }
13306
13307 if (oldacl) {
13308 ast_free_acl_list(oldacl);
13309 }
13310
13311 if (!ast_strlen_zero(peer->mailbox) && !peer->mwi_event_sub) {
13312 /* The MWI subscriptions exist just so the core knows we care about those
13313 * mailboxes. However, we just grab the events out of the cache when it
13314 * is time to send MWI, since it is only sent with a REGACK. */
13316 }
13317
13318 if (subscribe_acl_change) {
13320 }
13321
13322 return peer;
13323}
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:1016
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:1542
static int get_auth_methods(const char *value)
Definition: chan_iax2.c:12875
static iax2_format iax2_capability
Definition: chan_iax2.c:483
#define IAX_HASCALLERID
Definition: chan_iax2.c:522
#define IAX_SENDANI
Definition: chan_iax2.c:529
static int adsi
Definition: chan_iax2.c:501
#define DEFAULT_FREQ_OK
Definition: chan_iax2.c:419
static int iax2_authmethods
Definition: chan_iax2.c:504
#define DEFAULT_MAXMS
Definition: chan_iax2.c:418
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:12916
#define DEFAULT_FREQ_NOTOK
Definition: chan_iax2.c:420
static int iax2_encryption
Definition: chan_iax2.c:503
static void peer_destructor(void *obj)
Definition: chan_iax2.c:12986
static int get_encrypt_methods(const char *s)
Definition: chan_iax2.c:1839
static struct iax2_codec_pref prefs_global
Definition: chan_iax2.c:332
static int iax2_parse_allow_disallow(struct iax2_codec_pref *pref, iax2_format *formats, const char *list, int allowing)
Definition: chan_iax2.c:2002
#define IAX_DELME
Definition: chan_iax2.c:523
static int defaultsockfd
Definition: chan_iax2.c:392
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:4047
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:836
#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:648
struct ast_dnsmgr_entry * dnsmgr
Definition: chan_iax2.c:625
struct ast_mwi_subscriber * mwi_event_sub
Definition: chan_iax2.c:654
enum calltoken_peer_enum calltoken_required
Definition: chan_iax2.c:657
iax2_format capability
Definition: chan_iax2.c:640
int adsi
Definition: chan_iax2.c:630
struct ast_sockaddr defaddr
Definition: chan_iax2.c:634
uint16_t maxcallno
Definition: chan_iax2.c:652
struct iax2_codec_pref prefs
Definition: chan_iax2.c:624
struct ast_acl_list * acl
Definition: chan_iax2.c:656
int maxms
Definition: chan_iax2.c:646
int sockfd
Definition: chan_iax2.c:628
int smoothing
Definition: chan_iax2.c:651
const ast_string_field mailbox
Definition: chan_iax2.c:623
#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 6473 of file chan_iax2.c.

6474{
6475 long tmp;
6476 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
6477 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
6478 buf += sizeof(tmp);
6479 len -= sizeof(tmp);
6480 }
6481}

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

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

13340{
13341 struct iax2_user *user = NULL;
13342 struct iax2_context *con, *conl = NULL;
13343 struct ast_acl_list *oldacl = NULL;
13344 struct iax2_context *oldcon = NULL;
13345 int format;
13346 int firstpass=1;
13347 int oldcurauthreq = 0;
13348 int subscribe_acl_change = 0;
13349 char *varname = NULL, *varval = NULL;
13350 struct ast_variable *tmpvar = NULL;
13351
13352 if (!temponly) {
13355 firstpass = 0;
13356 }
13357
13358 if (user) {
13359 if (firstpass) {
13360 oldcurauthreq = user->curauthreq;
13361 oldacl = user->acl;
13362 oldcon = user->contexts;
13363 user->acl = NULL;
13364 user->contexts = NULL;
13365 }
13366 /* Already in the list, remove it and it will be added back (or FREE'd) */
13368 } else {
13369 user = ao2_alloc(sizeof(*user), user_destructor);
13370 }
13371
13372 if (user) {
13373 if (firstpass) {
13375 memset(user, 0, sizeof(struct iax2_user));
13376 if (ast_string_field_init(user, 32)) {
13377 user = user_unref(user);
13378 goto cleanup;
13379 }
13380 user->maxauthreq = maxauthreq;
13381 user->curauthreq = oldcurauthreq;
13382 user->prefs = prefs_global;
13383 user->capability = iax2_capability;
13384 user->encmethods = iax2_encryption;
13385 user->authmethods = iax2_authmethods;
13386 user->adsi = adsi;
13387 user->calltoken_required = CALLTOKEN_DEFAULT;
13392 ast_string_field_set(user, cid_name, "");
13393 ast_string_field_set(user, cid_num, "");
13397 }
13398 if (!v) {
13399 v = alt;
13400 alt = NULL;
13401 }
13402 while(v) {
13403 if (!strcasecmp(v->name, "context")) {
13404 con = build_context(v->value);
13405 if (con) {
13406 if (conl)
13407 conl->next = con;
13408 else
13409 user->contexts = con;
13410 conl = con;
13411 }
13412 } else if (!strcasecmp(v->name, "permit") ||
13413 !strcasecmp(v->name, "deny") ||
13414 !strcasecmp(v->name, "acl")) {
13415 ast_append_acl(v->name, v->value, &user->acl, NULL, &subscribe_acl_change);
13416 } else if (!strcasecmp(v->name, "setvar")) {
13417 varname = ast_strdupa(v->value);
13418 if ((varval = strchr(varname, '='))) {
13419 *varval = '\0';
13420 varval++;
13421 if ((tmpvar = ast_variable_new(varname, varval, ""))) {
13422 if (ast_variable_list_replace(&user->vars, tmpvar)) {
13423 tmpvar->next = user->vars;
13424 user->vars = tmpvar;
13425 }
13426 }
13427 }
13428 } else if (!strcasecmp(v->name, "allow")) {
13429 iax2_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
13430 } else if (!strcasecmp(v->name, "disallow")) {
13431 iax2_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
13432 } else if (!strcasecmp(v->name, "trunk")) {
13434 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
13435 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
13437 }
13438 } else if (!strcasecmp(v->name, "auth")) {
13439 user->authmethods = get_auth_methods(v->value);
13440 if (user->authmethods & IAX_AUTH_PLAINTEXT) {
13441 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);
13442 }
13443 } else if (!strcasecmp(v->name, "encryption")) {
13444 user->encmethods |= get_encrypt_methods(v->value);
13445 if (!user->encmethods) {
13447 }
13448 } else if (!strcasecmp(v->name, "forceencryption")) {
13449 if (ast_false(v->value)) {
13451 } else {
13452 user->encmethods |= get_encrypt_methods(v->value);
13453 if (user->encmethods) {
13455 }
13456 }
13457 } else if (!strcasecmp(v->name, "transfer")) {
13458 if (!strcasecmp(v->value, "mediaonly")) {
13460 } else if (ast_true(v->value)) {
13462 } else
13464 } else if (!strcasecmp(v->name, "codecpriority")) {
13465 if(!strcasecmp(v->value, "caller"))
13467 else if(!strcasecmp(v->value, "disabled"))
13469 else if(!strcasecmp(v->value, "reqonly")) {
13472 }
13473 } else if (!strcasecmp(v->name, "immediate")) {
13475 } else if (!strcasecmp(v->name, "jitterbuffer")) {
13477 } else if (!strcasecmp(v->name, "dbsecret")) {
13478 ast_string_field_set(user, dbsecret, v->value);
13479 } else if (!strcasecmp(v->name, "secret")) {
13480 if (!ast_strlen_zero(user->secret)) {
13481 char *old = ast_strdupa(user->secret);
13482
13483 ast_string_field_build(user, secret, "%s;%s", old, v->value);
13484 } else
13485 ast_string_field_set(user, secret, v->value);
13486 } else if (!strcasecmp(v->name, "callerid")) {
13487 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
13488 char name2[80];
13489 char num2[80];
13490 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
13491 ast_string_field_set(user, cid_name, name2);
13492 ast_string_field_set(user, cid_num, num2);
13494 } else {
13496 ast_string_field_set(user, cid_name, "");
13497 ast_string_field_set(user, cid_num, "");
13498 }
13499 } else if (!strcasecmp(v->name, "fullname")) {
13500 if (!ast_strlen_zero(v->value)) {
13501 ast_string_field_set(user, cid_name, v->value);
13503 } else {
13504 ast_string_field_set(user, cid_name, "");
13505 if (ast_strlen_zero(user->cid_num))
13507 }
13508 } else if (!strcasecmp(v->name, "cid_number")) {
13509 if (!ast_strlen_zero(v->value)) {
13510 ast_string_field_set(user, cid_num, v->value);
13512 } else {
13513 ast_string_field_set(user, cid_num, "");
13514 if (ast_strlen_zero(user->cid_name))
13516 }
13517 } else if (!strcasecmp(v->name, "accountcode")) {
13519 } else if (!strcasecmp(v->name, "mohinterpret")) {
13521 } else if (!strcasecmp(v->name, "mohsuggest")) {
13523 } else if (!strcasecmp(v->name, "parkinglot")) {
13524 ast_string_field_set(user, parkinglot, v->value);
13525 } else if (!strcasecmp(v->name, "language")) {
13527 } else if (!strcasecmp(v->name, "amaflags")) {
13528 format = ast_channel_string2amaflag(v->value);
13529 if (format < 0) {
13530 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13531 } else {
13532 user->amaflags = format;
13533 }
13534 } else if (!strcasecmp(v->name, "inkeys")) {
13535 ast_string_field_set(user, inkeys, v->value);
13536 } else if (!strcasecmp(v->name, "maxauthreq")) {
13537 user->maxauthreq = atoi(v->value);
13538 if (user->maxauthreq < 0)
13539 user->maxauthreq = 0;
13540 } else if (!strcasecmp(v->name, "adsi")) {
13541 user->adsi = ast_true(v->value);
13542 } else if (!strcasecmp(v->name, "connectedline")) {
13543 if (ast_true(v->value)) {
13545 } else if (!strcasecmp(v->value, "send")) {
13548 } else if (!strcasecmp(v->value, "receive")) {
13551 } else {
13553 }
13554 } else if (!strcasecmp(v->name, "requirecalltoken")) {
13555 /* default is required unless in optional ip list */
13556 if (ast_false(v->value)) {
13557 user->calltoken_required = CALLTOKEN_NO;
13558 } else if (!strcasecmp(v->value, "auto")) {
13559 user->calltoken_required = CALLTOKEN_AUTO;
13560 } else if (ast_true(v->value)) {
13561 user->calltoken_required = CALLTOKEN_YES;
13562 } else {
13563 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13564 }
13565 } /* else if (strcasecmp(v->name,"type")) */
13566 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13567 v = v->next;
13568 if (!v) {
13569 v = alt;
13570 alt = NULL;
13571 }
13572 }
13573 if (!user->authmethods) {
13574 if (!ast_strlen_zero(user->secret)) {
13575 user->authmethods = IAX_AUTH_MD5;
13576 if (!ast_strlen_zero(user->inkeys))
13577 user->authmethods |= IAX_AUTH_RSA;
13578 } else if (!ast_strlen_zero(user->inkeys)) {
13579 user->authmethods = IAX_AUTH_RSA;
13580 } else {
13581 user->authmethods = IAX_AUTH_MD5;
13582 }
13583 }
13585 }
13586cleanup:
13587 if (oldacl) {
13588 ast_free_acl_list(oldacl);
13589 }
13590 if (oldcon) {
13591 free_context(oldcon);
13592 }
13593
13594 if (subscribe_acl_change) {
13596 }
13597
13598 return user;
13599}
#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:12865
#define IAX_CODEC_NOCAP
Definition: chan_iax2.c:538
#define IAX_IMMEDIATE
Definition: chan_iax2.c:548
static void user_destructor(void *obj)
Definition: chan_iax2.c:13325
static void free_context(struct iax2_context *con)
Definition: chan_iax2.c:12666
static int maxauthreq
Definition: chan_iax2.c:355
static char language[MAX_LANGUAGE]
Definition: chan_iax2.c:348
#define IAX_CODEC_USER_FIRST
Definition: chan_iax2.c:536
#define IAX_CODEC_NOPREFS
Definition: chan_iax2.c:537
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
Definition: channel.c:4318
#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:753
#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 14284 of file chan_iax2.c.

14285{
14286 struct ast_sockaddr addr;
14287 int x;
14288 int callno;
14289 struct iax_ie_data ied;
14290 struct create_addr_info cai;
14291 struct parsed_dial_string pds;
14292 char *tmpstr;
14293
14294 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14295 /* Look for an *exact match* call. Once a call is negotiated, it can only
14296 look up entries for a single context */
14297 if (!ast_mutex_trylock(&iaxsl[x])) {
14298 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
14299 return x;
14301 }
14302 }
14303
14304 /* No match found, we need to create a new one */
14305
14306 memset(&cai, 0, sizeof(cai));
14307 memset(&ied, 0, sizeof(ied));
14308 memset(&pds, 0, sizeof(pds));
14309
14310 tmpstr = ast_strdupa(data);
14311 parse_dial_string(tmpstr, &pds);
14312
14313 if (ast_strlen_zero(pds.peer)) {
14314 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
14315 return -1;
14316 }
14317
14318 /* Populate our address from the given */
14319 if (create_addr(pds.peer, NULL, &addr, &cai))
14320 return -1;
14321
14322 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
14323 pds.peer, pds.username, pds.password, pds.context);
14324
14325 callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
14326 if (callno < 1) {
14327 ast_log(LOG_WARNING, "Unable to create call\n");
14328 return -1;
14329 }
14330
14331 ast_string_field_set(iaxs[callno], dproot, data);
14333
14336 /* the string format is slightly different from a standard dial string,
14337 because the context appears in the 'exten' position
14338 */
14339 if (pds.exten)
14340 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
14341 if (pds.username)
14342 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
14345 /* Keep password handy */
14346 if (pds.password)
14347 ast_string_field_set(iaxs[callno], secret, pds.password);
14348 if (pds.key)
14349 ast_string_field_set(iaxs[callno], outkey, pds.key);
14350 /* Start the call going */
14351 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
14352 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
14353
14354 return callno;
14355}
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:3311
#define IAX_CAPABILITY_FULLBANDWIDTH
Definition: chan_iax2.c:397
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:5132
static int create_addr(const char *peername, struct ast_channel *c, struct ast_sockaddr *addr, struct create_addr_info *cai)
Definition: chan_iax2.c:4706
static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
Definition: chan_iax2.c:4898
@ 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:198
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 6324 of file chan_iax2.c.

6325{
6326 /* Returns where in "receive time" we are. That is, how many ms
6327 since we received (or would have received) the frame with timestamp 0 */
6328 int ms;
6329#ifdef IAXTESTS
6330 int jit;
6331#endif /* IAXTESTS */
6332 /* Setup rxcore if necessary */
6333 if (ast_tvzero(p->rxcore)) {
6334 p->rxcore = ast_tvnow();
6335 if (iaxdebug)
6336 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %ums\n",
6337 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
6338 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
6339#if 1
6340 if (iaxdebug)
6341 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
6342 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
6343#endif
6344 }
6345
6346 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
6347#ifdef IAXTESTS
6348 if (test_jit) {
6349 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
6350 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
6351 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
6352 jit = -jit;
6353 ms += jit;
6354 }
6355 }
6356 if (test_late) {
6357 ms += test_late;
6358 test_late = 0;
6359 }
6360#endif /* IAXTESTS */
6361 return ms;
6362}
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 6189 of file chan_iax2.c.

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

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

6146{
6147 unsigned long int mssincetx; /* unsigned to handle overflows */
6148 long int ms, pred;
6149
6150 tpeer->trunkact = *now;
6151 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
6152 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
6153 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
6154 tpeer->txtrunktime = *now;
6155 tpeer->lastsent = 999999;
6156 }
6157 /* Update last transmit time now */
6158 tpeer->lasttxtime = *now;
6159
6160 /* Calculate ms offset */
6161 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
6162 /* Predict from last value */
6163 pred = tpeer->lastsent + sampms;
6164 if (labs(ms - pred) < MAX_TIMESTAMP_SKEW)
6165 ms = pred;
6166
6167 /* We never send the same timestamp twice, so fudge a little if we must */
6168 if (ms == tpeer->lastsent)
6169 ms = tpeer->lastsent + 1;
6170 tpeer->lastsent = ms;
6171 return ms;
6172}
struct timeval lasttxtime
Definition: chan_iax2.c:670
unsigned int lastsent
Definition: chan_iax2.c:672
struct timeval trunkact
Definition: chan_iax2.c:671
struct timeval txtrunktime
Definition: chan_iax2.c:668

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

2568{
2569 struct addr_range *addr_range;
2570 struct iax2_peer *peer = NULL;
2571 struct iax2_user *user = NULL;
2572 /* if no username is given, check for guest accounts */
2573 const char *find = S_OR(name, "guest");
2574 int res = 1; /* required by default */
2575 int optional = 0;
2577 /* There are only two cases in which calltoken validation is not required.
2578 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
2579 * the peer definition has not set the requirecalltoken option.
2580 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
2581 */
2582
2583 /* ----- Case 1 ----- */
2585 ao2_ref(addr_range, -1);
2586 optional = 1;
2587 }
2588
2589 /* ----- Case 2 ----- */
2590 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
2591 calltoken_required = user->calltoken_required;
2592 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, addr))) {
2593 calltoken_required = user->calltoken_required;
2594 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
2596 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, addr))) {
2598 }
2599
2600 if (peer) {
2601 peer_unref(peer);
2602 }
2603 if (user) {
2605 }
2606
2607 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);
2609 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
2610 res = 0;
2611 }
2612
2613 return res;
2614}
#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:2548
static int calltoken_required(struct ast_sockaddr *addr, const char *name, int subclass)
Definition: chan_iax2.c:2567
static struct iax2_user * find_user(const char *name)
Definition: chan_iax2.c:2107
calltoken_peer_enum
Call token validation settings.
Definition: chan_iax2.c:560
static struct iax2_user * realtime_user(const char *username, struct ast_sockaddr *addr)
Definition: chan_iax2.c:4589

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

7928{
7929 /* Start pessimistic */
7930 int res = -1;
7931 int version = 2;
7932 struct iax2_user *user = NULL, *best = NULL;
7933 int bestscore = 0;
7934 int gotcapability = 0;
7935 struct ast_variable *v = NULL, *tmpvar = NULL;
7936 struct ao2_iterator i;
7937
7938 if (!iaxs[callno])
7939 return res;
7940 if (ies->called_number)
7941 ast_string_field_set(iaxs[callno], exten, ies->called_number);
7942 if (ies->calling_number) {
7945 }
7946 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
7947 }
7948 if (ies->calling_name)
7949 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
7950 if (ies->calling_ani)
7951 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
7952 if (ies->dnid)
7953 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
7954 if (ies->rdnis)
7955 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
7956 if (ies->called_context)
7958 if (ies->language)
7960 if (ies->username)
7961 ast_string_field_set(iaxs[callno], username, ies->username);
7962 if (ies->calling_ton > -1)
7963 iaxs[callno]->calling_ton = ies->calling_ton;
7964 if (ies->calling_tns > -1)
7965 iaxs[callno]->calling_tns = ies->calling_tns;
7966 if (ies->calling_pres > -1)
7967 iaxs[callno]->calling_pres = ies->calling_pres;
7968 if (ies->calling_ani2 > -1)
7969 iaxs[callno]->calling_ani2 = ies->calling_ani2;
7970 if (ies->format)
7971 iaxs[callno]->peerformat = ies->format;
7972 if (ies->adsicpe)
7973 iaxs[callno]->peeradsicpe = ies->adsicpe;
7974 if (ies->capability) {
7975 gotcapability = 1;
7976 iaxs[callno]->peercapability = ies->capability;
7977 }
7978 if (ies->version)
7979 version = ies->version;
7980
7981 /* Use provided preferences until told otherwise for actual preferences */
7982 if (ies->codec_prefs) {
7983 iax2_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
7984 } else {
7985 memset(&iaxs[callno]->rprefs, 0, sizeof(iaxs[callno]->rprefs));
7986 }
7987 iaxs[callno]->prefs = iaxs[callno]->rprefs;
7988
7989 if (!gotcapability) {
7990 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
7991 }
7992 if (version > IAX_PROTO_VERSION) {
7993 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
7995 return res;
7996 }
7997 /* Search the userlist for a compatible entry, and fill in the rest */
7998 i = ao2_iterator_init(users, 0);
7999 while ((user = ao2_iterator_next(&i))) {
8000 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */
8001 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
8002 && (ast_apply_acl(user->acl, addr, "IAX2 user ACL: ") == AST_SENSE_ALLOW) /* Access is permitted from this IP */
8003 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */
8004 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */
8005 if (!ast_strlen_zero(iaxs[callno]->username)) {
8006 /* Exact match, stop right now. */
8007 if (best)
8008 user_unref(best);
8009 best = user;
8010 break;
8011 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
8012 /* No required authentication */
8013 if (user->acl) {
8014 /* There was host authentication and we passed, bonus! */
8015 if (bestscore < 4) {
8016 bestscore = 4;
8017 if (best)
8018 user_unref(best);
8019 best = user;
8020 continue;
8021 }
8022 } else {
8023 /* No host access, but no secret, either, not bad */
8024 if (bestscore < 3) {
8025 bestscore = 3;
8026 if (best)
8027 user_unref(best);
8028 best = user;
8029 continue;
8030 }
8031 }
8032 } else {
8033 if (user->acl) {
8034 /* Authentication, but host access too, eh, it's something.. */
8035 if (bestscore < 2) {
8036 bestscore = 2;
8037 if (best)
8038 user_unref(best);
8039 best = user;
8040 continue;
8041 }
8042 } else {
8043 /* Authentication and no host access... This is our baseline */
8044 if (bestscore < 1) {
8045 bestscore = 1;
8046 if (best)
8047 user_unref(best);
8048 best = user;
8049 continue;
8050 }
8051 }
8052 }
8053 }
8055 }
8057 user = best;
8058 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
8059 user = realtime_user(iaxs[callno]->username, addr);
8060 if (user && (ast_apply_acl(user->acl, addr, "IAX2 user ACL: ") == AST_SENSE_DENY /* Access is denied from this IP */
8061 || (!ast_strlen_zero(iaxs[callno]->context) && /* No context specified */
8062 !apply_context(user->contexts, iaxs[callno]->context)))) { /* Context is permitted */
8063 user = user_unref(user);
8064 }
8065 }
8066 if (user) {
8067 /* We found our match (use the first) */
8068 /* copy vars */
8069 for (v = user->vars ; v ; v = v->next) {
8070 if ((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
8071 if (ast_variable_list_replace(&iaxs[callno]->vars, tmpvar)) {
8072 tmpvar->next = iaxs[callno]->vars;
8073 iaxs[callno]->vars = tmpvar;
8074 }
8075 }
8076 }
8077 /* If a max AUTHREQ restriction is in place, activate it */
8078 if (user->maxauthreq > 0)
8080 iaxs[callno]->prefs = user->prefs;
8082 iaxs[callno]->encmethods = user->encmethods;
8083 /* Store the requested username if not specified */
8084 if (ast_strlen_zero(iaxs[callno]->username))
8085 ast_string_field_set(iaxs[callno], username, user->name);
8086 /* Store whether this is a trunked call, too, of course, and move if appropriate */
8088 iaxs[callno]->capability = user->capability;
8089 /* And use the default context */
8090 if (ast_strlen_zero(iaxs[callno]->context)) {
8091 if (user->contexts)
8092 ast_string_field_set(iaxs[callno], context, user->contexts->context);
8093 else
8095 }
8096 /* And any input keys */
8097 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
8098 /* And the permitted authentication methods */
8099 iaxs[callno]->authmethods = user->authmethods;
8100 iaxs[callno]->adsi = user->adsi;
8101 /* If the user has callerid, override the remote caller id. */
8103 iaxs[callno]->calling_tns = 0;
8104 iaxs[callno]->calling_ton = 0;
8105 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
8106 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
8107 ast_string_field_set(iaxs[callno], ani, user->cid_num);
8109 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
8111 } /* else user is allowed to set their own CID settings */
8112 if (!ast_strlen_zero(user->accountcode))
8113 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
8114 if (!ast_strlen_zero(user->mohinterpret))
8115 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
8116 if (!ast_strlen_zero(user->mohsuggest))
8117 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
8118 if (!ast_strlen_zero(user->parkinglot))
8119 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
8120 if (user->amaflags)
8121 iaxs[callno]->amaflags = user->amaflags;
8122 if (!ast_strlen_zero(user->language))
8123 ast_string_field_set(iaxs[callno], language, user->language);
8125 /* Keep this check last */
8126 if (!ast_strlen_zero(user->dbsecret)) {
8127 char *family, *key=NULL;
8128 char buf[80];
8129 family = ast_strdupa(user->dbsecret);
8130 key = strchr(family, '/');
8131 if (key) {
8132 *key = '\0';
8133 key++;
8134 }
8135 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
8136 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
8137 else
8138 ast_string_field_set(iaxs[callno], secret, buf);
8139 } else
8140 ast_string_field_set(iaxs[callno], secret, user->secret);
8141 res = 0;
8142 user = user_unref(user);
8143 } else {
8144 /* user was not found, but we should still fake an AUTHREQ.
8145 * Set authmethods to the last known authmethod used by the system
8146 * Set a fake secret, it's not looked at, just required to attempt authentication.
8147 * Set authrej so the AUTHREP is rejected without even looking at its contents */
8149 ast_string_field_set(iaxs[callno], secret, "badsecret");
8150 iaxs[callno]->authrej = 1;
8151 if (!ast_strlen_zero(iaxs[callno]->username)) {
8152 /* only send the AUTHREQ if a username was specified. */
8153 res = 0;
8154 }
8155 }
8157 return res;
8158}
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: db.c:421
#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:7916
#define IAX_SHRINKCALLERID
Definition: chan_iax2.c:552
static int last_authmethod
Definition: chan_iax2.c:372
static int iax2_getpeertrunk(struct ast_sockaddr addr)
Definition: chan_iax2.c:5924
#define DEFAULT_CONTEXT
Definition: chan_iax2.c:344
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:819
struct iax2_codec_pref prefs
Definition: chan_iax2.c:802
struct iax2_codec_pref rprefs
Definition: chan_iax2.c:804
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 9781 of file chan_iax2.c.

9782{
9783 unsigned int ourver;
9784 char rsi[80];
9785 snprintf(rsi, sizeof(rsi), "si-%s", si);
9786 if (iax_provision_version(&ourver, rsi, 1))
9787 return 0;
9788 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
9789 if (ourver != ver)
9790 iax2_provision(addr, sockfd, NULL, rsi, 1);
9791 return 0;
9792}
static int iax2_provision(struct ast_sockaddr *end, int sockfd, const char *dest, const char *template, int force)
Definition: chan_iax2.c:12415
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 12893 of file chan_iax2.c.

12894{
12895 int sd;
12896
12897 sd = socket(addr->ss.ss_family, SOCK_DGRAM, 0);
12898 if (sd < 0) {
12899 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12900 return -1;
12901 }
12902
12903 if (ast_bind(sd, addr) < 0) {
12904 ast_debug(1, "Can't bind: %s\n", strerror(errno));
12905 close(sd);
12906 return 1;
12907 }
12908
12909 close(sd);
12910 return 0;
12911}
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 14793 of file chan_iax2.c.

14794{
14795 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14796 struct iax2_thread_list *list_head = head;
14797 struct iax2_thread *thread;
14798
14799 AST_LIST_LOCK(list_head);
14800 while ((thread = AST_LIST_REMOVE_HEAD(list_head, list))) {
14801 pthread_t thread_id = thread->threadid;
14802
14803 thread->stop = 1;
14804 signal_condition(&thread->lock, &thread->cond);
14805
14806 AST_LIST_UNLOCK(list_head);
14807 pthread_join(thread_id, NULL);
14808 AST_LIST_LOCK(list_head);
14809 }
14810 AST_LIST_UNLOCK(list_head);
14811}
#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 1920 of file chan_iax2.c.

1921{
1922 int x;
1923 struct ast_format *found_format = NULL;
1924
1925 for (x = 0; x < ARRAY_LEN(pref->order); ++x) {
1926 struct ast_format *pref_format;
1927 uint64_t pref_bitfield;
1928
1929 pref_bitfield = iax2_codec_pref_order_value_to_format_bitfield(pref->order[x]);
1930 if (!pref_bitfield) {
1931 break;
1932 }
1933
1934 pref_format = ast_format_compatibility_bitfield2format(pref_bitfield);
1935 if (!pref_format) {
1936 /* The bitfield is not associated with any format. */
1937 continue;
1938 }
1939 found_format = ast_format_cap_get_compatible_format(cap, pref_format);
1940 if (found_format) {
1941 break;
1942 }
1943 }
1944
1945 if (found_format && (ast_format_get_type(found_format) == AST_MEDIA_TYPE_AUDIO)) {
1946 return found_format;
1947 }
1948
1949 ast_debug(4, "Could not find preferred codec - Returning zero codec.\n");
1950 ao2_cleanup(found_format);
1951 return NULL;
1952}
@ 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 8784 of file chan_iax2.c.

8785{
8786 char exten[256] = "";
8787 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
8788 struct iax2_dpcache *dp = NULL;
8789
8790 if (ies->called_number)
8791 ast_copy_string(exten, ies->called_number, sizeof(exten));
8792
8793 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
8795 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
8797 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
8799
8800 if (ies->refresh)
8801 expiry = ies->refresh;
8804
8807 if (strcmp(dp->exten, exten))
8808 continue;
8810 dp->callno = 0;
8811 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
8812 if (dp->flags & CACHE_FLAG_PENDING) {
8813 dp->flags &= ~CACHE_FLAG_PENDING;
8814 dp->flags |= status;
8815 dp->flags |= matchmore;
8816 }
8817 /* Wake up waiters */
8818 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
8819 if (dp->waiters[x] > -1) {
8820 if (write(dp->waiters[x], "asdf", 4) < 0) {
8821 }
8822 }
8823 }
8824 }
8827
8828 return 0;
8829}
static int iaxdefaultdpcache
Definition: chan_iax2.c:374
#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:1100
struct timeval expiry
Definition: chan_iax2.c:1097
char exten[AST_MAX_EXTENSION]
Definition: chan_iax2.c:1095
unsigned short callno
Definition: chan_iax2.c:1099
struct timeval orig
Definition: chan_iax2.c:1096
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 3964 of file chan_iax2.c.

3965{
3966 int which = 0;
3967 struct iax2_peer *peer;
3968 char *res = NULL;
3969 int wordlen = strlen(word);
3970 struct ao2_iterator i;
3971
3972 i = ao2_iterator_init(peers, 0);
3973 while ((peer = ao2_iterator_next(&i))) {
3974 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
3975 && (!flags || ast_test_flag64(peer, flags))) {
3976 res = ast_strdup(peer->name);
3977 peer_unref(peer);
3978 break;
3979 }
3980 peer_unref(peer);
3981 }
3983
3984 return res;
3985}
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 7288 of file chan_iax2.c.

7289{
7290 int which = 0;
7291 struct iax2_peer *p = NULL;
7292 char *res = NULL;
7293 int wordlen = strlen(word);
7294
7295 /* 0 - iax2; 1 - unregister; 2 - <peername> */
7296 if (pos == 2) {
7297 struct ao2_iterator i = ao2_iterator_init(peers, 0);
7298 while ((p = ao2_iterator_next(&i))) {
7299 if (!strncasecmp(p->name, word, wordlen) &&
7300 ++which > state && p->expire > -1) {
7301 res = ast_strdup(p->name);
7302 peer_unref(p);
7303 break;
7304 }
7305 peer_unref(p);
7306 }
7308 }
7309
7310 return res;
7311}

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

8832{
8833 int peercallno = 0;
8834 struct chan_iax2_pvt *pvt = iaxs[callno];
8835 struct iax_frame *cur;
8836 jb_frame frame;
8837
8838 if (ies->callno)
8839 peercallno = ies->callno;
8840
8841 if (peercallno < 1) {
8842 ast_log(LOG_WARNING, "Invalid transfer request\n");
8843 return -1;
8844 }
8846 /* since a transfer has taken place, the address will change.
8847 * This must be accounted for in the peercnts table. Remove
8848 * the old address and add the new one */
8850 peercnt_add(&pvt->transfer);
8851 /* now copy over the new address */
8852 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
8853 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
8854 /* Reset sequence numbers */
8855 pvt->oseqno = 0;
8856 pvt->rseqno = 0;
8857 pvt->iseqno = 0;
8858 pvt->aseqno = 0;
8859
8860 if (pvt->peercallno) {
8862 }
8863 pvt->peercallno = peercallno;
8864 /*this is where the transferring call switches hash tables */
8867 pvt->svoiceformat = -1;
8868 pvt->voiceformat = 0;
8869 pvt->svideoformat = -1;
8870 pvt->videoformat = 0;
8871 pvt->transfercallno = 0;
8872 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
8873 memset(&pvt->offset, 0, sizeof(pvt->offset));
8874 /* reset jitterbuffer */
8875 while(jb_getall(pvt->jb,&frame) == JB_OK)
8876 iax2_frame_free(frame.data);
8877 jb_reset(pvt->jb);
8878 pvt->lag = 0;
8879 pvt->last = 0;
8880 pvt->lastsent = 0;
8881 pvt->nextpred = 0;
8884 /* We must cancel any packets that would have been transmitted
8885 because now we're talking to someone new. It's okay, they
8886 were transmitted to someone that didn't care anyway. */
8887 cur->retries = -1;
8888 }
8889 return 0;
8890}
static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:2482
static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:2501
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:778
unsigned char iseqno
Definition: chan_iax2.c:843
iax2_format videoformat
Definition: chan_iax2.c:774
unsigned char rseqno
Definition: chan_iax2.c:841
unsigned short transfercallno
Definition: chan_iax2.c:921
unsigned char oseqno
Definition: chan_iax2.c:839
unsigned char aseqno
Definition: chan_iax2.c:845
iax2_format svoiceformat
Definition: chan_iax2.c:776
unsigned int last
Definition: chan_iax2.c:782
enum iax_transfer_state transferring
Definition: chan_iax2.c:915
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 1886 of file chan_iax2.c.

1887{
1888 int x;
1889 int power=-1;
1890 /* If it's 64 or smaller, just return it */
1891 if (subclass < IAX_FLAG_SC_LOG)
1892 return subclass;
1893 /* Otherwise find its power */
1894 for (x = 0; x < IAX_MAX_SHIFT; x++) {
1895 if (subclass & (1LL << x)) {
1896 if (power > -1) {
1897 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass);
1898 return 0;
1899 } else
1900 power = x;
1901 }
1902 }
1903 return power | IAX_FLAG_SC_LOG;
1904}
#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 9794 of file chan_iax2.c.

9795{
9796 jb_info stats;
9797 jb_getinfo(pvt->jb, &stats);
9798
9799 memset(iep, 0, sizeof(*iep));
9800
9802 if(stats.frames_in == 0) stats.frames_in = 1;
9803 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
9805 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
9808}
#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 4706 of file chan_iax2.c.

4707{
4708 struct iax2_peer *peer;
4709 int res = -1;
4710
4712 cai->sockfd = defaultsockfd;
4713 cai->maxtime = 0;
4714
4715 if (!(peer = find_peer(peername, 1))) {
4716 struct ast_sockaddr peer_addr;
4717
4718 peer_addr.ss.ss_family = AST_AF_UNSPEC;
4719 cai->found = 0;
4720 if (ast_get_ip_or_srv(&peer_addr, peername, srvlookup ? "_iax._udp" : NULL)) {
4721 ast_log(LOG_WARNING, "No such host: %s\n", peername);
4722 return -1;
4723 }
4724
4725 if (!ast_sockaddr_port(&peer_addr)) {
4727 }
4728
4729 ast_sockaddr_copy(addr, &peer_addr);
4730 /*
4731 * Use The global iax prefs for unknown peer/user.
4732 * However, move the calling channel's native codec to
4733 * the top of the preference list.
4734 */
4735 cai->prefs = prefs_global;
4736 if (c) {
4737 int i;
4738
4739 for (i = 0; i < ast_format_cap_count(ast_channel_nativeformats(c)); i++) {
4740 struct ast_format *format = ast_format_cap_get_format(
4742 iax2_codec_pref_prepend(&cai->prefs, format,
4744 1);
4745 ao2_ref(format, -1);
4746 }
4747 }
4748 return 0;
4749 }
4750
4751 cai->found = 1;
4752
4753 /* if the peer has no address (current or default), return failure */
4754 if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) {
4755 goto return_unref;
4756 }
4757
4758 /* if the peer is being monitored and is currently unreachable, return failure */
4759 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
4760 goto return_unref;
4761
4763 cai->maxtime = peer->maxms;
4764 cai->capability = peer->capability;
4765 cai->encmethods = peer->encmethods;
4766 cai->authmethods = peer->authmethods;
4767 cai->sockfd = peer->sockfd;
4768 cai->adsi = peer->adsi;
4769 cai->prefs = peer->prefs;
4770 /* Move the calling channel's native codec to the top of the preference list */
4771 if (c) {
4772 int i;
4773
4774 for (i = 0; i < ast_format_cap_count(ast_channel_nativeformats(c)); i++) {
4775 struct ast_format *tmpfmt = ast_format_cap_get_format(
4777 iax2_codec_pref_prepend(&cai->prefs, tmpfmt,
4779 1);
4780 ao2_ref(tmpfmt, -1);
4781 }
4782 }
4783 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
4784 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
4785 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
4786 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
4787 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
4788 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
4789 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
4790 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
4791 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
4792 if (ast_strlen_zero(peer->dbsecret)) {
4793 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
4794 } else {
4795 char *family;
4796 char *key = NULL;
4797
4798 family = ast_strdupa(peer->dbsecret);
4799 key = strchr(family, '/');
4800 if (key)
4801 *key++ = '\0';
4802 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
4803 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
4804 goto return_unref;
4805 }
4806 }
4807
4808 if (!ast_sockaddr_isnull(&peer->addr)) {
4809 ast_sockaddr_copy(addr, &peer->addr);
4810 } else {
4811 ast_sockaddr_copy(addr, &peer->defaddr);
4812 }
4813
4814 res = 0;
4815
4816return_unref:
4817 peer_unref(peer);
4818
4819 return res;
4820}
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:933
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:4696
iax2_format capability
Definition: chan_iax2.c:4685
char username[80]
Definition: chan_iax2.c:4694
char cid_num[80]
Definition: chan_iax2.c:4698
struct iax2_codec_pref prefs
Definition: chan_iax2.c:4687
char timezone[80]
Definition: chan_iax2.c:4697
char secret[80]
Definition: chan_iax2.c:4695
char cid_name[80]
Definition: chan_iax2.c:4699
char context[AST_MAX_CONTEXT]
Definition: chan_iax2.c:4700
char peercontext[AST_MAX_CONTEXT]
Definition: chan_iax2.c:4701
char mohsuggest[MAX_MUSICCLASS]
Definition: chan_iax2.c:4703
char mohinterpret[MAX_MUSICCLASS]
Definition: chan_iax2.c:4702
const ast_string_field peercontext
Definition: chan_iax2.c:623
const ast_string_field mohinterpret
Definition: chan_iax2.c:623
const ast_string_field cid_num
Definition: chan_iax2.c:623
const ast_string_field mohsuggest
Definition: chan_iax2.c:623
const ast_string_field zonetag
Definition: chan_iax2.c:623
const ast_string_field context
Definition: chan_iax2.c:623
const ast_string_field dbsecret
Definition: chan_iax2.c:623
const ast_string_field cid_name
Definition: chan_iax2.c:623
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 3094 of file chan_iax2.c.

3095{
3096 uint16_t i;
3097
3099
3100 /* We start at 2. 0 and 1 are reserved. */
3101 for (i = 2; i < TRUNK_CALL_START; i++) {
3104 }
3105
3106 for (i = TRUNK_CALL_START; i < IAX_MAX_CALLS; i++) {
3109 }
3110
3113
3115
3116 return 0;
3117}
#define TRUNK_CALL_START
Definition: chan_iax2.c:1247
static struct call_number_pool callno_pool
Definition: chan_iax2.c:991
static struct call_number_pool callno_pool_trunk
Definition: chan_iax2.c:994
#define IAX_MAX_CALLS
Definition: iax2.h:37
size_t available
Definition: chan_iax2.c:984
callno_entry numbers[IAX_MAX_CALLS/2+1]
Definition: chan_iax2.c:985
#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 6563 of file chan_iax2.c.

6564{
6565 int padding;
6566 unsigned char *workspace;
6567
6568 workspace = ast_alloca(*datalen);
6569 memset(f, 0, sizeof(*f));
6570 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
6571 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
6572 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
6573 return -1;
6574 /* Decrypt */
6575 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
6576
6577 padding = 16 + (workspace[15] & 0x0f);
6578 if (iaxdebug)
6579 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02hhx)\n", *datalen, padding, workspace[15]);
6580 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
6581 return -1;
6582
6583 *datalen -= padding;
6584 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
6585 f->frametype = fh->type;
6586 if (f->frametype == AST_FRAME_VIDEO) {
6588 if (!f->subclass.format) {
6590 }
6591 } else if (f->frametype == AST_FRAME_VOICE) {
6593 if (!f->subclass.format) {
6595 }
6596 } else {
6598 }
6599 } else {
6600 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
6601 if (iaxdebug)
6602 ast_debug(5, "Decoding mini with length %d\n", *datalen);
6603 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
6604 return -1;
6605 /* Decrypt */
6606 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
6607 padding = 16 + (workspace[15] & 0x0f);
6608 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
6609 return -1;
6610 *datalen -= padding;
6611 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
6612 }
6613 return 0;
6614}
#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:1906
static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
Definition: chan_iax2.c:6515
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 6655 of file chan_iax2.c.

6656{
6657 int res=-1;
6658 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
6659 /* Search for possible keys, given secrets */
6660 struct MD5Context md5;
6661 unsigned char digest[16];
6662 char *tmppw, *stringp;
6663
6664 tmppw = ast_strdupa(iaxs[callno]->secret);
6665 stringp = tmppw;
6666 while ((tmppw = strsep(&stringp, ";"))) {
6667 MD5Init(&md5);
6668 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
6669 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
6670 MD5Final(digest, &md5);
6671 build_encryption_keys(digest, iaxs[callno]);
6672 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
6673 if (!res) {
6675 break;
6676 }
6677 }
6678 } else
6679 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
6680 return res;
6681}
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:6563

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

9925{
9926 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
9927 struct ast_iax2_full_hdr *fh, *cur_fh;
9928
9929 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
9930 return;
9931
9932 pkt_buf->len = from_here->buf_len;
9933 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
9934
9935 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
9936 ast_mutex_lock(&to_here->lock);
9937 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
9938 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
9939 if (fh->oseqno < cur_fh->oseqno) {
9940 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
9941 break;
9942 }
9943 }
9945
9946 if (!cur_pkt_buf)
9947 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
9948
9949 to_here->iostate = IAX_IOSTATE_READY;
9950 ast_cond_signal(&to_here->cond);
9951
9952 ast_mutex_unlock(&to_here->lock);
9953}
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:210
unsigned char oseqno
Definition: iax2.h:234
unsigned char buf[1]
Definition: chan_iax2.c:1130
size_t len
Definition: chan_iax2.c:1129
ast_cond_t cond
Definition: chan_iax2.c:1155
unsigned char * buf
Definition: chan_iax2.c:1149
enum iax2_thread_iostate iostate
Definition: chan_iax2.c:1136
ast_mutex_t lock
Definition: chan_iax2.c:1154
struct iax2_thread::@129 full_frames
ssize_t buf_len
Definition: chan_iax2.c:1150

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

13620{
13621 struct iax2_registry *reg;
13622
13624
13626 while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
13627 if (sched) {
13628 AST_SCHED_DEL(sched, reg->expire);
13629 }
13630 if (reg->callno) {
13631 int callno = reg->callno;
13633 if (iaxs[callno]) {
13634 iaxs[callno]->reg = NULL;
13636 }
13638 }
13639 if (reg->dnsmgr)
13641 ast_free(reg);
13642 }
13644
13646}
@ OBJ_NODATA
Definition: astobj2.h:1044
static int user_delme_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:13610
static int peer_delme_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:13601
void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry)
Free a DNS manager entry.
Definition: dnsmgr.c:136
struct iax2_registry::@121 entry

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::entry, 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 9720 of file chan_iax2.c.

9721{
9722 unsigned short dpstatus = 0;
9723 struct iax_ie_data ied1;
9724 int mm;
9725
9726 memset(&ied1, 0, sizeof(ied1));
9727 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
9728 /* Must be started */
9729 if (ast_exists_extension(NULL, context, callednum, 1, callerid)) {
9730 dpstatus = IAX_DPSTATUS_EXISTS;
9731 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
9732 dpstatus = IAX_DPSTATUS_CANEXIST;
9733 } else {
9734 dpstatus = IAX_DPSTATUS_NONEXISTENT;
9735 }
9736 if (ast_ignore_pattern(context, callednum))
9737 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
9738 if (mm)
9739 dpstatus |= IAX_DPSTATUS_MATCHMORE;
9740 if (!skiplock)
9741 ast_mutex_lock(&iaxsl[callno]);
9742 if (iaxs[callno]) {
9743 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
9744 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
9746 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
9747 }
9748 if (!skiplock)
9749 ast_mutex_unlock(&iaxsl[callno]);
9750}
@ 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:4190
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:4205
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
Definition: pbx.c:6894
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:4210

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

9753{
9754 /* Look up for dpreq */
9755 struct dpreq_data *dpr = data;
9756 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
9757 if (dpr->callerid)
9758 ast_free(dpr->callerid);
9759 ast_free(dpr);
9760 return NULL;
9761}
static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
Definition: chan_iax2.c:9720
char context[AST_MAX_EXTENSION]
Definition: chan_iax2.c:9715
char callednum[AST_MAX_EXTENSION]
Definition: chan_iax2.c:9716
char * callerid
Definition: chan_iax2.c:9717

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

1824{
1825 ast_str_set(buf, 0, "(");
1826 if (e & IAX_ENCRYPT_AES128) {
1827 ast_str_append(buf, 0, "aes128");
1828 }
1829 if (e & IAX_ENCRYPT_KEYROTATE) {
1830 ast_str_append(buf, 0, ",keyrotate");
1831 }
1832 if (ast_str_strlen(*buf) > 1) {
1833 ast_str_append(buf, 0, ")");
1834 } else {
1835 ast_str_set(buf, 0, "No");
1836 }
1837}
#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 6616 of file chan_iax2.c.

6617{
6618 int padding;
6619 unsigned char *workspace;
6620 workspace = ast_alloca(*datalen + 32);
6621 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
6622 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
6623 if (iaxdebug)
6624 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
6625 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
6626 padding = 16 + (padding & 0xf);
6627 memcpy(workspace, poo, padding);
6628 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
6629 workspace[15] &= 0xf0;
6630 workspace[15] |= (padding & 0xf);
6631 if (iaxdebug)
6632 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02hhx)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
6633 *datalen += padding;
6634 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
6635 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
6636 memcpy(poo, workspace + *datalen - 32, 32);
6637 } else {
6638 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
6639 if (iaxdebug)
6640 ast_debug(5, "Encoding mini frame with length %d\n", *datalen);
6641 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
6642 padding = 16 + (padding & 0xf);
6643 memcpy(workspace, poo, padding);
6644 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
6645 workspace[15] &= 0xf0;
6646 workspace[15] |= (padding & 0x0f);
6647 *datalen += padding;
6648 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
6649 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
6650 memcpy(poo, workspace + *datalen - 32, 32);
6651 }
6652 return 0;
6653}
static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
Definition: chan_iax2.c:6539

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

9122{
9123#ifdef SCHED_MULTITHREADED
9125#endif
9126 __expire_registry(data);
9127 return 0;
9128}
static void __expire_registry(const void *data)
Definition: chan_iax2.c:9080

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

14358{
14359 struct iax2_dpcache *dp = NULL;
14360 struct timeval now = ast_tvnow();
14361 int x, com[2], timeout, doabort, callno;
14362
14363 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
14364 if (ast_tvcmp(now, dp->expiry) > 0) {
14365 AST_LIST_REMOVE_CURRENT(cache_list);
14366 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
14367 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
14368 else
14369 ast_free(dp);
14370 continue;
14371 }
14372 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
14373 break;
14374 }
14376
14377 if (!dp) {
14378 /* No matching entry. Create a new one. */
14379 /* First, can we make a callno? */
14380 if ((callno = cache_get_callno_locked(data)) < 0) {
14381 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
14382 return NULL;
14383 }
14384 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
14385 ast_mutex_unlock(&iaxsl[callno]);
14386 return NULL;
14387 }
14388 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
14389 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
14390 dp->expiry = ast_tvnow();
14391 dp->orig = dp->expiry;
14392 /* Expires in 30 mins by default */
14393 dp->expiry.tv_sec += iaxdefaultdpcache;
14395 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
14396 dp->waiters[x] = -1;
14397 /* Insert into the lists */
14398 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
14399 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
14400 /* Send the request if we're already up */
14401 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
14402 iax2_dprequest(dp, callno);
14403 ast_mutex_unlock(&iaxsl[callno]);
14404 }
14405
14406 /* By here we must have a dp */
14407 if (dp->flags & CACHE_FLAG_PENDING) {
14408 int res;
14409 struct pollfd pfd;
14410 /* Okay, here it starts to get nasty. We need a pipe now to wait
14411 for a reply to come back so long as it's pending */
14412 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
14413 /* Find an empty slot */
14414 if (dp->waiters[x] < 0)
14415 break;
14416 }
14417 if (x >= ARRAY_LEN(dp->waiters)) {
14418 ast_log(LOG_WARNING, "No more waiter positions available\n");
14419 return NULL;
14420 }
14421 if (pipe(com)) {
14422 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
14423 return NULL;
14424 }
14425 dp->waiters[x] = com[1];
14426 /* Okay, now we wait */
14427 timeout = iaxdefaulttimeout * 1000;
14428 /* Temporarily unlock */
14430 doabort = 0;
14431
14432 /* chan is in autoservice here, so do NOT service it here! */
14433 pfd.fd = com[0];
14434 pfd.events = POLLIN;
14435 pfd.revents = 0;
14436 /* Wait for pipe activity... if the channel hangs up, we'll catch it on the way out. */
14437 res = ast_poll(&pfd, 1, timeout);
14438 if (res < 0) {
14439 ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
14440 return NULL;
14441 } else if (!pfd.revents) {
14442 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
14443 }
14444
14445 if (chan && ast_check_hangup(chan)) {
14446 doabort = 1;
14447 }
14448
14450 dp->waiters[x] = -1;
14451 close(com[1]);
14452 close(com[0]);
14453 if (doabort) {
14454 /* Don't interpret anything, just abort. */
14455 return NULL;
14456 }
14457 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
14458 /* Now to do non-independent analysis the results of our wait */
14459 if (dp->flags & CACHE_FLAG_PENDING) {
14460 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer
14461 pending. Don't let it take as long to timeout. */
14462 dp->flags &= ~CACHE_FLAG_PENDING;
14464 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded
14465 systems without leaving it unavailable once the server comes back online */
14466 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
14467 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
14468 if (dp->waiters[x] > -1) {
14469 if (write(dp->waiters[x], "asdf", 4) < 0) {
14470 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
14471 }
14472 }
14473 }
14474 }
14475 }
14476 /* Our caller will obtain the rest */
14477 }
14478 return dp;
14479}
static int iaxdefaulttimeout
Definition: chan_iax2.c:376
static int cache_get_callno_locked(const char *data)
Definition: chan_iax2.c:14284
static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
Definition: chan_iax2.c:9543
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:444
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
char peercontext[AST_MAX_CONTEXT]
Definition: chan_iax2.c:1094
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 3307 of file chan_iax2.c.

3307 {
3308 return __find_callno(callno, dcallno, addr, new, sockfd, 0, full_frame);
3309}
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:3181

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

3311 {
3312
3313 return __find_callno(callno, dcallno, addr, new, sockfd, 1, full_frame);
3314}

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

1659{
1660 struct iax2_thread *thread = NULL;
1661
1662 /* Pop the head of the idle list off */
1666
1667 /* If we popped a thread off the idle list, just return it */
1668 if (thread) {
1669 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
1670 return thread;
1671 }
1672
1673 /* Pop the head of the dynamic list off */
1677
1678 /* If we popped a thread off the dynamic list, just return it */
1679 if (thread) {
1680 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
1681 return thread;
1682 }
1683
1684 /* If we can't create a new dynamic thread for any reason, return no thread at all */
1686 return NULL;
1687
1688 /* Set default values */
1692
1693 /* Initialize lock and condition */
1694 ast_mutex_init(&thread->lock);
1695 ast_cond_init(&thread->cond, NULL);
1696 ast_mutex_init(&thread->init_lock);
1697 ast_cond_init(&thread->init_cond, NULL);
1698 ast_mutex_lock(&thread->init_lock);
1699
1700 /* Create thread and send it on it's way */
1702 ast_cond_destroy(&thread->cond);
1703 ast_mutex_destroy(&thread->lock);
1704 ast_mutex_unlock(&thread->init_lock);
1705 ast_cond_destroy(&thread->init_cond);
1706 ast_mutex_destroy(&thread->init_lock);
1708 return NULL;
1709 }
1710
1711 /* this thread is not processing a full frame (since it is idle),
1712 so ensure that the field for the full frame call number is empty */
1713 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
1714
1715 /* Wait for the thread to be ready before returning it to the caller */
1716 ast_cond_wait(&thread->init_cond, &thread->init_lock);
1717
1718 /* Done with init_lock */
1719 ast_mutex_unlock(&thread->init_lock);
1720
1721 return thread;
1722}
static int iaxdynamicthreadcount
Definition: chan_iax2.c:746
static void * iax2_process_thread(void *data)
Definition: chan_iax2.c:12208
static int iaxdynamicthreadnum
Definition: chan_iax2.c:747
static int iaxmaxthreadcount
Definition: chan_iax2.c:745
#define ast_cond_destroy(cond)
Definition: lock.h:209
#define ast_cond_wait(cond, mutex)
Definition: lock.h:212
#define ast_cond_init(cond, attr)
Definition: lock.h:208
#define ast_mutex_init(pmutex)
Definition: lock.h:193
#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 function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno, so do not call it with a pvt lock held.

Definition at line 2082 of file chan_iax2.c.

2083{
2084 struct iax2_peer *peer = NULL;
2085
2086 peer = ao2_find(peers, name, OBJ_KEY);
2087
2088 /* Now go for realtime if applicable */
2089 if (!peer && realtime) {
2090 peer = realtime_peer(name, NULL);
2091 }
2092 return peer;
2093}

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

6365{
6366 struct iax2_trunk_peer *tpeer = NULL;
6367
6368 /* Finds and locks trunk peer */
6370
6371 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
6372 if (!ast_sockaddr_cmp(&tpeer->addr, addr)) {
6373 ast_mutex_lock(&tpeer->lock);
6374 break;
6375 }
6376 }
6377
6378 if (!tpeer) {
6379 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
6380 ast_mutex_init(&tpeer->lock);
6381 tpeer->lastsent = 9999;
6382 ast_sockaddr_copy(&tpeer->addr, addr);
6383 tpeer->trunkact = ast_tvnow();
6384 ast_mutex_lock(&tpeer->lock);
6385 tpeer->sockfd = fd;
6386
6387#ifdef SO_NO_CHECK
6388 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
6389#endif
6390 ast_debug(1, "Created trunk peer for '%s'\n", ast_sockaddr_stringify(&tpeer->addr));
6392 }
6393 }
6394
6396
6397 return tpeer;
6398}
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:667
struct iax2_trunk_peer::@120 list
ast_mutex_t lock
Definition: chan_iax2.c:665

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

2108{
2109 return ao2_find(users, name, OBJ_KEY);
2110}

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

7347{
7348 int *fd = user_data;
7349
7350 ast_cli(*fd, "%-15.15s %-15d %-15d\n",
7351 header->devname,
7352 ntohs(header->version),
7353 (int) ntohl(header->datalen));
7354
7355 return 0;
7356}

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

6175{
6176 long ms; /* NOT unsigned */
6177 if (ast_tvzero(iaxs[callno]->rxcore)) {
6178 /* Initialize rxcore time if appropriate */
6179 iaxs[callno]->rxcore = ast_tvnow();
6180 /* Round to nearest 20ms so traces look pretty */
6181 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
6182 }
6183 /* Calculate difference between trunk and channel */
6184 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
6185 /* Return as the sum of trunk time and the difference between trunk and real time */
6186 return ms + ts;
6187}

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

12667{
12668 struct iax2_context *conl;
12669 while(con) {
12670 conl = con;
12671 con = con->next;
12672 ast_free(conl);
12673 }
12674}

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

2222{
2223 if (s->f.datalen) {
2224 ast_free(s->f.data.ptr);
2225 }
2226 ast_free(s);
2227}
struct ast_frame f
Definition: chan_iax2.c:966

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

14603{
14604 struct iax2_peer *peer;
14605 char *peername, *colname;
14606
14607 peername = ast_strdupa(data);
14608
14609 /* if our channel, return the IP address of the endpoint of current channel */
14610 if (!strcmp(peername,"CURRENTCHANNEL")) {
14611 unsigned short callno;
14612 if (!chan || ast_channel_tech(chan) != &iax2_tech) {
14613 return -1;
14614 }
14617 return 0;
14618 }
14619
14620 if ((colname = strchr(peername, ',')))
14621 *colname++ = '\0';
14622 else
14623 colname = "ip";
14624
14625 if (!(peer = find_peer(peername, 1)))
14626 return -1;
14627
14628 if (!strcasecmp(colname, "ip")) {
14630 } else if (!strcasecmp(colname, "status")) {
14631 peer_status(peer, buf, len);
14632 } else if (!strcasecmp(colname, "mailbox")) {
14633 ast_copy_string(buf, peer->mailbox, len);
14634 } else if (!strcasecmp(colname, "context")) {
14635 ast_copy_string(buf, peer->context, len);
14636 } else if (!strcasecmp(colname, "expire")) {
14637 snprintf(buf, len, "%d", peer->expire);
14638 } else if (!strcasecmp(colname, "dynamic")) {
14639 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
14640 } else if (!strcasecmp(colname, "callerid_name")) {
14642 } else if (!strcasecmp(colname, "callerid_num")) {
14643 ast_copy_string(buf, peer->cid_num, len);
14644 } else if (!strcasecmp(colname, "codecs")) {
14645 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
14646
14647 iax2_getformatname_multiple(peer->capability, &codec_buf);
14648 ast_copy_string(buf, ast_str_buffer(codec_buf), len);
14649 } else if (!strncasecmp(colname, "codec[", 6)) {
14650 char *codecnum, *ptr;
14651 struct ast_format *tmpfmt;
14652
14653 /* skip over "codec" to the '[' */
14654 codecnum = colname + 5;
14655 *codecnum = '\0';
14656 codecnum++;
14657 if ((ptr = strchr(codecnum, ']'))) {
14658 *ptr = '\0';
14659 }
14660 if((iax2_codec_pref_index(&peer->prefs, atoi(codecnum), &tmpfmt))) {
14662 } else {
14663 buf[0] = '\0';
14664 }
14665 } else {
14666 buf[0] = '\0';
14667 }
14668
14669 peer_unref(peer);
14670
14671 return 0;
14672}
static const char * iax2_getformatname_multiple(iax2_format format, struct ast_str **codec_buf)
Definition: chan_iax2.c:1988
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 12875 of file chan_iax2.c.

12876{
12877 int methods = 0;
12878 if (strstr(value, "rsa"))
12880 if (strstr(value, "md5"))
12882 if (strstr(value, "plaintext"))
12884 return methods;
12885}
static struct @453 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 1839 of file chan_iax2.c.

1840{
1841 int e;
1842 if (!strcasecmp(s, "aes128"))
1844 else if (ast_true(s))
1846 else
1847 e = 0;
1848 return e;
1849}

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

4302{
4303#ifdef SCHED_MULTITHREADED
4304 if (schedule_action(__get_from_jb, data))
4305#endif
4306 __get_from_jb(data);
4307 return 0;
4308}
static void __get_from_jb(const void *p)
Definition: chan_iax2.c:4198

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

2979{
2980 struct call_number_pool *pool = NULL;
2981 callno_entry swap;
2982 size_t choice;
2983
2984 switch (type) {
2985 case CALLNO_TYPE_NORMAL:
2986 pool = &callno_pool;
2987 break;
2988 case CALLNO_TYPE_TRUNK:
2989 pool = &callno_pool_trunk;
2990 break;
2991 default:
2992 ast_assert(0);
2993 break;
2994 }
2995
2996 /* If we fail, make sure this has a defined value */
2997 *entry = 0;
2998
2999 /* We lock here primarily to ensure thread safety of the
3000 * total_nonval_callno_used check and increment */
3002
3003 /* Bail out if we don't have any available call numbers */
3004 if (!pool->available) {
3005 ast_log(LOG_WARNING, "Out of call numbers\n");
3007 return 1;
3008 }
3009
3010 /* Only a certain number of non-validated call numbers should be allocated.
3011 * If there ever is an attack, this separates the calltoken validating users
3012 * from the non-calltoken validating users. */
3015 "NON-CallToken callnumber limit is reached. Current: %d Max: %d\n",
3019 return 1;
3020 }
3021
3022 /* We use a modified Fisher-Yates-Durstenfeld Shuffle to maintain a list of
3023 * available call numbers. The array of call numbers begins as an ordered
3024 * list from 1 -> n, and we keep a running tally of how many remain unclaimed
3025 * - let's call that x. When a call number is needed we pick a random index
3026 * into the array between 0 and x and use that as our call number. In a
3027 * typical FYD shuffle, we would swap the value that we are extracting with
3028 * the number at x, but in our case we swap and don't touch the value at x
3029 * because it is effectively invisible. We rely on the rest of the IAX2 core
3030 * to return the number to us at some point. Finally, we decrement x by 1
3031 * which establishes our new unused range.
3032 *
3033 * When numbers are returned to the pool, we put them just past x and bump x
3034 * by 1 so that this number is now available for re-use. */
3035
3036 choice = ast_random() % pool->available;
3037
3038 *entry = pool->numbers[choice];
3039 swap = pool->numbers[pool->available - 1];
3040
3041 pool->numbers[choice] = swap;
3042 pool->available--;
3043
3044 if (validated) {
3046 } else {
3048 }
3049
3051
3052 return 0;
3053}
static uint16_t global_maxcallno_nonval
Definition: chan_iax2.c:1046
static ast_mutex_t callno_pool_lock
Definition: chan_iax2.c:988
#define CALLNO_ENTRY_SET_VALIDATED(a)
Definition: chan_iax2.c:978
static uint16_t total_nonval_callno_used
Definition: chan_iax2.c:1048

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

5032{
5033#define CALLTOKEN_HASH_FORMAT "%s%u%d" /* address + port + ts + randomcalldata */
5034#define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */
5035 struct ast_str *buf = ast_str_alloca(256);
5036 time_t t = time(NULL);
5037 char hash[41]; /* 40 char sha1 hash */
5038 int subclass = uncompress_subclass(fh->csub);
5039
5040 /* ----- Case 1 ----- */
5041 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */
5042 struct iax_ie_data ied = {
5043 .buf = { 0 },
5044 .pos = 0,
5045 };
5046
5047 /* create the hash with their address data and our timestamp */
5050
5051 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
5053 send_apathetic_reply(1, ntohs(fh->scallno), addr, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
5054
5055 return 1;
5056
5057 /* ----- Case 2 ----- */
5058 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */
5059 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */
5060 char *rec_ts = NULL; /* received timestamp */
5061 unsigned int rec_time; /* received time_t */
5062
5063 /* split the timestamp from the hash data */
5064 rec_hash = strchr((char *) ies->calltokendata, '?');
5065 if (rec_hash) {
5066 *rec_hash++ = '\0';
5067 rec_ts = (char *) ies->calltokendata;
5068 }
5069
5070 /* check that we have valid data before we do any comparisons */
5071 if (!rec_hash || !rec_ts) {
5072 goto reject;
5073 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
5074 goto reject;
5075 }
5076
5077 /* create a hash with their address and the _TOKEN'S_ timestamp */
5080
5081 /* compare hashes and then check timestamp delay */
5082 if (strcmp(hash, rec_hash)) {
5083 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_sockaddr_stringify(addr));
5084 goto reject; /* received hash does not match ours, reject */
5085 } else if ((t < rec_time) || ((t - rec_time) >= max_calltoken_delay)) {
5086 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_sockaddr_stringify(addr));
5087 goto reject; /* too much delay, reject */
5088 }
5089
5090 /* at this point the call token is valid, returning 0
5091 * will allow socket_process to continue as usual */
5092 requirecalltoken_mark_auto(ies->username, subclass);
5093 return 0;
5094
5095 /* ----- Case 3 ----- */
5096 } else { /* calltokens are not supported for this client, how do we respond? */
5097 if (calltoken_required(addr, ies->username, subclass)) {
5098 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"));
5099 goto reject;
5100 }
5101 return 0; /* calltoken is not required for this addr, so permit it. */
5102 }
5103
5104reject:
5105 /* received frame has failed calltoken inspection, send apathetic reject messages */
5106 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
5107 send_apathetic_reply(1, ntohs(fh->scallno), addr, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
5108 } else {
5109 send_apathetic_reply(1, ntohs(fh->scallno), addr, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
5110 }
5111
5112 return 1;
5113}
static int randomcalltokendata
Definition: chan_iax2.c:1009
static time_t max_calltoken_delay
Definition: chan_iax2.c:1011
#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:4870
#define CALLTOKEN_HASH_FORMAT
static void requirecalltoken_mark_auto(const char *name, int subclass)
Definition: chan_iax2.c:4990
@ 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 12496 of file chan_iax2.c.

12497{
12498 int force = 0;
12499 int res;
12500
12501 switch (cmd) {
12502 case CLI_INIT:
12503 e->command = "iax2 provision";
12504 e->usage =
12505 "Usage: iax2 provision <host> <template> [forced]\n"
12506 " Provisions the given peer or IP address using a template\n"
12507 " matching either 'template' or '*' if the template is not\n"
12508 " found. If 'forced' is specified, even empty provisioning\n"
12509 " fields will be provisioned as empty fields.\n";
12510 return NULL;
12511 case CLI_GENERATE:
12512 if (a->pos == 3)
12513 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
12514 return NULL;
12515 }
12516
12517 if (a->argc < 4)
12518 return CLI_SHOWUSAGE;
12519 if (a->argc > 4) {
12520 if (!strcasecmp(a->argv[4], "forced"))
12521 force = 1;
12522 else
12523 return CLI_SHOWUSAGE;
12524 }
12525 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
12526 if (res < 0)
12527 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
12528 else if (res < 1)
12529 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
12530 else
12531 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
12532 return CLI_SUCCESS;
12533}
#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 3713 of file chan_iax2.c.

3714{
3715 struct iax2_peer *peer = NULL;
3716 struct iax2_user *user = NULL;
3717 static const char * const choices[] = { "all", NULL };
3718 char *cmplt;
3719
3720 switch (cmd) {
3721 case CLI_INIT:
3722 e->command = "iax2 prune realtime";
3723 e->usage =
3724 "Usage: iax2 prune realtime [<peername>|all]\n"
3725 " Prunes object(s) from the cache\n";
3726 return NULL;
3727 case CLI_GENERATE:
3728 if (a->pos == 3) {
3729 cmplt = ast_cli_complete(a->word, choices, a->n);
3730 if (!cmplt)
3731 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
3732 return cmplt;
3733 }
3734 return NULL;
3735 }
3736 if (a->argc != 4)
3737 return CLI_SHOWUSAGE;
3738 if (!strcmp(a->argv[3], "all")) {
3739 prune_users();
3740 prune_peers();
3741 ast_cli(a->fd, "Cache flushed successfully.\n");
3742 return CLI_SUCCESS;
3743 }
3744 peer = find_peer(a->argv[3], 0);
3745 user = find_user(a->argv[3]);
3746 if (peer || user) {
3747 if (peer) {
3751 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
3752 } else {
3753 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
3754 }
3755 peer_unref(peer);
3756 }
3757 if (user) {
3760 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
3761 } else {
3762 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
3763 }
3766 }
3767 } else {
3768 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
3769 }
3770
3771 return CLI_SUCCESS;
3772}
static char * complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags)
Definition: chan_iax2.c:3964
static void prune_peers(void)
Definition: chan_iax2.c:13664
static void prune_users(void)
Definition: chan_iax2.c:13648
static int expire_registry(const void *data)
Definition: chan_iax2.c:9121
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: main/cli.c:1853

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

14262{
14263 switch (cmd) {
14264 case CLI_INIT:
14265 e->command = "iax2 reload";
14266 e->usage =
14267 "Usage: iax2 reload\n"
14268 " Reloads IAX configuration from iax.conf\n";
14269 return NULL;
14270 case CLI_GENERATE:
14271 return NULL;
14272 }
14273
14274 reload_config(0);
14275
14276 return CLI_SUCCESS;
14277}

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

7725{
7726 switch (cmd) {
7727 case CLI_INIT:
7728 e->command = "iax2 set debug {on|off|peer}";
7729 e->usage =
7730 "Usage: iax2 set debug {on|off|peer peername}\n"
7731 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
7732 return NULL;
7733 case CLI_GENERATE:
7734 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
7735 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
7736 return NULL;
7737 }
7738
7739 if (a->argc < e->args || a->argc > e->args + 1)
7740 return CLI_SHOWUSAGE;
7741
7742 if (!strcasecmp(a->argv[3], "peer")) {
7743 struct iax2_peer *peer;
7744
7745 if (a->argc != e->args + 1)
7746 return CLI_SHOWUSAGE;
7747
7748 peer = find_peer(a->argv[4], 1);
7749
7750 if (!peer) {
7751 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
7752 return CLI_FAILURE;
7753 }
7754
7756
7757 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_port(&debugaddr));
7758
7759 ao2_ref(peer, -1);
7760 } else if (!strncasecmp(a->argv[3], "on", 2)) {
7761 iaxdebug = 1;
7762 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
7763 } else {
7764 iaxdebug = 0;
7765 memset(&debugaddr, 0, sizeof(debugaddr));
7766 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
7767 }
7768 return CLI_SUCCESS;
7769}
static struct ast_sockaddr debugaddr
Definition: chan_iax2.c:1250
#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 7797 of file chan_iax2.c.

7798{
7799 switch (cmd) {
7800 case CLI_INIT:
7801 e->command = "iax2 set debug jb {on|off}";
7802 e->usage =
7803 "Usage: iax2 set debug jb {on|off}\n"
7804 " Enables/Disables jitterbuffer debugging information\n";
7805 return NULL;
7806 case CLI_GENERATE:
7807 return NULL;
7808 }
7809
7810 if (a->argc != e->args)
7811 return CLI_SHOWUSAGE;
7812
7813 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
7815 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
7816 } else {
7818 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
7819 }
7820 return CLI_SUCCESS;
7821}
static void jb_error_output(const char *fmt,...)
Definition: chan_iax2.c:1281
static void jb_debug_output(const char *fmt,...)
Definition: chan_iax2.c:1305
static void jb_warning_output(const char *fmt,...)
Definition: chan_iax2.c:1293
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 7771 of file chan_iax2.c.

7772{
7773 switch (cmd) {
7774 case CLI_INIT:
7775 e->command = "iax2 set debug trunk {on|off}";
7776 e->usage =
7777 "Usage: iax2 set debug trunk {on|off}\n"
7778 " Enables/Disables debugging of IAX trunking\n";
7779 return NULL;
7780 case CLI_GENERATE:
7781 return NULL;
7782 }
7783
7784 if (a->argc != e->args)
7785 return CLI_SHOWUSAGE;
7786
7787 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
7788 iaxtrunkdebug = 1;
7789 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
7790 } else {
7791 iaxtrunkdebug = 0;
7792 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
7793 }
7794 return CLI_SUCCESS;
7795}
static int iaxtrunkdebug
Definition: chan_iax2.c:487

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

4034{
4035 int mtuv;
4036
4037 switch (cmd) {
4038 case CLI_INIT:
4039 e->command = "iax2 set mtu";
4040 e->usage =
4041 "Usage: iax2 set mtu <value>\n"
4042 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
4043 " zero to disable. Disabling means that the operating system\n"
4044 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
4045 " packet exceeds the UDP payload size. This is substantially\n"
4046 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
4047 " greater for G.711 samples.\n";
4048 return NULL;
4049 case CLI_GENERATE:
4050 return NULL;
4051 }
4052
4053 if (a->argc != 4)
4054 return CLI_SHOWUSAGE;
4055 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
4056 mtuv = MAX_TRUNK_MTU;
4057 else
4058 mtuv = atoi(a->argv[3]);
4059
4060 if (mtuv == 0) {
4061 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
4063 return CLI_SUCCESS;
4064 }
4065 if (mtuv < 172 || mtuv > 4000) {
4066 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
4067 return CLI_SHOWUSAGE;
4068 }
4069 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
4070 global_max_trunk_mtu = mtuv;
4071 return CLI_SUCCESS;
4072}
#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:339
static int global_max_trunk_mtu
Definition: chan_iax2.c:341

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

4075{
4076 struct iax2_dpcache *dp = NULL;
4077 char tmp[1024], *pc = NULL;
4078 int s, x, y;
4079 struct timeval now = ast_tvnow();
4080
4081 switch (cmd) {
4082 case CLI_INIT:
4083 e->command = "iax2 show cache";
4084 e->usage =
4085 "Usage: iax2 show cache\n"
4086 " Display currently cached IAX Dialplan results.\n";
4087 return NULL;
4088 case CLI_GENERATE:
4089 return NULL;
4090 }
4091
4093
4094 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
4095
4096 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
4097 s = dp->expiry.tv_sec - now.tv_sec;
4098 tmp[0] = '\0';
4099 if (dp->flags & CACHE_FLAG_EXISTS)
4100 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
4101 if (dp->flags & CACHE_FLAG_NONEXISTENT)
4102 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
4103 if (dp->flags & CACHE_FLAG_CANEXIST)
4104 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
4105 if (dp->flags & CACHE_FLAG_PENDING)
4106 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
4107 if (dp->flags & CACHE_FLAG_TIMEOUT)
4108 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
4109 if (dp->flags & CACHE_FLAG_TRANSMITTED)
4110 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
4111 if (dp->flags & CACHE_FLAG_MATCHMORE)
4112 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
4113 if (dp->flags & CACHE_FLAG_UNKNOWN)
4114 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
4115 /* Trim trailing pipe */
4116 if (!ast_strlen_zero(tmp)) {
4117 tmp[strlen(tmp) - 1] = '\0';
4118 } else {
4119 ast_copy_string(tmp, "(none)", sizeof(tmp));
4120 }
4121 y = 0;
4122 pc = strchr(dp->peercontext, '@');
4123 if (!pc) {
4124 pc = dp->peercontext;
4125 } else {
4126 pc++;
4127 }
4128 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
4129 if (dp->waiters[x] > -1)
4130 y++;
4131 }
4132 if (s > 0) {
4133 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
4134 } else {
4135 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
4136 }
4137 }
4138
4140
4141 return CLI_SUCCESS;
4142}

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

2910{
2911 struct ao2_iterator i;
2912 struct peercnt *peercnt;
2913 struct ast_sockaddr addr;
2914 int found = 0;
2915
2916 switch (cmd) {
2917 case CLI_INIT:
2918 e->command = "iax2 show callnumber usage";
2919 e->usage =
2920 "Usage: iax2 show callnumber usage [IP address]\n"
2921 " Shows current IP addresses which are consuming iax2 call numbers\n";
2922 return NULL;
2923 case CLI_GENERATE:
2924 return NULL;
2925 case CLI_HANDLER:
2926 if (a->argc < 4 || a->argc > 5)
2927 return CLI_SHOWUSAGE;
2928
2929 if (a->argc == 4) {
2930 ast_cli(a->fd, "%-45s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
2931 }
2932
2934 while ((peercnt = ao2_iterator_next(&i))) {
2935 ast_sockaddr_copy(&addr, &peercnt->addr);
2936
2937 if (a->argc == 5) {
2938 if (!strcasecmp(a->argv[4], ast_sockaddr_stringify(&addr))) {
2939 ast_cli(a->fd, "%-45s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
2940 ast_cli(a->fd, "%-45s %-12d %-12d\n", ast_sockaddr_stringify(&addr), peercnt->cur, peercnt->limit);
2941 ao2_ref(peercnt, -1);
2942 found = 1;
2943 break;
2944 }
2945 } else {
2946 ast_cli(a->fd, "%-45s %-12d %-12d\n", ast_sockaddr_stringify(&addr), peercnt->cur, peercnt->limit);
2947 }
2948 ao2_ref(peercnt, -1);
2949 }
2951
2952 if (a->argc == 4) {
2953 size_t pool_avail = callno_pool.available;
2954 size_t trunk_pool_avail = callno_pool_trunk.available;
2955
2956 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
2957 "Non-CallToken Validated Callno Used: %d\n",
2960
2961 ast_cli(a->fd, "Total Available Callno: %zu\n"
2962 "Regular Callno Available: %zu\n"
2963 "Trunk Callno Available: %zu\n",
2964 pool_avail + trunk_pool_avail,
2965 pool_avail,
2966 trunk_pool_avail);
2967 } else if (a->argc == 5 && !found) {
2968 ast_cli(a->fd, "No call number table entries for %s found\n", a->argv[4] );
2969 }
2970
2971
2972 return CLI_SUCCESS;
2973 default:
2974 return NULL;
2975 }
2976}
@ CLI_HANDLER
Definition: cli.h:154
struct ast_sockaddr addr
Definition: chan_iax2.c:1054
uint16_t limit
Definition: chan_iax2.c:1058
uint16_t cur
Definition: chan_iax2.c:1056

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

7552{
7553#define FORMAT2 "%-20.20s %-40.40s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
7554#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"
7555#define FORMATB "%-20.20s %-40.40s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
7556 int x;
7557 int numchans = 0;
7558 char first_message[10] = { 0, };
7559 char last_message[10] = { 0, };
7560
7561 switch (cmd) {
7562 case CLI_INIT:
7563 e->command = "iax2 show channels";
7564 e->usage =
7565 "Usage: iax2 show channels\n"
7566 " Lists all currently active IAX channels.\n";
7567 return NULL;
7568 case CLI_GENERATE:
7569 return NULL;
7570 }
7571
7572 if (a->argc != 3)
7573 return CLI_SHOWUSAGE;
7574 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
7575 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
7576 ast_mutex_lock(&iaxsl[x]);
7577 if (iaxs[x]) {
7578 int lag, jitter, localdelay;
7579 jb_info jbinfo;
7581 jb_getinfo(iaxs[x]->jb, &jbinfo);
7582 jitter = jbinfo.jitter;
7583 localdelay = jbinfo.current - jbinfo.min;
7584 } else {
7585 jitter = -1;
7586 localdelay = 0;
7587 }
7588
7589 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
7590 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
7591 lag = iaxs[x]->remote_rr.delay;
7592 ast_cli(a->fd, FORMAT,
7593 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
7595 S_OR(iaxs[x]->username, "(None)"),
7596 iaxs[x]->callno, iaxs[x]->peercallno,
7597 iaxs[x]->oseqno, iaxs[x]->iseqno,
7598 lag,
7599 jitter,
7600 localdelay,
7601 iax2_getformatname(iaxs[x]->voiceformat),
7602 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7603 first_message,
7604 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7605 last_message);
7606 numchans++;
7607 }
7609 }
7610 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
7611 return CLI_SUCCESS;
7612#undef FORMAT
7613#undef FORMAT2
7614#undef FORMATB
7615}
#define FORMAT
const char * iax2_getformatname(iax2_format format)
iax2 wrapper function for ast_getformatname
Definition: chan_iax2.c:1976
#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 7358 of file chan_iax2.c.

7359{
7360 switch (cmd) {
7361 case CLI_INIT:
7362 e->command = "iax2 show firmware";
7363 e->usage =
7364 "Usage: iax2 show firmware\n"
7365 " Lists all known IAX firmware images.\n";
7366 return NULL;
7367 case CLI_GENERATE:
7368 return NULL;
7369 }
7370
7371 if (a->argc != 3 && a->argc != 4)
7372 return CLI_SHOWUSAGE;
7373
7374 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
7375
7377 a->argc == 3 ? NULL : a->argv[3],
7379 (void *) &a->fd);
7380
7381 return CLI_SUCCESS;
7382}
static int firmware_show_callback(struct ast_iax2_firmware_header *header, void *user_data)
Definition: chan_iax2.c:7345
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 7701 of file chan_iax2.c.

7702{
7703 int numchans = 0;
7704
7705 switch (cmd) {
7706 case CLI_INIT:
7707 e->command = "iax2 show netstats";
7708 e->usage =
7709 "Usage: iax2 show netstats\n"
7710 " Lists network status for all currently active IAX channels.\n";
7711 return NULL;
7712 case CLI_GENERATE:
7713 return NULL;
7714 }
7715 if (a->argc != 3)
7716 return CLI_SHOWUSAGE;
7717 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
7718 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
7719 numchans = ast_cli_netstats(NULL, a->fd, 1);
7720 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
7721 return CLI_SUCCESS;
7722}
static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
Definition: chan_iax2.c:7617

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

3889{
3890 char status[64];
3891 char cbuf[256];
3892 struct iax2_peer *peer;
3893 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
3894 struct ast_str *encmethods = ast_str_alloca(256);
3895 int load_realtime = 0;
3896
3897 switch (cmd) {
3898 case CLI_INIT:
3899 e->command = "iax2 show peer";
3900 e->usage =
3901 "Usage: iax2 show peer <name>\n"
3902 " Display details on specific IAX peer\n";
3903 return NULL;
3904 case CLI_GENERATE:
3905 if (a->pos == 3)
3906 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
3907 return NULL;
3908 }
3909
3910 if (a->argc < 4)
3911 return CLI_SHOWUSAGE;
3912
3913 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
3914
3915 peer = find_peer(a->argv[3], load_realtime);
3916 if (peer) {
3917 char *str_addr, *str_defaddr;
3918 char *str_port, *str_defport;
3919
3920 str_addr = ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr));
3921 str_port = ast_strdupa(ast_sockaddr_stringify_port(&peer->addr));
3922 str_defaddr = ast_strdupa(ast_sockaddr_stringify_addr(&peer->defaddr));
3923 str_defport = ast_strdupa(ast_sockaddr_stringify_port(&peer->defaddr));
3924
3925 encmethods_to_str(peer->encmethods, &encmethods);
3926 ast_cli(a->fd, "\n\n");
3927 ast_cli(a->fd, " * Name : %s\n", peer->name);
3928 ast_cli(a->fd, " Description : %s\n", peer->description);
3929 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
3930 ast_cli(a->fd, " Context : %s\n", peer->context);
3931 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
3932 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
3933 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
3934 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
3935 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
3936 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
3937 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
3938 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
3939 ast_cli(a->fd, " Expire : %d\n", peer->expire);
3940 ast_cli(a->fd, " ACL : %s\n", (ast_acl_list_is_empty(peer->acl) ? "No" : "Yes"));
3941 ast_cli(a->fd, " Addr->IP : %s Port %s\n", str_addr ? str_addr : "(Unspecified)", str_port);
3942 ast_cli(a->fd, " Defaddr->IP : %s Port %s\n", str_defaddr, str_defport);
3943 ast_cli(a->fd, " Username : %s\n", peer->username);
3944 ast_cli(a->fd, " Codecs : %s\n", iax2_getformatname_multiple(peer->capability, &codec_buf));
3945
3946 if (iax2_codec_pref_string(&peer->prefs, cbuf, sizeof(cbuf)) < 0) {
3947 strcpy(cbuf, "Error"); /* Safe */
3948 }
3949 ast_cli(a->fd, " Codec Order : %s\n", cbuf);
3950
3951 peer_status(peer, status, sizeof(status));
3952 ast_cli(a->fd, " Status : %s\n", status);
3953 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");
3954 ast_cli(a->fd, "\n");
3955 peer_unref(peer);
3956 } else {
3957 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
3958 ast_cli(a->fd, "\n");
3959 }
3960
3961 return CLI_SUCCESS;
3962}
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:623

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

7314{
7315 switch (cmd) {
7316 case CLI_INIT:
7317 e->command = "iax2 show peers";
7318 e->usage =
7319 "Usage: iax2 show peers [registered] [like <pattern>]\n"
7320 " Lists all known IAX2 peers.\n"
7321 " Optional 'registered' argument lists only peers with known addresses.\n"
7322 " Optional regular expression pattern is used to filter the peer list.\n";
7323 return NULL;
7324 case CLI_GENERATE:
7325 return NULL;
7326 }
7327
7328 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
7329 case RESULT_SHOWUSAGE:
7330 return CLI_SHOWUSAGE;
7331 case RESULT_FAILURE:
7332 return CLI_FAILURE;
7333 default:
7334 return CLI_SUCCESS;
7335 }
7336}
static int __iax2_show_peers(int fd, int *total, struct mansession *s, const int argc, const char *const argv[])
Definition: chan_iax2.c:7086
#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 7468 of file chan_iax2.c.

7469{
7470#define FORMAT2 "%-45.45s %-6.6s %-10.10s %-45.45s %8.8s %s\n"
7471#define FORMAT "%-45.45s %-6.6s %-10.10s %-45.45s %8d %s\n"
7472
7473 struct iax2_registry *reg = NULL;
7474 char host[80];
7475 char perceived[80];
7476 int counter = 0;
7477
7478 switch (cmd) {
7479 case CLI_INIT:
7480 e->command = "iax2 show registry";
7481 e->usage =
7482 "Usage: iax2 show registry\n"
7483 " Lists all registration requests and status.\n";
7484 return NULL;
7485 case CLI_GENERATE:
7486 return NULL;
7487 }
7488 if (a->argc != 3)
7489 return CLI_SHOWUSAGE;
7490 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
7493 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
7494
7495 snprintf(perceived, sizeof(perceived), "%s", ast_sockaddr_isnull(&reg->us) ? "<Unregistered>" : ast_sockaddr_stringify(&reg->us));
7496
7497 ast_cli(a->fd, FORMAT, host,
7498 (reg->dnsmgr) ? "Y" : "N",
7499 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
7500 counter++;
7501 }
7503 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
7504 return CLI_SUCCESS;
7505#undef FORMAT
7506#undef FORMAT2
7507}
static char * regstate2str(int regstate)
Definition: chan_iax2.c:7446
char username[80]
Definition: chan_iax2.c:711

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, iax2_registry::entry, 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 3987 of file chan_iax2.c.

3988{
3989 struct iax_frame *cur;
3990 int cnt = 0, dead = 0, final = 0, i = 0;
3991
3992 switch (cmd) {
3993 case CLI_INIT:
3994 e->command = "iax2 show stats";
3995 e->usage =
3996 "Usage: iax2 show stats\n"
3997 " Display statistics on IAX channel driver.\n";
3998 return NULL;
3999 case CLI_GENERATE:
4000 return NULL;
4001 }
4002
4003 if (a->argc != 3)
4004 return CLI_SHOWUSAGE;
4005
4006 for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
4007 ast_mutex_lock(&iaxsl[i]);
4009 if (cur->retries < 0)
4010 dead++;
4011 if (cur->final)
4012 final++;
4013 cnt++;
4014 }
4016 }
4017
4018 ast_cli(a->fd, " IAX Statistics\n");
4019 ast_cli(a->fd, "---------------------\n");
4020 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
4021 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
4023 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
4024
4028
4029 return CLI_SUCCESS;
4030}
static int trunk_untimed
Definition: chan_iax2.c:342
static int trunk_maxmtu
Definition: chan_iax2.c:342
static int trunk_nmaxmtu
Definition: chan_iax2.c:342
static int trunk_timed
Definition: chan_iax2.c:342
int iax_get_iframes(void)
Definition: parser.c:1351
int iax_get_oframes(void)
Definition: parser.c:1352
int iax_get_frames(void)
Definition: parser.c:1350

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

7179{
7180 struct iax2_thread *thread = NULL;
7181 time_t t;
7182 int threadcount = 0, dynamiccount = 0;
7183 char type;
7184
7185 switch (cmd) {
7186 case CLI_INIT:
7187 e->command = "iax2 show threads";
7188 e->usage =
7189 "Usage: iax2 show threads\n"
7190 " Lists status of IAX helper threads\n";
7191 return NULL;
7192 case CLI_GENERATE:
7193 return NULL;
7194 }
7195 if (a->argc != 3)
7196 return CLI_SHOWUSAGE;
7197
7198 ast_cli(a->fd, "IAX2 Thread Information\n");
7199 time(&t);
7200 ast_cli(a->fd, "Idle Threads:\n");
7203#ifdef DEBUG_SCHED_MULTITHREAD
7204 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d, func='%s'\n",
7205 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
7206#else
7207 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d\n",
7208 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
7209#endif
7210 threadcount++;
7211 }
7213 ast_cli(a->fd, "Active Threads:\n");
7216 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
7217 type = 'D';
7218 else
7219 type = 'P';
7220#ifdef DEBUG_SCHED_MULTITHREAD
7221 ast_cli(a->fd, "Thread %c%d: state=%u, update=%d, actions=%d, func='%s'\n",
7222 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
7223#else
7224 ast_cli(a->fd, "Thread %c%d: state=%u, update=%d, actions=%d\n",
7225 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
7226#endif
7227 threadcount++;
7228 }
7230 ast_cli(a->fd, "Dynamic Threads:\n");
7233#ifdef DEBUG_SCHED_MULTITHREAD
7234 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d, func='%s'\n",
7235 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
7236#else
7237 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d\n",
7238 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
7239#endif
7240 dynamiccount++;
7241 }
7243 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
7244 return CLI_SUCCESS;
7245}
static int iaxthreadcount
Definition: chan_iax2.c:744

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

6898{
6899 regex_t regexbuf;
6900 int havepattern = 0;
6901
6902#define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
6903#define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
6904
6905 struct iax2_user *user = NULL;
6906 char auth[90];
6907 char *pstr = "";
6908 struct ao2_iterator i;
6909
6910 switch (cmd) {
6911 case CLI_INIT:
6912 e->command = "iax2 show users [like]";
6913 e->usage =
6914 "Usage: iax2 show users [like <pattern>]\n"
6915 " Lists all known IAX2 users.\n"
6916 " Optional regular expression pattern is used to filter the user list.\n";
6917 return NULL;
6918 case CLI_GENERATE:
6919 return NULL;
6920 }
6921
6922 switch (a->argc) {
6923 case 5:
6924 if (!strcasecmp(a->argv[3], "like")) {
6925 if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
6926 return CLI_SHOWUSAGE;
6927 havepattern = 1;
6928 } else
6929 return CLI_SHOWUSAGE;
6930 case 3:
6931 break;
6932 default:
6933 return CLI_SHOWUSAGE;
6934 }
6935
6936 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
6937 i = ao2_iterator_init(users, 0);
6938 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
6939 if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
6940 continue;
6941
6942 if (!ast_strlen_zero(user->secret)) {
6943 ast_copy_string(auth,user->secret, sizeof(auth));
6944 } else if (!ast_strlen_zero(user->inkeys)) {
6945 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
6946 } else
6947 ast_copy_string(auth, "-no secret-", sizeof(auth));
6948
6950 pstr = "REQ Only";
6952 pstr = "Disabled";
6953 else
6954 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
6955
6956 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
6957 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
6958 ast_acl_list_is_empty(user->acl) ? "No" : "Yes", pstr);
6959 }
6961
6962 if (havepattern)
6963 regfree(&regexbuf);
6964
6965 return CLI_SUCCESS;
6966#undef FORMAT
6967#undef FORMAT2
6968}

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

3775{
3776 switch (cmd) {
3777 case CLI_INIT:
3778 e->command = "iax2 test losspct";
3779 e->usage =
3780 "Usage: iax2 test losspct <percentage>\n"
3781 " For testing, throws away <percentage> percent of incoming packets\n";
3782 return NULL;
3783 case CLI_GENERATE:
3784 return NULL;
3785 }
3786 if (a->argc != 4)
3787 return CLI_SHOWUSAGE;
3788
3789 test_losspct = atoi(a->argv[3]);
3790
3791 return CLI_SUCCESS;
3792}
static int test_losspct
Definition: chan_iax2.c:489

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

7248{
7249 struct iax2_peer *p;
7250
7251 switch (cmd) {
7252 case CLI_INIT:
7253 e->command = "iax2 unregister";
7254 e->usage =
7255 "Usage: iax2 unregister <peername>\n"
7256 " Unregister (force expiration) an IAX2 peer from the registry.\n";
7257 return NULL;
7258 case CLI_GENERATE:
7259 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
7260 }
7261
7262 if (a->argc != 3)
7263 return CLI_SHOWUSAGE;
7264
7265 p = find_peer(a->argv[2], 1);
7266 if (p) {
7267 if (p->expire > -1) {
7268 struct iax2_peer *peer;
7269
7270 peer = ao2_find(peers, a->argv[2], OBJ_KEY);
7271 if (peer) {
7272 expire_registry(peer_ref(peer)); /* will release its own reference when done */
7273 peer_unref(peer); /* ref from ao2_find() */
7274 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
7275 } else {
7276 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
7277 }
7278 } else {
7279 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
7280 }
7281 peer_unref(p);
7282 } else {
7283 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
7284 }
7285 return CLI_SUCCESS;
7286}
static char * complete_iax2_unregister(const char *line, const char *word, int pos, int state)
Definition: chan_iax2.c:7288

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

9895{
9896 struct iax2_pkt_buf *pkt_buf;
9897
9898 ast_mutex_lock(&thread->lock);
9899
9900 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
9901 ast_mutex_unlock(&thread->lock);
9902
9903 thread->buf = pkt_buf->buf;
9904 thread->buf_len = pkt_buf->len;
9905 thread->buf_size = pkt_buf->len + 1;
9906
9908
9909 thread->buf = NULL;
9910 ast_free(pkt_buf);
9911
9912 ast_mutex_lock(&thread->lock);
9913 }
9914
9915 ast_mutex_unlock(&thread->lock);
9916}
static int socket_process(struct iax2_thread *thread)
Definition: chan_iax2.c:12186
struct iax2_pkt_buf::@126 entry

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

Referenced by iax2_process_thread().

◆ handle_error()

static int handle_error ( void  )
static

Definition at line 3428 of file chan_iax2.c.

3429{
3430 /* XXX Ideally we should figure out why an error occurred and then abort those
3431 rather than continuing to try. Unfortunately, the published interface does
3432 not seem to work XXX */
3433#if 0
3434 struct sockaddr_in *sin;
3435 int res;
3436 struct msghdr m;
3437 struct sock_extended_err e;
3438 m.msg_name = NULL;
3439 m.msg_namelen = 0;
3440 m.msg_iov = NULL;
3441 m.msg_control = &e;
3442 m.msg_controllen = sizeof(e);
3443 m.msg_flags = 0;
3444 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
3445 if (res < 0)
3446 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
3447 else {
3448 if (m.msg_controllen) {
3449 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
3450 if (sin)
3451 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
3452 else
3453 ast_log(LOG_WARNING, "No address detected??\n");
3454 } else {
3455 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
3456 }
3457 }
3458#endif
3459 return 0;
3460}
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:195

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

8899{
8900 struct iax2_registry *reg;
8901 /* Start pessimistic */
8902 char peer[256] = "";
8903 char msgstatus[60];
8904 int refresh = 60;
8905 char ourip[256] = "<Unspecified>";
8906 struct ast_sockaddr oldus;
8907 struct ast_sockaddr us;
8908 int oldmsgs;
8909
8910 if (!ast_sockaddr_isnull(&ies->apparent_addr)) {
8911 ast_sockaddr_copy(&us, &ies->apparent_addr);
8912 }
8913 if (ies->username) {
8914 ast_copy_string(peer, ies->username, sizeof(peer));
8915 }
8916 if (ies->refresh) {
8917 refresh = ies->refresh;
8918 }
8919 if (ies->calling_number) {
8920 /* We don't do anything with it really, but maybe we should */
8921 }
8922 reg = iaxs[callno]->reg;
8923 if (!reg) {
8924 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
8925 return -1;
8926 }
8927 ast_sockaddr_copy(&oldus, &reg->us);
8928 oldmsgs = reg->messages;
8929 if (ast_sockaddr_cmp(&reg->addr, addr)) {
8930 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_sockaddr_stringify(addr));
8931 return -1;
8932 }
8933 ast_sockaddr_copy(&reg->us, &us);
8934 if (ies->msgcount >= 0) {
8935 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */
8936 }
8937 /* always refresh the registration at the interval requested by the server
8938 we are registering to
8939 */
8940 reg->refresh = refresh;
8942 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
8943 if (ast_sockaddr_cmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
8944
8945 if (reg->messages > 255) {
8946 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
8947 } else if (reg->messages > 1) {
8948 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
8949 } else if (reg->messages > 0) {
8950 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
8951 } else {
8952 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
8953 }
8954
8955 snprintf(ourip, sizeof(ourip), "%s", ast_sockaddr_stringify(&reg->us));
8956
8957 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_sockaddr_stringify(addr), ourip, msgstatus);
8958 iax2_publish_registry(reg->username, ast_sockaddr_stringify(addr), "Registered", NULL);
8959 }
8961 return 0;
8962}
static void iax2_publish_registry(const char *username, const char *domain, const char *status, const char *cause)
Definition: chan_iax2.c:8892
static int iax2_do_register_s(const void *data)
Definition: chan_iax2.c:8741
#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 3158 of file chan_iax2.c.

3159{
3160 if (frametype != AST_FRAME_IAX) {
3161 return 0;
3162 }
3163 switch (subclass) {
3164 case IAX_COMMAND_NEW:
3165 case IAX_COMMAND_REGREQ:
3167 case IAX_COMMAND_REGREL:
3168 return 1;
3169 case IAX_COMMAND_POKE:
3170 if (!inbound) {
3171 return 1;
3172 }
3173 break;
3174 }
3175 return 0;
3176}
@ 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 5844 of file chan_iax2.c.

5845{
5846 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5847 ast_debug(1, "Answering IAX2 call\n");
5849}
static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int)
Definition: chan_iax2.c:7882
@ 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 8964 of file chan_iax2.c.

8966{
8967 struct iax2_registry *reg;
8968
8969 if (!(reg = ast_calloc(1, sizeof(*reg) + strlen(hostname) + 1))) {
8970 return -1;
8971 }
8972
8973 reg->addr.ss.ss_family = AST_AF_UNSPEC;
8974 if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
8975 ast_free(reg);
8976 return -1;
8977 }
8978
8979 ast_copy_string(reg->username, username, sizeof(reg->username));
8980 strcpy(reg->hostname, hostname); /* Note: This is safe */
8981
8982 if (secret) {
8983 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
8984 }
8985
8986 reg->expire = -1;
8988
8989 reg->port = ast_sockaddr_port(&reg->addr);
8990
8991 if (!porta && !reg->port) {
8992 reg->port = IAX_DEFAULT_PORTNO;
8993 } else if (porta) {
8994 sscanf(porta, "%5d", &reg->port);
8995 }
8996
8997 ast_sockaddr_set_port(&reg->addr, reg->port);
8998
9002
9003 return 0;
9004}
#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:116
char secret[80]
Definition: chan_iax2.c:712

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::entry, 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 5192 of file chan_iax2.c.

5193{
5194 struct ast_sockaddr addr;
5195 char *l=NULL, *n=NULL, *tmpstr;
5196 struct iax_ie_data ied;
5197 char *defaultrdest = "s";
5198 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5199 struct parsed_dial_string pds;
5200 struct create_addr_info cai;
5201 struct ast_var_t *var;
5203 const char* osp_token_ptr;
5204 unsigned int osp_token_length;
5205 unsigned char osp_block_index;
5206 unsigned int osp_block_length;
5207 unsigned char osp_buffer[256];
5208 char encoded_prefs[32];
5209 iax2_format iax2_tmpfmt;
5210
5212 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", ast_channel_name(c));
5213 return -1;
5214 }
5215
5216 memset(&cai, 0, sizeof(cai));
5217 cai.encmethods = iax2_encryption;
5218 cai.authmethods = iax2_authmethods;
5219
5220 memset(&pds, 0, sizeof(pds));
5221 tmpstr = ast_strdupa(dest);
5222 parse_dial_string(tmpstr, &pds);
5223
5224 if (ast_strlen_zero(pds.peer)) {
5225 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
5226 return -1;
5227 }
5228 if (!pds.exten) {
5229 pds.exten = defaultrdest;
5230 }
5231 if (create_addr(pds.peer, c, &addr, &cai)) {
5232 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
5233 return -1;
5234 }
5235
5238 if (!cai.encmethods) {
5239 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
5241 return -1;
5242 }
5243 if (((cai.authmethods & IAX_AUTH_RSA) || (cai.authmethods & IAX_AUTH_MD5) || (cai.authmethods & IAX_AUTH_PLAINTEXT)) &&
5244 ast_strlen_zero(cai.secret) && ast_strlen_zero(pds.password)) {
5245 ast_log(LOG_WARNING, "Call terminated. Encryption forced but no secret provided\n");
5246 return -1;
5247 }
5248 }
5249
5250 if (!pds.username && !ast_strlen_zero(cai.username))
5251 pds.username = cai.username;
5252 if (!pds.password && !ast_strlen_zero(cai.secret))
5253 pds.password = cai.secret;
5254 if (!pds.key && !ast_strlen_zero(cai.outkey))
5255 pds.key = cai.outkey;
5256 if (!pds.context && !ast_strlen_zero(cai.peercontext))
5257 pds.context = cai.peercontext;
5258
5259 /* Keep track of the context for outgoing calls too */
5260 ast_channel_context_set(c, cai.context);
5261
5262 if (pds.port) {
5263 int bindport;
5264 if (ast_parse_arg(pds.port, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535)) {
5265 ast_sockaddr_set_port(&addr, bindport);
5266 }
5267 }
5268
5271
5272 /* Now build request */
5273 memset(&ied, 0, sizeof(ied));
5274
5275 /* On new call, first IE MUST be IAX version of caller */
5277 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
5278 if (pds.options && strchr(pds.options, 'a')) {
5279 /* Request auto answer */
5281 }
5282
5283 /* WARNING: this breaks down at 190 bits! */
5284 iax2_codec_pref_convert(&cai.prefs, encoded_prefs, sizeof(encoded_prefs), 1);
5285 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, encoded_prefs);
5286
5287 if (l) {
5291 } else if (n) {
5294 } else {
5296 }
5297
5299 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, ast_channel_dialed(c)->transit_network_select);
5301
5302 if (n)
5304 if (ast_test_flag64(iaxs[callno], IAX_SENDANI)
5305 && ast_channel_connected(c)->ani.number.valid
5306 && ast_channel_connected(c)->ani.number.str) {
5308 }
5309
5314 }
5315 if (ast_channel_redirecting(c)->from.number.valid
5316 && !ast_strlen_zero(ast_channel_redirecting(c)->from.number.str)) {
5317 iax_ie_append_str(&ied, IAX_IE_RDNIS, ast_channel_redirecting(c)->from.number.str);
5318 }
5319
5320 if (pds.context)
5321 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
5322
5323 if (pds.username)
5324 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
5325
5326 if (cai.encmethods)
5327 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
5328
5329 ast_mutex_lock(&iaxsl[callno]);
5330
5333
5334 if (pds.username)
5335 ast_string_field_set(iaxs[callno], username, pds.username);
5336
5337 iaxs[callno]->encmethods = cai.encmethods;
5338
5339 iaxs[callno]->adsi = cai.adsi;
5340
5341 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
5342 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
5343
5344 if (pds.key)
5345 ast_string_field_set(iaxs[callno], outkey, pds.key);
5346 if (pds.password)
5347 ast_string_field_set(iaxs[callno], secret, pds.password);
5348
5350 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) iax2_tmpfmt);
5351 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, iax2_tmpfmt);
5352
5353 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
5354 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
5356 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
5357
5358 if (iaxs[callno]->maxtime) {
5359 /* Initialize pingtime and auto-congest time */
5360 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
5361 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
5362 } else if (autokill) {
5363 iaxs[callno]->pingtime = autokill / 2;
5365 }
5366
5367 /* Check if there is an OSP token */
5368 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
5369 if (!ast_strlen_zero(osp_token_ptr)) {
5370 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
5371 osp_block_index = 0;
5372 while (osp_token_length > 0) {
5373 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
5374 osp_buffer[0] = osp_block_index;
5375 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
5376 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
5377 osp_block_index++;
5378 osp_token_ptr += osp_block_length;
5379 osp_token_length -= osp_block_length;
5380 }
5381 } else
5382 ast_log(LOG_WARNING, "OSP token is too long\n");
5383 } else if (iaxdebug)
5384 ast_debug(1, "OSP token is undefined\n");
5385
5386 /* send the command using the appropriate socket for this peer */
5387 iaxs[callno]->sockfd = cai.sockfd;
5388
5389 /* Add remote vars */
5390 if (variablestore) {
5391 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
5392 ast_debug(1, "Found an IAX variable store on this channel\n");
5393 AST_LIST_LOCK(variablelist);
5394 AST_LIST_TRAVERSE(variablelist, var, entries) {
5395 char tmp[256];
5396 int i;
5397 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
5398 /* Automatically divide the value up into sized chunks */
5399 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
5400 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
5402 }
5403 }
5404 AST_LIST_UNLOCK(variablelist);
5405 }
5406
5407 /* Transmit the string in a "NEW" request */
5408 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
5409 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
5410
5411 ast_mutex_unlock(&iaxsl[callno]);
5413
5414 return 0;
5415}
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:130
static int autokill
Definition: chan_iax2.c:370
static int auto_congest(const void *data)
Definition: chan_iax2.c:4835
static unsigned int iax2_datetime(const char *tz)
Definition: chan_iax2.c:4844
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1788
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:888
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:7359
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:460
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:281
char * str
Subscriber name (Malloced)
Definition: channel.h:266
Number structure.
Definition: app_followme.c:157

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

14506{
14507 int res = 0;
14508 struct iax2_dpcache *dp = NULL;
14509#if 0
14510 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14511#endif
14512 if ((priority != 1) && (priority != 2))
14513 return 0;
14514
14516 if ((dp = find_cache(chan, data, context, exten, priority))) {
14517 if (dp->flags & CACHE_FLAG_CANEXIST)
14518 res = 1;
14519 } else {
14520 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14521 }
14523
14524 return res;
14525}
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:14357

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

1955{
1956 struct ast_format_cap *cap;
1957 struct ast_format *tmpfmt;
1958 iax2_format format = 0;
1959
1962 tmpfmt = codec_choose_from_prefs(pref, cap);
1963 if (!tmpfmt) {
1964 ao2_ref(cap, -1);
1965 return 0;
1966 }
1967
1969 ao2_ref(tmpfmt, -1);
1970 ao2_ref(cap, -1);
1971 }
1972
1973 return format;
1974}
static struct ast_format * codec_choose_from_prefs(struct iax2_codec_pref *pref, struct ast_format_cap *cap)
Definition: chan_iax2.c:1920
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 4844 of file chan_iax2.c.

4845{
4846 struct timeval t = ast_tvnow();
4847 struct ast_tm tm;
4848 unsigned int tmp;
4849 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
4850 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */
4851 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */
4852 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */
4853 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */
4854 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */
4855 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
4856 return tmp;
4857}
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, 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 2150 of file chan_iax2.c.

2151{
2152 int sched_id = (int)(long)data;
2153
2155
2156 return 0;
2157}
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 3532 of file chan_iax2.c.

3533{
3534 struct chan_iax2_pvt *pvt = NULL;
3535 struct ast_channel *owner = NULL;
3536
3537retry:
3538 if ((pvt = iaxs[callno])) {
3539#if 0
3540 /* iax2_destroy_helper gets called from this function later on. When
3541 * called twice, we get the (previously) familiar FRACK! errors in
3542 * devmode, from the scheduler. An alternative to this approach is to
3543 * reset the scheduler entries to -1 when they're deleted in
3544 * iax2_destroy_helper(). That approach was previously decided to be
3545 * "wrong" because "the memory is going to be deallocated anyway. Why
3546 * should we be resetting those values?" */
3548#endif
3549 }
3550
3551 owner = pvt ? pvt->owner : NULL;
3552
3553 if (owner) {
3554 if (ast_channel_trylock(owner)) {
3555 ast_debug(3, "Avoiding IAX destroy deadlock\n");
3556 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
3557 goto retry;
3558 }
3559 }
3560
3561 if (!owner) {
3562 iaxs[callno] = NULL;
3563 }
3564
3565 if (pvt) {
3566 if (!owner) {
3567 pvt->owner = NULL;
3568 } else {
3569 /* If there's an owner, prod it to give up */
3570 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
3571 * because we already hold the owner channel lock. */
3572 ast_queue_hangup(owner);
3573 }
3574
3575 if (pvt->peercallno) {
3577 }
3578
3579 if (pvt->transfercallno) {
3581 }
3582
3583 if (!owner) {
3584 ao2_ref(pvt, -1);
3585 pvt = NULL;
3586 }
3587 }
3588
3589 if (owner) {
3590 ast_channel_unlock(owner);
3591 }
3592}
static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:2161
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1180
#define ast_channel_trylock(chan)
Definition: channel.h:2974
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:486

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

2162{
2163 /* Decrement AUTHREQ count if needed */
2164 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) {
2165 struct iax2_user *user;
2166
2168 if (user) {
2169 ast_atomic_fetchadd_int(&user->curauthreq, -1);
2171 }
2172
2174 }
2175
2176
2177 /* Mark call destroy initiated flag. */
2178 pvt->destroy_initiated = 1;
2179
2180 /*
2181 * Schedule deleting the scheduled (but didn't run yet) PINGs or LAGRQs.
2182 * Already running tasks will be terminated because of destroy_initiated.
2183 *
2184 * Don't call AST_SCHED_DEL from this thread for pingid and lagid because
2185 * it leads to a deadlock between the scheduler thread callback locking
2186 * the callno mutex and this thread which holds the callno mutex one or
2187 * more times. It is better to have another thread delete the scheduled
2188 * callbacks which doesn't lock the callno mutex.
2189 */
2190 iax2_sched_add(sched, 0, iax2_delete_from_sched, (void*)(long)pvt->pingid);
2191 iax2_sched_add(sched, 0, iax2_delete_from_sched, (void*)(long)pvt->lagid);
2192
2193 pvt->pingid = -1;
2194 pvt->lagid = -1;
2195
2196 AST_SCHED_DEL(sched, pvt->autoid);
2197 AST_SCHED_DEL(sched, pvt->authid);
2198 AST_SCHED_DEL(sched, pvt->initid);
2199 AST_SCHED_DEL(sched, pvt->jbid);
2201}
static int iax2_delete_from_sched(const void *data)
Definition: chan_iax2.c:2150
int destroy_initiated
Definition: chan_iax2.c:956

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

14716{
14717 struct parsed_dial_string pds;
14718 char *tmp = ast_strdupa(data);
14719 struct iax2_peer *p;
14720 int res = AST_DEVICE_INVALID;
14721
14722 memset(&pds, 0, sizeof(pds));
14723 parse_dial_string(tmp, &pds);
14724
14725 if (ast_strlen_zero(pds.peer)) {
14726 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
14727 return res;
14728 }
14729
14730 ast_debug(3, "Checking device state for device %s\n", pds.peer);
14731
14732 /* SLD: FIXME: second call to find_peer during registration */
14733 if (!(p = find_peer(pds.peer, 1)))
14734 return res;
14735
14737
14738 ast_debug(3, "Found peer. What's device state of %s? addr=%s, defaddr=%s maxms=%d, lastms=%d\n",
14740
14741 if (((!ast_sockaddr_isnull(&p->addr)) || (!ast_sockaddr_isnull(&p->defaddr))) &&
14742 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
14743 /* Peer is registered, or have default IP address
14744 and a valid registration */
14745 if (p->historicms == 0 || p->historicms <= p->maxms)
14746 /* let the core figure out whether it is in use or not */
14747 res = AST_DEVICE_UNKNOWN;
14748 }
14749
14750 peer_unref(p);
14751
14752 return res;
14753}
@ AST_DEVICE_UNKNOWN
Definition: devicestate.h:53
@ AST_DEVICE_INVALID
Definition: devicestate.h:57
int historicms
Definition: chan_iax2.c:650

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

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

12355{
12356 struct iax_ie_data ied;
12357 if (iaxdebug)
12358 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
12359
12360 if (reg->dnsmgr &&
12361 ((reg->regstate == REG_STATE_TIMEOUT) || ast_sockaddr_isnull(&reg->addr))) {
12362 /* Maybe the IP has changed, force DNS refresh */
12364 }
12365
12366 /*
12367 * if IP has Changed, free allocated call to create a new one with new IP
12368 * call has the pointer to IP and must be updated to the new one
12369 */
12370 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
12371 int callno = reg->callno;
12372 ast_mutex_lock(&iaxsl[callno]);
12373 iax2_destroy(callno);
12374 ast_mutex_unlock(&iaxsl[callno]);
12375 reg->callno = 0;
12376 }
12377 if (ast_sockaddr_isnull(&reg->addr)) {
12378 if (iaxdebug)
12379 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
12380 /* Setup the next registration attempt */
12382 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
12383 return -1;
12384 }
12385 if (!ast_sockaddr_port(&reg->addr) && reg->port) {
12386 ast_sockaddr_set_port(&reg->addr, reg->port);
12387 }
12388
12389 if (!reg->callno) {
12390
12391 ast_debug(3, "Allocate call number\n");
12392
12393 reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
12394 if (reg->callno < 1) {
12395 ast_log(LOG_WARNING, "Unable to create call for registration\n");
12396 return -1;
12397 } else
12398 ast_debug(3, "Registration created on call %d\n", reg->callno);
12399 iaxs[reg->callno]->reg = reg;
12401 }
12402 /* Setup the next registration a little early */
12404 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
12405 /* Send the request */
12406 memset(&ied, 0, sizeof(ied));
12409 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */
12410 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
12412 return 0;
12413}
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 8741 of file chan_iax2.c.

8742{
8743#ifdef SCHED_MULTITHREADED
8745#endif
8747 return 0;
8748}
static void __iax2_do_register_s(const void *data)
Definition: chan_iax2.c:8723

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

9544{
9545 struct iax_ie_data ied;
9546 /* Auto-hangup with 30 seconds of inactivity */
9547 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
9548 sched, 30000, auto_hangup, (void *)(long)callno);
9549 memset(&ied, 0, sizeof(ied));
9551 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
9553}
static int auto_hangup(const void *data)
Definition: chan_iax2.c:9528
@ 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 1601 of file chan_iax2.c.

1602{
1603 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
1604 struct ast_var_t *oldvar, *newvar;
1605
1606 newlist = ast_calloc(sizeof(*newlist), 1);
1607 if (!newlist) {
1608 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
1609 return NULL;
1610 }
1611
1612 AST_LIST_HEAD_INIT(newlist);
1613 AST_LIST_LOCK(oldlist);
1614 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
1615 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
1616 if (newvar)
1617 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
1618 else
1619 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
1620 }
1621 AST_LIST_UNLOCK(oldlist);
1622 return newlist;
1623}

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

14552{
14553 char odata[256];
14554 char req[sizeof(odata) + AST_MAX_CONTEXT + AST_MAX_EXTENSION + sizeof("IAX2//@")];
14555 char *ncontext;
14556 struct iax2_dpcache *dp = NULL;
14557 struct ast_app *dial = NULL;
14558#if 0
14559 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);
14560#endif
14561 if (priority == 2) {
14562 /* Indicate status, can be overridden in dialplan */
14563 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
14564 if (dialstatus) {
14565 dial = pbx_findapp(dialstatus);
14566 if (dial)
14567 pbx_exec(chan, dial, "");
14568 }
14569 return -1;
14570 } else if (priority != 1)
14571 return -1;
14572
14574 if ((dp = find_cache(chan, data, context, exten, priority))) {
14575 if (dp->flags & CACHE_FLAG_EXISTS) {
14576 ast_copy_string(odata, data, sizeof(odata));
14577 ncontext = strchr(odata, '/');
14578 if (ncontext) {
14579 *ncontext = '\0';
14580 ncontext++;
14581 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
14582 } else {
14583 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
14584 }
14585 ast_verb(3, "Executing Dial('%s')\n", req);
14586 } else {
14588 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
14589 return -1;
14590 }
14591 }
14593
14594 if ((dial = pbx_findapp("Dial")))
14595 return pbx_exec(chan, dial, req);
14596 else
14597 ast_log(LOG_WARNING, "No dial application registered\n");
14598
14599 return -1;
14600}
#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 14482 of file chan_iax2.c.

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

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

4442{
4443 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(newchan));
4444 ast_mutex_lock(&iaxsl[callno]);
4445 if (iaxs[callno])
4446 iaxs[callno]->owner = newchan;
4447 else
4448 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
4449 ast_mutex_unlock(&iaxsl[callno]);
4450 return 0;
4451}

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

2204{
2206 iax_frame_free(fr);
2207}
void iax_frame_free(struct iax_frame *fr)
Definition: parser.c:1296

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

1626{
1627 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
1628 struct ast_var_t *oldvar;
1629
1630 AST_LIST_LOCK(oldlist);
1631 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
1632 ast_free(oldvar);
1633 }
1634 AST_LIST_UNLOCK(oldlist);
1635 AST_LIST_HEAD_DESTROY(oldlist);
1636 ast_free(oldlist);
1637}
#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 1976 of file chan_iax2.c.

1977{
1978 struct ast_format *tmpfmt;
1979
1981 if (!tmpfmt) {
1982 return "Unknown";
1983 }
1984
1985 return ast_format_get_name(tmpfmt);
1986}

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

1989{
1991
1992 if (!cap) {
1993 return "(Nothing)";
1994 }
1996 ast_format_cap_get_names(cap, codec_buf);
1997 ao2_ref(cap, -1);
1998
1999 return ast_str_buffer(*codec_buf);
2000}
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 2118 of file chan_iax2.c.

2119{
2120 struct iax2_peer *peer = NULL;
2121 int res = 0;
2122 struct ao2_iterator i;
2123
2124 i = ao2_iterator_init(peers, 0);
2125 while ((peer = ao2_iterator_next(&i))) {
2126
2127 if (!ast_sockaddr_cmp(&peer->addr, &addr)) {
2128 ast_copy_string(host, peer->name, len);
2129 peer_unref(peer);
2130 res = 1;
2131 break;
2132 }
2133 peer_unref(peer);
2134 }
2136
2137 if (!peer) {
2138 peer = realtime_peer(NULL, &addr);
2139 if (peer) {
2140 ast_copy_string(host, peer->name, len);
2141 peer_unref(peer);
2142 res = 1;
2143 }
2144 }
2145
2146 return res;
2147}

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

5925{
5926 struct iax2_peer *peer;
5927 int res = 0;
5928 struct ao2_iterator i;
5929
5930 i = ao2_iterator_init(peers, 0);
5931 while ((peer = ao2_iterator_next(&i))) {
5932
5933 if (!ast_sockaddr_cmp(&peer->addr, &addr)) {
5934 res = ast_test_flag64(peer, IAX_TRUNK);
5935 peer_unref(peer);
5936 break;
5937 }
5938 peer_unref(peer);
5939 }
5941
5942 return res;
5943}

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

5418{
5419 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5420 struct iax_ie_data ied;
5421 int alreadygone;
5422 memset(&ied, 0, sizeof(ied));
5423 ast_mutex_lock(&iaxsl[callno]);
5424 if (callno && iaxs[callno]) {
5425 ast_debug(1, "We're hanging up %s now...\n", ast_channel_name(c));
5426 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
5427 /* Send the hangup unless we have had a transmission error or are already gone */
5429 if (!iaxs[callno]->error && !alreadygone) {
5430 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
5431 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
5432 }
5433 if (!iaxs[callno]) {
5434 ast_mutex_unlock(&iaxsl[callno]);
5435 return 0;
5436 }
5437 }
5438 /* Explicitly predestroy it */
5439 iax2_predestroy(callno);
5440 /* If we were already gone to begin with, destroy us now */
5441 if (iaxs[callno] && alreadygone) {
5442 ast_debug(1, "Really destroying %s now...\n", ast_channel_name(c));
5443 iax2_destroy(callno);
5444 } else if (iaxs[callno]) {
5445 if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
5446 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
5447 iax2_destroy(callno);
5448 }
5449 }
5450 } else if (ast_channel_tech_pvt(c)) {
5451 /* If this call no longer exists, but the channel still
5452 * references it we need to set the channel's tech_pvt to null
5453 * to avoid ast_channel_free() trying to free it.
5454 */
5456 }
5457 ast_mutex_unlock(&iaxsl[callno]);
5458 ast_verb(3, "Hungup '%s'\n", ast_channel_name(c));
5459 return 0;
5460}
static int iax2_predestroy(int callno)
Definition: chan_iax2.c:3509
static int scheduled_destroy(const void *vid)
Definition: chan_iax2.c:2209
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 5851 of file chan_iax2.c.

5852{
5853 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5854 struct chan_iax2_pvt *pvt;
5855 int res = 0;
5856
5857 if (iaxdebug)
5858 ast_debug(1, "Indicating condition %d\n", condition);
5859
5861 pvt = iaxs[callno];
5862
5863 if (wait_for_peercallno(pvt)) {
5864 res = -1;
5865 goto done;
5866 }
5867
5868 switch (condition) {
5869 case AST_CONTROL_HOLD:
5870 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
5871 ast_moh_start(c, data, pvt->mohinterpret);
5872 goto done;
5873 }
5874 break;
5875 case AST_CONTROL_UNHOLD:
5876 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
5877 ast_moh_stop(c);
5878 goto done;
5879 }
5880 break;
5884 /* We are not configured to allow sending these updates. */
5885 ast_debug(2, "Callno %d: Config blocked sending control frame %d.\n",
5886 callno, condition);
5887 goto done;
5888 }
5889 break;
5892 res = -1;
5893 goto done;
5894 }
5895
5896 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
5897
5898done:
5900
5901 return res;
5902}
static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:5465
@ 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:7739
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7749
const ast_string_field mohinterpret
Definition: chan_iax2.c:886
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 1430 of file chan_iax2.c.

1431{
1432 enum ast_control_frame_type control = subtype;
1433 int is_allowed;
1434
1435 /*
1436 * Note: If we compare the enumeration type, which does not have any
1437 * negative constants, the compiler may optimize this code away.
1438 * Therefore, we must perform an integer comparison here.
1439 */
1440 if (subtype == -1) {
1441 return -1;
1442 }
1443
1444 /* Default to not allowing control frames to pass. */
1445 is_allowed = 0;
1446
1447 /*
1448 * The switch default is not present in order to take advantage
1449 * of the compiler complaining of a missing enum case.
1450 */
1451 switch (control) {
1452 /*
1453 * These control frames make sense to send/receive across the link.
1454 */
1455 case AST_CONTROL_HANGUP:
1456 case AST_CONTROL_RING:
1458 case AST_CONTROL_ANSWER:
1459 case AST_CONTROL_BUSY:
1463 case AST_CONTROL_FLASH:
1464 case AST_CONTROL_WINK:
1465 case AST_CONTROL_OPTION:
1470 case AST_CONTROL_HOLD:
1471 case AST_CONTROL_UNHOLD:
1476 case AST_CONTROL_AOC:
1478 case AST_CONTROL_MCID:
1479 is_allowed = -1;
1480 break;
1481
1482 /*
1483 * These control frames do not make sense to send/receive across the link.
1484 */
1486 /* The control value is deprecated in favor of AST_CONTROL_T38_PARAMETERS. */
1488 /* Across an IAX link the source is still the same. */
1490 /* A success/fail status report from calling ast_transfer() on this machine. */
1491 case AST_CONTROL_CC:
1492 /* The payload contains pointers that are valid for the sending machine only. */
1494 /* Across an IAX link the source is still the same. */
1496 /* The action can only be done by the sending machine. */
1498 /* This frame would cause the call to unexpectedly hangup. */
1500 /* Only meaningful across a bridge on this machine for direct-media exchange. */
1502 /* Intended only for the sending machine's local channel structure. */
1504 /* Intended only for masquerades when calling ast_indicate_data(). */
1506 /* Intended only for internal stream topology manipulation. */
1508 /* Intended only for internal stream topology change notification. */
1515 case AST_CONTROL_PLAYBACK_BEGIN: /* Only supported by app_dial currently */
1516 /* None of these playback stream control frames should go across the link. */
1521 /* None of these media recording control frames should go across the link. */
1522 break;
1523 }
1524 return is_allowed;
1525}
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_PLAYBACK_BEGIN
@ 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_PLAYBACK_BEGIN, 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 5579 of file chan_iax2.c.

5580{
5581 int res = 0;
5582 struct chan_iax2_pvt *pvt = (void *) vpvt;
5583 struct MD5Context md5;
5584 char key[17] = "";
5585 struct iax_ie_data ied = {
5586 .pos = 0,
5587 };
5588
5589 ast_mutex_lock(&iaxsl[pvt->callno]);
5590 pvt->keyrotateid = ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
5591
5592 snprintf(key, sizeof(key), "%lX", (unsigned long)ast_random());
5593
5594 MD5Init(&md5);
5595 MD5Update(&md5, (unsigned char *) key, strlen(key));
5596 MD5Final((unsigned char *) key, &md5);
5597
5598 IAX_DEBUGDIGEST("Sending", key);
5599
5600 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
5601
5602 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
5603
5604 build_ecx_key((unsigned char *) key, pvt);
5605
5607
5608 return res;
5609}
static int iax2_key_rotate(const void *vpvt)
Definition: chan_iax2.c:5579
#define IAX_DEBUGDIGEST(msg, key)
Definition: chan_iax2.c:467
@ 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 1771 of file chan_iax2.c.

1772{
1773 ast_mutex_lock(&iaxsl[callno]);
1774
1775 /* We acquired the lock; but the call was already destroyed (we came after full hang up procedures)
1776 * or destroy initiated (in middle of hang up procedure. */
1777 if (!iaxs[callno] || iaxs[callno]->destroy_initiated) {
1778 ast_debug(3, "I wanted to lock callno %d, but it is dead or going to die.\n", callno);
1779 ast_mutex_unlock(&iaxsl[callno]);
1780 return 0;
1781 }
1782
1783 /* Lock acquired, and callno is alive and kicking. */
1784 return 1;
1785}

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

1407{
1408 for (;;) {
1409 if (!iaxs[callno] || !iaxs[callno]->owner) {
1410 /* There is no owner lock to get. */
1411 break;
1412 }
1413 if (!ast_channel_trylock(iaxs[callno]->owner)) {
1414 /* We got the lock */
1415 break;
1416 }
1417 /* Avoid deadlock by pausing and trying again */
1418 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
1419 }
1420}

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

14529{
14530 int res = 0;
14531 struct iax2_dpcache *dp = NULL;
14532#if 0
14533 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14534#endif
14535 if ((priority != 1) && (priority != 2))
14536 return 0;
14537
14539 if ((dp = find_cache(chan, data, context, exten, priority))) {
14540 if (dp->flags & CACHE_FLAG_MATCHMORE)
14541 res = 1;
14542 } else {
14543 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14544 }
14546
14547 return res;
14548}

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

2003{
2004 int res, i;
2005 struct ast_format_cap *cap;
2006
2007 /* We want to add the formats to the cap in the preferred order */
2009 if (!cap || iax2_codec_pref_to_cap(pref, cap)) {
2010 ao2_cleanup(cap);
2011 return 1;
2012 }
2013
2014 res = ast_format_cap_update_by_allow_disallow(cap, list, allowing);
2015
2016 /* Adjust formats bitfield and pref list to match. */
2019
2020 for (i = 0; i < ast_format_cap_count(cap); i++) {
2021 struct ast_format *fmt = ast_format_cap_get_format(cap, i);
2022
2024 ao2_ref(fmt, -1);
2025 }
2026
2027 ao2_ref(cap, -1);
2028
2029 return res;
2030}
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 12564 of file chan_iax2.c.

12565{
12566 struct iax2_peer *peer = (struct iax2_peer *)data;
12567 peer->pokeexpire = -1;
12568#ifdef SCHED_MULTITHREADED
12570#endif
12572 peer_unref(peer);
12573 return 0;
12574}
static void __iax2_poke_noanswer(const void *data)
Definition: chan_iax2.c:12535

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

12586{
12587 int callno;
12588 int poke_timeout;
12589
12590 if (!peer->maxms || (ast_sockaddr_isnull(&peer->addr) && !peer->dnsmgr)) {
12591 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
12592 immediately after clearing things out */
12593 peer->lastms = 0;
12594 peer->historicms = 0;
12595 peer->pokeexpire = -1;
12596 peer->callno = 0;
12597 return 0;
12598 }
12599
12600 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
12601 if ((callno = peer->callno) > 0) {
12602 ast_log(LOG_NOTICE, "Still have a callno...\n");
12603 ast_mutex_lock(&iaxsl[callno]);
12604 iax2_destroy(callno);
12605 ast_mutex_unlock(&iaxsl[callno]);
12606 }
12607 if (heldcall)
12608 ast_mutex_unlock(&iaxsl[heldcall]);
12609 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
12610 if (heldcall)
12611 ast_mutex_lock(&iaxsl[heldcall]);
12612 if (callno < 1) {
12613 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12614 return -1;
12615 }
12616
12617 if (peer->pokeexpire > -1) {
12618 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
12619 peer->pokeexpire = -1;
12620 peer_unref(peer);
12621 }
12622 }
12623
12624 if (peer->lastms < 0){
12625 /* If the host is already unreachable then use time less than the unreachable
12626 * interval. 5/6 is arbitrary multiplier to get value less than
12627 * peer->pokefreqnotok. Value less than peer->pokefreqnotok is used to expire
12628 * current POKE before starting new POKE (which is scheduled after
12629 * peer->pokefreqnotok). */
12630 poke_timeout = peer->pokefreqnotok * 5 / 6;
12631 } else {
12632 /* If the host is reachable, use timeout large enough to allow for multiple
12633 * POKE retries. Limit this value to less than peer->pokefreqok. 5/6 is arbitrary
12634 * multiplier to get value less than peer->pokefreqok. Value less than
12635 * peer->pokefreqok is used to expire current POKE before starting new POKE
12636 * (which is scheduled after peer->pokefreqok). */
12637 poke_timeout = MIN(MAX_RETRY_TIME * 2 + peer->maxms, peer->pokefreqok * 5 / 6);
12638 }
12639
12640 /* Queue up a new task to handle no reply */
12641 peer->pokeexpire = iax2_sched_add(sched, poke_timeout, iax2_poke_noanswer, peer_ref(peer));
12642
12643 if (peer->pokeexpire == -1)
12644 peer_unref(peer);
12645
12646 /* And send the poke */
12647 ast_mutex_lock(&iaxsl[callno]);
12648 if (iaxs[callno]) {
12649 struct iax_ie_data ied = {
12650 .buf = { 0 },
12651 .pos = 0,
12652 };
12653
12654 /* Speed up retransmission times for this qualify call */
12655 iaxs[callno]->pingtime = peer->maxms / 8;
12656 iaxs[callno]->peerpoke = peer;
12657
12658 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
12659 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12660 }
12661 ast_mutex_unlock(&iaxsl[callno]);
12662
12663 return 0;
12664}
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:3307
static int iax2_poke_noanswer(const void *data)
Definition: chan_iax2.c:12564
struct iax2_peer * peerpoke
Definition: chan_iax2.c:909
#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 12576 of file chan_iax2.c.

12577{
12578 struct iax2_peer *peer = obj;
12579
12580 iax2_poke_peer(peer, 0);
12581
12582 return 0;
12583}

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

9581{
9582 struct iax2_peer *peer = (struct iax2_peer *)data;
9583 peer->pokeexpire = -1;
9584#ifdef SCHED_MULTITHREADED
9586#endif
9587 __iax2_poke_peer_s(data);
9588 return 0;
9589}
static void __iax2_poke_peer_s(const void *data)
Definition: chan_iax2.c:9573

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

3510{
3511 struct ast_channel *c = NULL;
3512 struct chan_iax2_pvt *pvt = iaxs[callno];
3513
3514 if (!pvt)
3515 return -1;
3516
3517 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
3520 }
3521
3522 if ((c = pvt->owner)) {
3525 pvt->owner = NULL;
3527 }
3528
3529 return 0;
3530}
static int iax2_queue_hangup(int callno)
Queue a hangup frame on the ast_channel owner.
Definition: chan_iax2.c:3395
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:483

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

12209{
12210 struct iax2_thread *thread = data;
12211 struct timeval wait;
12212 struct timespec ts;
12213 int put_into_idle = 0;
12214 int first_time = 1;
12215 int old_state;
12216
12218
12219 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
12220 pthread_cleanup_push(iax2_process_thread_cleanup, data);
12221
12222 for (;;) {
12223 /* Wait for something to signal us to be awake */
12224 ast_mutex_lock(&thread->lock);
12225
12226 if (thread->stop) {
12227 ast_mutex_unlock(&thread->lock);
12228 break;
12229 }
12230
12231 /* Flag that we're ready to accept signals */
12232 if (first_time) {
12233 signal_condition(&thread->init_lock, &thread->init_cond);
12234 first_time = 0;
12235 }
12236
12237 /* Put into idle list if applicable */
12238 if (put_into_idle) {
12240 }
12241
12242 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
12243 struct iax2_thread *t = NULL;
12244 /* Wait to be signalled or time out */
12245 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
12246 ts.tv_sec = wait.tv_sec;
12247 ts.tv_nsec = wait.tv_usec * 1000;
12248 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
12249 /* This thread was never put back into the available dynamic
12250 * thread list, so just go away. */
12251 if (!put_into_idle || thread->stop) {
12252 ast_mutex_unlock(&thread->lock);
12253 break;
12254 }
12256 /* Account for the case where this thread is acquired *right* after a timeout */
12260 if (t) {
12261 /* This dynamic thread timed out waiting for a task and was
12262 * not acquired immediately after the timeout,
12263 * so it's time to go away. */
12264 ast_mutex_unlock(&thread->lock);
12265 break;
12266 }
12267 /* Someone grabbed our thread *right* after we timed out.
12268 * Wait for them to set us up with something to do and signal
12269 * us to continue. */
12270 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
12271 ts.tv_sec = wait.tv_sec;
12272 ts.tv_nsec = wait.tv_usec * 1000;
12273 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
12274 ast_mutex_unlock(&thread->lock);
12275 break;
12276 }
12277 }
12278 } else {
12279 ast_cond_wait(&thread->cond, &thread->lock);
12280 }
12281
12282 /* Go back into our respective list */
12283 put_into_idle = 1;
12284
12285 ast_mutex_unlock(&thread->lock);
12286
12287 if (thread->stop) {
12288 break;
12289 }
12290
12291 /* See what we need to do */
12292 switch (thread->iostate) {
12293 case IAX_IOSTATE_IDLE:
12294 continue;
12295 case IAX_IOSTATE_READY:
12296 thread->actions++;
12297 thread->iostate = IAX_IOSTATE_PROCESSING;
12300 break;
12302 thread->actions++;
12303 thread->iostate = IAX_IOSTATE_PROCESSING;
12304#ifdef SCHED_MULTITHREADED
12305 thread->schedfunc(thread->scheddata);
12306#endif
12307 break;
12308 default:
12309 break;
12310 }
12311
12312 /* The network thread added us to the active_thread list when we were given
12313 * frames to process, Now that we are done, we must remove ourselves from
12314 * the active list, and return to the idle list */
12318
12319 /* Make sure another frame didn't sneak in there after we thought we were done. */
12321
12322 time(&thread->checktime);
12323 thread->iostate = IAX_IOSTATE_IDLE;
12324#ifdef DEBUG_SCHED_MULTITHREAD
12325 thread->curfunc[0]='\0';
12326#endif
12327 }
12328
12329 /*!
12330 * \note For some reason, idle threads are exiting without being
12331 * removed from an idle list, which is causing memory
12332 * corruption. Forcibly remove it from the list, if it's there.
12333 */
12337
12341
12342 if (!thread->stop) {
12343 /* Nobody asked me to stop so nobody is waiting to join me. */
12344 pthread_detach(pthread_self());
12345 }
12346
12347 /* I am exiting here on my own volition, I need to clean up my own data structures
12348 * Assume that I am no longer in any of the lists (idle, active, or dynamic)
12349 */
12350 pthread_cleanup_pop(1);
12351 return NULL;
12352}
static int iaxactivethreadcount
Definition: chan_iax2.c:748
static void insert_idle_thread(struct iax2_thread *thread)
Definition: chan_iax2.c:1643
static void handle_deferred_full_frames(struct iax2_thread *thread)
Handle any deferred full frames for this thread.
Definition: chan_iax2.c:9894
static void iax2_process_thread_cleanup(void *data)
Definition: chan_iax2.c:12196
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:213

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

12197{
12198 struct iax2_thread *thread = data;
12199 ast_mutex_destroy(&thread->lock);
12200 ast_cond_destroy(&thread->cond);
12201 ast_mutex_destroy(&thread->init_lock);
12202 ast_cond_destroy(&thread->init_cond);
12204 /* Ignore check_return warning from Coverity for ast_atomic_dec_and_test below */
12206}
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:774

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

12416{
12417 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
12418 is found for template */
12419 struct iax_ie_data provdata;
12420 struct iax_ie_data ied;
12421 unsigned int sig;
12422 struct ast_sockaddr addr;
12423 int callno;
12424 struct create_addr_info cai;
12425
12426 memset(&cai, 0, sizeof(cai));
12427
12428 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
12429
12430 if (iax_provision_build(&provdata, &sig, template, force)) {
12431 ast_debug(1, "No provisioning found for template '%s'\n", template);
12432 return 0;
12433 }
12434
12435 if (end) {
12436 ast_sockaddr_copy(&addr, end);
12437 cai.sockfd = sockfd;
12438 } else if (create_addr(dest, NULL, &addr, &cai))
12439 return -1;
12440
12441 /* Build the rest of the message */
12442 memset(&ied, 0, sizeof(ied));
12443 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
12444
12445 callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
12446 if (!callno)
12447 return -1;
12448
12449 if (iaxs[callno]) {
12450 /* Schedule autodestruct in case they don't ever give us anything back */
12451 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
12452 sched, 15000, auto_hangup, (void *)(long)callno);
12454 /* Got a call number now, so go ahead and send the provisioning information */
12455 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
12456 }
12457 ast_mutex_unlock(&iaxsl[callno]);
12458
12459 return 1;
12460}
#define IAX_PROVISION
Definition: chan_iax2.c:532
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 8892 of file chan_iax2.c.

8893{
8894 ast_system_publish_registry("IAX2", username, domain, status, cause);
8895}
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 5556 of file chan_iax2.c.

5557{
5558 switch (option) {
5561 {
5562 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5563 ast_mutex_lock(&iaxsl[callno]);
5564 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
5565 ast_mutex_unlock(&iaxsl[callno]);
5566 return 0;
5567 }
5568 default:
5569 return -1;
5570 }
5571}
#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 3326 of file chan_iax2.c.

3327{
3328 iax2_lock_owner(callno);
3329 if (iaxs[callno] && iaxs[callno]->owner) {
3330 ast_queue_frame(iaxs[callno]->owner, f);
3331 ast_channel_unlock(iaxs[callno]->owner);
3332 }
3333 return 0;
3334}
static void iax2_lock_owner(int callno)
Definition: chan_iax2.c:1406
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:1169

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

3396{
3397 iax2_lock_owner(callno);
3398 if (iaxs[callno] && iaxs[callno]->owner) {
3399 ast_queue_hangup(iaxs[callno]->owner);
3400 ast_channel_unlock(iaxs[callno]->owner);
3401 }
3402 return 0;
3403}

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

3350{
3351 iax2_lock_owner(callno);
3352 if (iaxs[callno] && iaxs[callno]->owner) {
3353 ast_queue_hold(iaxs[callno]->owner, musicclass);
3354 ast_channel_unlock(iaxs[callno]->owner);
3355 }
3356 return 0;
3357}
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition: channel.c:1229

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

3373{
3374 iax2_lock_owner(callno);
3375 if (iaxs[callno] && iaxs[callno]->owner) {
3376 ast_queue_unhold(iaxs[callno]->owner);
3377 ast_channel_unlock(iaxs[callno]->owner);
3378 }
3379 return 0;
3380}
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1254

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

5574{
5575 ast_debug(1, "I should never be called!\n");
5576 return &ast_null_frame;
5577}
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 9006 of file chan_iax2.c.

9007{
9008 char copy[256];
9009 char *username, *hostname, *secret;
9010 char *porta;
9011 char *stringp=NULL;
9012
9013 if (!value)
9014 return -1;
9015
9016 ast_copy_string(copy, value, sizeof(copy));
9017 stringp = copy;
9018 username = strsep(&stringp, "@");
9019 hostname = strsep(&stringp, "@");
9020
9021 if (!hostname) {
9022 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
9023 return -1;
9024 }
9025
9026 stringp = username;
9027 username = strsep(&stringp, ":");
9028 secret = strsep(&stringp, ":");
9029 stringp = hostname;
9030 hostname = strsep(&stringp, ":");
9031 porta = strsep(&stringp, ":");
9032
9033 if (porta && !atoi(porta)) {
9034 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
9035 return -1;
9036 }
9037
9038 return iax2_append_register(hostname, username, secret, porta);
9039}
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:8964

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

12677{
12678 int callno;
12679 int res;
12680 struct ast_sockaddr addr;
12681 struct ast_channel *c;
12682 struct parsed_dial_string pds;
12683 struct create_addr_info cai;
12684 char *tmpstr;
12685 ast_callid callid;
12686
12687 memset(&pds, 0, sizeof(pds));
12688 tmpstr = ast_strdupa(data);
12689 parse_dial_string(tmpstr, &pds);
12690
12692
12693 if (ast_strlen_zero(pds.peer)) {
12694 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
12695 return NULL;
12696 }
12697 memset(&cai, 0, sizeof(cai));
12698 cai.capability = iax2_capability;
12699
12701
12702 /* Populate our address from the given */
12703 if (create_addr(pds.peer, NULL, &addr, &cai)) {
12704 *cause = AST_CAUSE_UNREGISTERED;
12705 return NULL;
12706 }
12707
12708 if (pds.port) {
12709 int bindport;
12710 ast_parse_arg(pds.port, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535);
12711 ast_sockaddr_set_port(&addr, bindport);
12712 }
12713
12714 callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
12715 if (callno < 1) {
12716 ast_log(LOG_WARNING, "Unable to create call\n");
12717 *cause = AST_CAUSE_CONGESTION;
12718 return NULL;
12719 }
12720
12721 /* If this is a trunk, update it now */
12723 if (ast_test_flag64(&cai, IAX_TRUNK)) {
12724 int new_callno;
12725 if ((new_callno = make_trunk(callno, 1)) != -1)
12726 callno = new_callno;
12727 }
12728 iaxs[callno]->maxtime = cai.maxtime;
12729 if (callid) {
12730 iax_pvt_callid_set(callno, callid);
12731 }
12732
12733 if (cai.found) {
12734 ast_string_field_set(iaxs[callno], host, pds.peer);
12735 }
12736
12737 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, &cai.prefs, assignedids,
12738 requestor, cai.found);
12739
12740 ast_mutex_unlock(&iaxsl[callno]);
12741
12742 if (c) {
12743 struct ast_format_cap *joint;
12744 struct ast_format *format;
12745 if (callid) {
12747 ast_channel_callid_set(c, callid);
12749 }
12750
12752 if (!joint) {
12753 ast_hangup(c);
12754 return NULL;
12755 }
12756
12758
12759 /* If there is no joint format find one through translation */
12760 if (!ast_format_cap_count(joint)) {
12761 struct ast_format *best_fmt_cap = NULL;
12762 struct ast_format *best_fmt_native = NULL;
12763
12764 res = ast_translator_best_choice(cap, ast_channel_nativeformats(c), &best_fmt_cap, &best_fmt_native);
12765 if (res < 0) {
12766 struct ast_str *native_cap_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
12768
12769 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12771 ast_format_cap_get_names(cap, &cap_buf),
12773 ast_hangup(c);
12774 ao2_ref(joint, -1);
12775 return NULL;
12776 }
12777 ast_format_cap_append(joint, best_fmt_native, 0);
12778 ao2_ref(best_fmt_cap, -1);
12779 ao2_ref(best_fmt_native, -1);
12780 }
12785
12786 ao2_ref(joint, -1);
12787 ao2_ref(format, -1);
12788 }
12789
12790 return c;
12791}
#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:5946
static void iax_pvt_callid_set(int callno, ast_callid callid)
Definition: chan_iax2.c:1205
static int make_trunk(unsigned short callno, int locked)
Definition: chan_iax2.c:2406
#define ast_channel_lock(chan)
Definition: channel.h:2972
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:2273
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

Definition at line 1759 of file chan_iax2.c.

1761{
1762 return ast_sched_add(con, when, callback, data);
1763}
static struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)

References ast_sched_add(), and callback().

Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), iax2_call(), iax2_destroy_helper(), iax2_poke_peer(), make_trunk(), network_change_stasis_cb(), realtime_peer(), reg_source_db(), sched_delay_remove(), socket_process_helper(), transmit_frame(), and update_registry().

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

1755{
1756 return ast_sched_replace(id, con, when, callback, data);
1757}
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(), and callback().

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

6684{
6685 /* Queue a packet for delivery on a given private structure. Use "ts" for
6686 timestamp, or calculate if ts is 0. Send immediately without retransmission
6687 or delayed, with retransmission */
6688 struct ast_iax2_full_hdr *fh;
6689 struct ast_iax2_mini_hdr *mh;
6690 struct ast_iax2_video_hdr *vh;
6691 struct {
6692 struct iax_frame fr2;
6693 unsigned char buffer[4096];
6694 } frb;
6695 struct iax_frame *fr;
6696 int res;
6697 int sendmini=0;
6698 unsigned int lastsent;
6699 unsigned int fts;
6700
6701 frb.fr2.afdatalen = sizeof(frb.buffer);
6702
6703 if (!pvt) {
6704 ast_log(LOG_WARNING, "No private structure for packet?\n");
6705 return -1;
6706 }
6707
6708 lastsent = pvt->lastsent;
6709
6710 /* Calculate actual timestamp */
6711 fts = calc_timestamp(pvt, ts, f);
6712
6713 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
6714 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we
6715 * increment the "predicted timestamps" for voice, if we're predicting */
6716 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
6717 return 0;
6718#if 0
6720 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
6721 *("=!" + (f->frametype == AST_FRAME_VOICE)),
6722 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
6723 pvt->keyrotateid != -1 ? "" : "no "
6724 );
6725#endif
6726 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
6727 iax2_key_rotate(pvt);
6728 }
6729
6730 if ((ast_test_flag64(pvt, IAX_TRUNK) ||
6731 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
6732 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
6733 /* High two bytes are the same on timestamp, or sending on a trunk */ &&
6735 /* is a voice frame */ &&
6738 /* is the same type */ ) {
6739 /* Force immediate rather than delayed transmission */
6740 now = 1;
6741 /* Mark that mini-style frame is appropriate */
6742 sendmini = 1;
6743 }
6744 if ( f->frametype == AST_FRAME_VIDEO ) {
6745 /*
6746 * If the lower 15 bits of the timestamp roll over, or if
6747 * the video format changed then send a full frame.
6748 * Otherwise send a mini video frame
6749 */
6750 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
6753 ) {
6754 now = 1;
6755 sendmini = 1;
6756 } else {
6757 now = 0;
6758 sendmini = 0;
6759 }
6760 pvt->lastvsent = fts;
6761 }
6762 if (f->frametype == AST_FRAME_IAX) {
6763 /* 0x8000 marks this message as TX:, this bit will be stripped later */
6765 if (!pvt->first_iax_message) {
6767 }
6768 }
6769 /* Allocate an iax_frame */
6770 if (now) {
6771 fr = &frb.fr2;
6772 } else
6774 if (!fr) {
6775 ast_log(LOG_WARNING, "Out of memory\n");
6776 return -1;
6777 }
6778 /* Copy our prospective frame into our immediate or retransmitted wrapper */
6779 iax_frame_wrap(fr, f);
6780
6781 fr->ts = fts;
6782 fr->callno = pvt->callno;
6783 fr->transfer = transfer;
6784 fr->final = final;
6785 fr->encmethods = 0;
6786 if (!sendmini) {
6787 /* We need a full frame */
6788 if (seqno > -1)
6789 fr->oseqno = seqno;
6790 else
6791 fr->oseqno = pvt->oseqno++;
6792 fr->iseqno = pvt->iseqno;
6793 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
6794 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
6795 fh->ts = htonl(fr->ts);
6796 fh->oseqno = fr->oseqno;
6797 if (transfer) {
6798 fh->iseqno = 0;
6799 } else
6800 fh->iseqno = fr->iseqno;
6801 /* Keep track of the last thing we've acknowledged */
6802 if (!transfer)
6803 pvt->aseqno = fr->iseqno;
6804 fh->type = fr->af.frametype & 0xFF;
6805
6806 if (fr->af.frametype == AST_FRAME_VIDEO) {
6808 tmpfmt |= fr->af.subclass.frame_ending ? 0x1LL : 0;
6809 fh->csub = compress_subclass(tmpfmt | ((tmpfmt & 0x1LL) << 6));
6810 } else if (fr->af.frametype == AST_FRAME_VOICE) {
6812 } else {
6814 }
6815
6816 if (transfer) {
6817 fr->dcallno = pvt->transfercallno;
6818 } else
6819 fr->dcallno = pvt->peercallno;
6820 fh->dcallno = htons(fr->dcallno);
6821 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
6822 fr->data = fh;
6823 fr->retries = 0;
6824 /* Retry after 2x the ping time has passed */
6825 fr->retrytime = pvt->pingtime * 2;
6826 if (fr->retrytime < MIN_RETRY_TIME)
6828 if (fr->retrytime > MAX_RETRY_TIME)
6830 /* Acks' don't get retried */
6832 fr->retries = -1;
6833 else if (f->frametype == AST_FRAME_VOICE)
6835 else if (f->frametype == AST_FRAME_VIDEO)
6837 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
6839 if (fr->transfer)
6840 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
6841 else
6842 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
6843 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
6844 fr->encmethods = pvt->encmethods;
6845 fr->ecx = pvt->ecx;
6846 fr->mydcx = pvt->mydcx;
6847 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
6848 } else
6849 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
6850 }
6851
6852 if (now) {
6853 res = send_packet(fr);
6854 } else
6855 res = iax2_transmit(fr);
6856 } else {
6857 if (ast_test_flag64(pvt, IAX_TRUNK)) {
6858 iax2_trunk_queue(pvt, fr);
6859 res = 0;
6860 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
6861 /* Video frame have no sequence number */
6862 fr->oseqno = -1;
6863 fr->iseqno = -1;
6864 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
6865 vh->zeros = 0;
6866 vh->callno = htons(0x8000 | fr->callno);
6867 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.frame_ending ? 0x8000 : 0));
6868 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
6869 fr->data = vh;
6870 fr->retries = -1;
6871 res = send_packet(fr);
6872 } else {
6873 /* Mini-frames have no sequence number */
6874 fr->oseqno = -1;
6875 fr->iseqno = -1;
6876 /* Mini frame will do */
6877 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
6878 mh->callno = htons(fr->callno);
6879 mh->ts = htons(fr->ts & 0xFFFF);
6880 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
6881 fr->data = mh;
6882 fr->retries = -1;
6883 if (pvt->transferring == TRANSFER_MEDIAPASS)
6884 fr->transfer = 1;
6885 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
6887 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
6888 } else
6889 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
6890 }
6891 res = send_packet(fr);
6892 }
6893 }
6894 return res;
6895}
static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
Definition: chan_iax2.c:6400
static unsigned char compress_subclass(iax2_format subclass)
Definition: chan_iax2.c:1886
static int iax2_transmit(struct iax_frame *fr)
Definition: chan_iax2.c:4407
static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
Definition: chan_iax2.c:6616
#define MIN_RETRY_TIME
Definition: chan_iax2.c:728
static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
Definition: chan_iax2.c:6189
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:1252
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:1229
void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
Definition: parser.c:1196
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:786
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 4436 of file chan_iax2.c.

4437{
4438 return send_command_locked(PTR_TO_CALLNO(ast_channel_tech_pvt(c)), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
4439}
@ 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 4424 of file chan_iax2.c.

4425{
4426
4428 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
4429}
char * text
Definition: app_queue.c:1809
@ 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 5484 of file chan_iax2.c.

5485{
5486 struct ast_option_header *h;
5487 int res;
5488
5489 switch (option) {
5490 case AST_OPTION_TXGAIN:
5491 case AST_OPTION_RXGAIN:
5492 /* these two cannot be sent, because they require a result */
5493 errno = ENOSYS;
5494 return -1;
5495 case AST_OPTION_OPRMODE:
5496 errno = EINVAL;
5497 return -1;
5500 {
5501 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5502 ast_mutex_lock(&iaxsl[callno]);
5503 if ((*(int *) data)) {
5505 } else {
5507 }
5508 ast_mutex_unlock(&iaxsl[callno]);
5509 return 0;
5510 }
5511 /* These options are sent to the other side across the network where
5512 * they will be passed to whatever channel is bridged there. Don't
5513 * do anything silly like pass an option that transmits pointers to
5514 * memory on this machine to a remote machine to use */
5516 case AST_OPTION_TDD:
5521 {
5522 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5523 struct chan_iax2_pvt *pvt;
5524
5526 pvt = iaxs[callno];
5527
5528 if (wait_for_peercallno(pvt)) {
5530 return -1;
5531 }
5532
5534
5535 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
5536 return -1;
5537 }
5538
5539 h->flag = AST_OPTION_FLAG_REQUEST;
5540 h->option = htons(option);
5541 memcpy(h->data, data, datalen);
5543 AST_CONTROL_OPTION, 0, (unsigned char *) h,
5544 datalen + sizeof(*h), -1);
5545 ast_free(h);
5546 return res;
5547 }
5548 default:
5549 return -1;
5550 }
5551
5552 /* Just in case someone does a break instead of a return */
5553 return -1;
5554}
#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 5904 of file chan_iax2.c.

5905{
5906 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5907 struct iax_ie_data ied = { "", };
5908 char tmp[256], *context;
5910 ast_copy_string(tmp, dest, sizeof(tmp));
5911 context = strchr(tmp, '@');
5912 if (context) {
5913 *context = '\0';
5914 context++;
5915 }
5917 if (context)
5919 ast_debug(1, "Transferring '%s' to '%s'\n", ast_channel_name(c), dest);
5921 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
5922}
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:1276
@ 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, and send_command_locked().

◆ iax2_transmit()

static int iax2_transmit ( struct iax_frame fr)
static

Definition at line 4407 of file chan_iax2.c.

4408{
4409 fr->sentyet = 0;
4410
4412}
static int transmit_frame(void *data)
Definition: chan_iax2.c:4380
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 9634 of file chan_iax2.c.

9635{
9636 /* Drop when trunk is about 5 seconds idle */
9637 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
9638 return 1;
9639 return 0;
9640}

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

6401{
6402 struct ast_frame *f;
6403 struct iax2_trunk_peer *tpeer;
6404 void *tmp, *ptr;
6405 struct timeval now;
6406 struct ast_iax2_meta_trunk_entry *met;
6407 struct ast_iax2_meta_trunk_mini *mtm;
6408
6409 f = &fr->af;
6410 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
6411 if (tpeer) {
6412
6413 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
6414 /* Need to reallocate space */
6415 if (tpeer->trunkdataalloc < trunkmaxsize) {
6416 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
6417 ast_mutex_unlock(&tpeer->lock);
6418 return -1;
6419 }
6420
6422 tpeer->trunkdata = tmp;
6423 ast_debug(1, "Expanded trunk '%s' to %u bytes\n", ast_sockaddr_stringify(&tpeer->addr), tpeer->trunkdataalloc);
6424 } else {
6425 ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s\n", ast_sockaddr_stringify(&tpeer->addr));
6426 ast_mutex_unlock(&tpeer->lock);
6427 return -1;
6428 }
6429 }
6430
6431 /* Append to meta frame */
6432 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
6434 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
6435 mtm->len = htons(f->datalen);
6436 mtm->mini.callno = htons(pvt->callno);
6437 mtm->mini.ts = htons(0xffff & fr->ts);
6438 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
6439 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
6440 } else {
6441 met = (struct ast_iax2_meta_trunk_entry *)ptr;
6442 /* Store call number and length in meta header */
6443 met->callno = htons(pvt->callno);
6444 met->len = htons(f->datalen);
6445 /* Advance pointers/decrease length past trunk entry header */
6446 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
6447 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
6448 }
6449 /* Copy actual trunk data */
6450 memcpy(ptr, f->data.ptr, f->datalen);
6451 tpeer->trunkdatalen += f->datalen;
6452
6453 tpeer->calls++;
6454
6455 /* track the largest mtu we actually have sent */
6456 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
6457 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
6458
6459 /* if we have enough for a full MTU, ship it now without waiting */
6460 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
6461 now = ast_tvnow();
6462 send_trunk(tpeer, &now);
6463 trunk_untimed ++;
6464 }
6465
6466 ast_mutex_unlock(&tpeer->lock);
6467 }
6468 return 0;
6469}
#define ast_realloc(p, len)
A wrapper for realloc()
Definition: astmm.h:226
#define IAX_TRUNKTIMESTAMPS
Definition: chan_iax2.c:543
static struct iax2_trunk_peer * find_tpeer(struct ast_sockaddr *addr, int fd)
Definition: chan_iax2.c:6364
static int trunkmaxsize
Definition: chan_iax2.c:367
#define IAX2_TRUNK_PREFACE
Definition: chan_iax2.c:662
#define DEFAULT_TRUNKDATA
Definition: chan_iax2.c:734
static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
Definition: chan_iax2.c:9591
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:676
unsigned int trunkdatalen
Definition: chan_iax2.c:675
unsigned char * trunkdata
Definition: chan_iax2.c:674

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

9556{
9557 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
9558}
static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
Definition: chan_iax2.c:7906
@ 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 7823 of file chan_iax2.c.

7824{
7825 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
7826 int res = -1;
7827 ast_mutex_lock(&iaxsl[callno]);
7828 if (iaxs[callno]) {
7829 /* If there's an outstanding error, return failure now */
7830 if (!iaxs[callno]->error) {
7831 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
7832 res = 0;
7833 /* Don't waste bandwidth sending null frames */
7834 else if (f->frametype == AST_FRAME_NULL)
7835 res = 0;
7836 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
7837 res = 0;
7838 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
7839 res = 0;
7840 else
7841 /* Simple, just queue for transmission */
7842 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
7843 } else {
7844 ast_debug(1, "Write error: %s\n", strerror(errno));
7845 }
7846 }
7847 /* If it's already gone, just return */
7848 ast_mutex_unlock(&iaxsl[callno]);
7849 return res;
7850}
#define IAX_QUELCH
Definition: chan_iax2.c:533
@ 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 1270 of file chan_iax2.c.

1271{
1272 if (iaxdebug)
1273 ast_verbose("%s", data);
1274}
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 1276 of file chan_iax2.c.

1277{
1278 ast_log(LOG_WARNING, "%s", data);
1279}

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

1253{
1254 if (iaxdebug ||
1255 (addr && !ast_sockaddr_isnull(&debugaddr) &&
1258 !ast_sockaddr_cmp_addr(&debugaddr, addr))) {
1259
1260 if (iaxdebug) {
1261 iax_showframe(f, fhi, rx, addr, datalen);
1262 } else {
1263 iaxdebug = 1;
1264 iax_showframe(f, fhi, rx, addr, datalen);
1265 iaxdebug = 0;
1266 }
1267 }
1268}
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 1200 of file chan_iax2.c.

1201{
1202 return iaxs[callno]->callid;
1203}
ast_callid callid
Definition: chan_iax2.c:770

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

1211{
1212 ast_callid callid = ast_create_callid();
1213 char buffer[AST_CALLID_BUFFER_LENGTH];
1214 ast_callid_strnprint(buffer, sizeof(buffer), callid);
1215 iax_pvt_callid_set(callno, callid);
1216}
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:2263
#define AST_CALLID_BUFFER_LENGTH
ast_callid ast_create_callid(void)
factory function to create a new uniquely identifying callid.
Definition: logger.c:2268

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

1206{
1207 iaxs[callno]->callid = callid;
1208}

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

2360{
2362 if (new) {
2363 size_t afdatalen = new->afdatalen;
2364 memcpy(new, fr, sizeof(*new));
2365 iax_frame_wrap(new, &fr->af);
2366 new->afdatalen = afdatalen;
2367 new->data = NULL;
2368 new->datalen = 0;
2369 new->direction = DIRECTION_INGRESS;
2370 new->retrans = -1;
2371 }
2372 return new;
2373}
#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 1643 of file chan_iax2.c.

1644{
1645 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
1649 } else {
1653 }
1654
1655 return;
1656}

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

6484{
6485#ifdef HAVE_OPENSSL
6486 int i;
6487 for (i = 0; i < 60; i++) {
6488 if (ecx->raw[i]) {
6489 return 0; /* stop if we encounter anything non-zero */
6490 }
6491 }
6492 /* if ast_aes_encrypt or ast_aes_decrypt is called, then we'll crash when calling AES_encrypt or AES_decrypt */
6493 return -1;
6494#else
6495 return 0; /* Can't verify, but doesn't matter anyways */
6496#endif
6497}
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 1305 of file chan_iax2.c.

1306{
1307 va_list args;
1308 char buf[1024];
1309
1310 va_start(args, fmt);
1311 vsnprintf(buf, sizeof(buf), fmt, args);
1312 va_end(args);
1313
1314 ast_verbose("%s", buf);
1315}

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

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

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

1294{
1295 va_list args;
1296 char buf[1024];
1297
1298 va_start(args, fmt);
1299 vsnprintf(buf, sizeof(buf), fmt, args);
1300 va_end(args);
1301
1302 ast_log(LOG_WARNING, "%s", buf);
1303}

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

15041{
15042 static const char config[] = "iax.conf";
15043 int x = 0;
15044 struct iax2_registry *reg = NULL;
15045
15048 }
15050
15051 if (load_objects()) {
15055 }
15056
15057 memset(iaxs, 0, sizeof(iaxs));
15058
15059 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
15060 ast_mutex_init(&iaxsl[x]);
15061 }
15062
15063 if (!(sched = ast_sched_context_create())) {
15064 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
15068 }
15069
15074 sched = NULL;
15076 }
15077
15078 if (!(io = io_context_create())) {
15079 ast_log(LOG_ERROR, "Failed to create I/O context\n");
15083 sched = NULL;
15085 }
15086
15087 if (!(netsock = ast_netsock_list_alloc())) {
15088 ast_log(LOG_ERROR, "Failed to create netsock list\n");
15093 sched = NULL;
15095 }
15097
15099 if (!outsock) {
15100 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
15105 sched = NULL;
15107 }
15109
15111
15115
15116 if ((timer = ast_timer_open())) {
15118 }
15119
15120 if (set_config(config, 0, 0) == -1) {
15121 if (timer) {
15123 timer = NULL;
15124 }
15127 }
15128
15130
15132
15135
15140
15142 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
15145 }
15146
15148 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
15149 }
15150
15151 if (start_network_thread()) {
15152 ast_log(LOG_ERROR, "Unable to start network thread\n");
15155 } else {
15156 ast_verb(2, "IAX Ready and Listening\n");
15157 }
15158
15161 iax2_do_register(reg);
15163
15166
15167
15170
15171 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
15172
15174
15176}
static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
callback to display iax peers in manager
Definition: chan_iax2.c:7385
static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:12576
static void iax_error_output(const char *data)
Definition: chan_iax2.c:1276
static struct ast_custom_function iaxvar_function
Definition: chan_iax2.c:10238
static int __unload_module(void)
Definition: chan_iax2.c:14813
static struct ast_custom_function iaxpeer_function
Definition: chan_iax2.c:14674
static int load_objects(void)
Definition: chan_iax2.c:14947
static void iax_debug_output(const char *data)
Definition: chan_iax2.c:1270
static int set_config(const char *config_file, int reload, int forced)
Load configuration.
Definition: chan_iax2.c:13696
static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
Definition: chan_iax2.c:7338
static void network_change_stasis_subscribe(void)
Definition: chan_iax2.c:1527
static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
Definition: chan_iax2.c:7509
static int trunkfreq
Definition: chan_iax2.c:366
static struct io_context * io
Definition: chan_iax2.c:480
static int peer_set_sock_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:14901
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:7407
static int start_network_thread(void)
Definition: chan_iax2.c:12818
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:538
#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:12467
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
Definition: main/config.c:3769
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:192
@ 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:640
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:1559
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, iax2_registry::entry, 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 14947 of file chan_iax2.c.

14948{
14951
14954 if (!peers) {
14955 goto container_fail;
14956 }
14957
14960 if (!users) {
14961 goto container_fail;
14962 }
14963
14966 if (!iax_peercallno_pvts) {
14967 goto container_fail;
14968 }
14969
14973 goto container_fail;
14974 }
14975
14978 if (!peercnts) {
14979 goto container_fail;
14980 }
14981
14984 if (!callno_limits) {
14985 goto container_fail;
14986 }
14987
14990 if (!calltoken_ignores) {
14991 goto container_fail;
14992 }
14993
14994 if (create_callno_pools()) {
14995 goto container_fail;
14996 }
14997
14999 if (!transmit_processor) {
15000 goto container_fail;
15001 }
15002
15003 return 0;
15004
15005container_fail:
15006 if (peers) {
15007 ao2_ref(peers, -1);
15008 }
15009 if (users) {
15010 ao2_ref(users, -1);
15011 }
15012 if (iax_peercallno_pvts) {
15014 }
15017 }
15018 if (peercnts) {
15019 ao2_ref(peercnts, -1);
15020 }
15021 if (callno_limits) {
15023 }
15024 if (calltoken_ignores) {
15026 }
15027 return -1;
15028}
@ 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:1027
static int peer_hash_cb(const void *obj, const int flags)
Definition: chan_iax2.c:2035
static int peercnt_hash_cb(const void *obj, const int flags)
Definition: chan_iax2.c:2532
static int peer_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:2046
static int addr_range_hash_cb(const void *obj, const int flags)
Definition: chan_iax2.c:2518
static int pvt_hash_cb(const void *obj, const int flags)
Definition: chan_iax2.c:14911
static int user_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:2069
static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:14936
static int pvt_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:14918
static int create_callno_pools(void)
Definition: chan_iax2.c:3094
static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
Definition: chan_iax2.c:14929
static int user_hash_cb(const void *obj, const int flags)
Definition: chan_iax2.c:2058
static int addr_range_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:2524
#define MAX_PEER_BUCKETS
Definition: chan_iax2.c:1023
static int peercnt_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:2542
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 9851 of file chan_iax2.c.

9852{
9853 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
9854 jb_info jbinfo;
9855
9856 ast_mutex_lock(&iaxsl[callno]);
9857 if (iaxs[callno] && iaxs[callno]->owner && ast_channel_name(iaxs[callno]->owner)) {
9858 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
9859 jb_getinfo(iaxs[callno]->jb, &jbinfo);
9860 localjitter = jbinfo.jitter;
9861 localdelay = jbinfo.current - jbinfo.min;
9862 locallost = jbinfo.frames_lost;
9863 locallosspct = jbinfo.losspct/1000;
9864 localdropped = jbinfo.frames_dropped;
9865 localooo = jbinfo.frames_ooo;
9866 localpackets = jbinfo.frames_in;
9867 }
9868 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",
9869 ast_channel_name(iaxs[callno]->owner),
9870 iaxs[callno]->pingtime,
9871 localjitter,
9872 localdelay,
9873 locallost,
9874 locallosspct,
9875 localdropped,
9876 localooo,
9877 localpackets,
9878 iaxs[callno]->remote_rr.jitter,
9879 iaxs[callno]->remote_rr.delay,
9880 iaxs[callno]->remote_rr.losscnt,
9881 iaxs[callno]->remote_rr.losspct/1000,
9882 iaxs[callno]->remote_rr.dropped,
9883 iaxs[callno]->remote_rr.ooo,
9884 iaxs[callno]->remote_rr.packets);
9885 }
9886 ast_mutex_unlock(&iaxsl[callno]);
9887}

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

2407{
2408 int x;
2409 int res= 0;
2410 callno_entry entry;
2411 if (iaxs[callno]->oseqno) {
2412 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
2413 return -1;
2414 }
2415 if (callno >= TRUNK_CALL_START) {
2416 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
2417 return -1;
2418 }
2419
2423 &entry)) {
2424 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
2425 return -1;
2426 }
2427
2428 x = CALLNO_ENTRY_GET_CALLNO(entry);
2429 ast_mutex_lock(&iaxsl[x]);
2430
2431 /*!
2432 * \note We delete these before switching the slot, because if
2433 * they fire in the meantime, they will generate a warning.
2434 */
2435 AST_SCHED_DEL(sched, iaxs[callno]->pingid);
2436 AST_SCHED_DEL(sched, iaxs[callno]->lagid);
2437 iaxs[callno]->lagid = iaxs[callno]->pingid = -1;
2438 iaxs[x] = iaxs[callno];
2439 iaxs[x]->callno = x;
2440
2441 /* since we copied over the pvt from a different callno, make sure the old entry is replaced
2442 * before assigning the new one */
2443 if (iaxs[x]->callno_entry) {
2445 sched,
2446 MIN_REUSE_TIME * 1000,
2449
2450 }
2451 iaxs[x]->callno_entry = entry;
2452
2453 iaxs[callno] = NULL;
2454 /* Update the two timers that should have been started */
2456 ping_time * 1000, send_ping, (void *)(long)x);
2458 lagrq_time * 1000, send_lagrq, (void *)(long)x);
2459
2460 if (locked)
2461 ast_mutex_unlock(&iaxsl[callno]);
2462 res = x;
2463 if (!locked)
2465
2466 /* We moved this call from a non-trunked to a trunked call */
2467 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
2468
2469 return res;
2470}
#define CALLNO_ENTRY_IS_VALIDATED(a)
Definition: chan_iax2.c:979
#define MIN_REUSE_TIME
Definition: chan_iax2.c:327

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

7339{
7340 ast_cli_netstats(s, -1, 0);
7341 astman_append(s, "\r\n");
7342 return RESULT_SUCCESS;
7343}

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

7408{
7409 struct show_peers_context cont = {
7410 .havepattern = 0,
7411 .idtext = "",
7412 .registeredonly = 0,
7413
7414 .peerlist = 1,
7415
7416 .total_peers = 0,
7417 .online_peers = 0,
7418 .offline_peers = 0,
7419 .unmonitored_peers = 0,
7420 };
7421
7422 struct iax2_peer *peer = NULL;
7423 struct ao2_iterator i;
7424
7425 const char *id = astman_get_header(m,"ActionID");
7426
7427 if (!ast_strlen_zero(id)) {
7428 snprintf(cont.idtext, sizeof(cont.idtext), "ActionID: %s\r\n", id);
7429 }
7430
7431 astman_send_listack(s, m, "IAX Peer status list will follow", "start");
7432
7433 i = ao2_iterator_init(peers, 0);
7434 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
7435 _iax2_show_peers_one(-1, s, &cont, peer);
7436 }
7438
7439 astman_send_list_complete_start(s, m, "PeerlistComplete", cont.total_peers);
7441
7442 return RESULT_SUCCESS;
7443}
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:2028
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:2064
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:1647
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:2072

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

7386{
7387 static const char * const a[] = { "iax2", "show", "peers" };
7388 const char *id = astman_get_header(m,"ActionID");
7389 char idtext[256] = "";
7390 int total = 0;
7391
7392 if (!ast_strlen_zero(id))
7393 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
7394
7395 astman_send_listack(s, m, "Peer status list will follow", "start");
7396
7397 /* List the peers in separate manager events */
7398 __iax2_show_peers(-1, &total, s, 3, a);
7399
7400 /* Send final confirmation */
7401 astman_send_list_complete_start(s, m, "PeerlistComplete", total);
7403 return 0;
7404}

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

7510{
7511 const char *id = astman_get_header(m, "ActionID");
7512 struct iax2_registry *reg = NULL;
7513 char idtext[256] = "";
7514 char host[80] = "";
7515 char perceived[80] = "";
7516 int total = 0;
7517
7518 if (!ast_strlen_zero(id))
7519 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
7520
7521 astman_send_listack(s, m, "Registrations will follow", "start");
7522
7525 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
7526
7527 snprintf(perceived, sizeof(perceived), "%s", ast_sockaddr_isnull(&reg->us) ? "<Unregistered>" : ast_sockaddr_stringify(&reg->us));
7528
7529 astman_append(s,
7530 "Event: RegistryEntry\r\n"
7531 "%s"
7532 "Host: %s\r\n"
7533 "DNSmanager: %s\r\n"
7534 "Username: %s\r\n"
7535 "Perceived: %s\r\n"
7536 "Refresh: %d\r\n"
7537 "State: %s\r\n"
7538 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
7539 reg->refresh, regstate2str(reg->regstate));
7540
7541 total++;
7542 }
7544
7545 astman_send_list_complete_start(s, m, "RegistrationsComplete", total);
7547
7548 return 0;
7549}

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, iax2_registry::entry, 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 2388 of file chan_iax2.c.

2389{
2390 if (!ast_sockaddr_cmp(&cur->addr, addr)) {
2391 /* This is the main host */
2392 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
2393 (check_dcallno ? dcallno == cur->callno : 1) ) {
2394 /* That's us. Be sure we keep track of the peer call number */
2395 return 1;
2396 }
2397 }
2398 if (!ast_sockaddr_cmp(&cur->transfer, addr) && cur->transferring) {
2399 /* We're transferring */
2400 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
2401 return 1;
2402 }
2403 return 0;
2404}

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_retrieve(), 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(), filter_cmp_fn(), 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 6515 of file chan_iax2.c.

6516{
6517#if 0
6518 /* Debug with "fake encryption" */
6519 int x;
6520 if (len % 16)
6521 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
6522 for (x=0;x<len;x++)
6523 dst[x] = src[x] ^ 0xff;
6524#else
6525 unsigned char lastblock[16] = { 0 };
6526 int x;
6527 while(len > 0) {
6528 ast_aes_decrypt(src, dst, dcx);
6529 for (x=0;x<16;x++)
6530 dst[x] ^= lastblock[x];
6531 memcpy(lastblock, src, sizeof(lastblock));
6532 dst += 16;
6533 src += 16;
6534 len -= 16;
6535 }
6536#endif
6537}
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 6539 of file chan_iax2.c.

6540{
6541#if 0
6542 /* Debug with "fake encryption" */
6543 int x;
6544 if (len % 16)
6545 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
6546 for (x=0;x<len;x++)
6547 dst[x] = src[x] ^ 0xff;
6548#else
6549 unsigned char curblock[16] = { 0 };
6550 int x;
6551 while(len > 0) {
6552 for (x=0;x<16;x++)
6553 curblock[x] ^= src[x];
6554 ast_aes_encrypt(curblock, dst, ecx);
6555 memcpy(curblock, dst, sizeof(curblock));
6556 dst += 16;
6557 src += 16;
6558 len -= 16;
6559 }
6560#endif
6561}
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 8176 of file chan_iax2.c.

8177{
8178 /* Select exactly one common encryption if there are any */
8179 p->encmethods &= enc;
8180 if (p->encmethods) {
8181 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */
8182 p->keyrotateid = -2;
8183 }
8186 else
8187 p->encmethods = 0;
8188 }
8189}

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

1558{
1559 struct iax2_registry *reg;
1563 iax2_do_register(reg);
1564 }
1566
1567 return 0;
1568}
static int network_change_sched_id
Definition: chan_iax2.c:353

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_registry::entry, 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 1570 of file chan_iax2.c.

1572{
1573 /* This callback is only concerned with network change messages from the system topic. */
1575 return;
1576 }
1577
1578 ast_verb(1, "IAX, got a network change message, renewing all IAX registrations.\n");
1579 if (network_change_sched_id == -1) {
1581 }
1582}
static int network_change_sched_cb(const void *data)
Definition: chan_iax2.c:1557
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 1527 of file chan_iax2.c.

1528{
1529 if (!network_change_sub) {
1534 }
1535}
static void network_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: chan_iax2.c:1570
static struct stasis_subscription * network_change_sub
Definition: chan_iax2.c:351
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 12793 of file chan_iax2.c.

12794{
12795 int res;
12796
12797 if (timer) {
12799 }
12800
12801 for (;;) {
12802 pthread_testcancel();
12803 /* Wake up once a second just in case SIGURG was sent while
12804 * we weren't in poll(), to make sure we don't hang when trying
12805 * to unload. */
12806 res = ast_io_wait(io, 1000);
12807 /* Timeout(=0), and EINTR is not a thread exit condition. We do
12808 * not want to exit the thread loop on these conditions. */
12809 if (res < 0 && errno != -EINTR) {
12810 ast_log(LOG_ERROR, "IAX2 network thread unexpected exit: %s\n", strerror(errno));
12811 break;
12812 }
12813 }
12814
12815 return NULL;
12816}
static int timing_read(int *id, int fd, short events, void *cbdata)
Definition: chan_iax2.c:9642
#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 2316 of file chan_iax2.c.

2317{
2318 struct chan_iax2_pvt *tmp;
2319 jb_conf jbconf;
2320
2321 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
2322 return NULL;
2323 }
2324
2325 tmp->pingid = -1;
2326 tmp->lagid = -1;
2327 tmp->autoid = -1;
2328 tmp->authid = -1;
2329 tmp->initid = -1;
2330 tmp->keyrotateid = -1;
2331 tmp->jbid = -1;
2332
2333 if (ast_string_field_init(tmp, 32)) {
2334 ao2_ref(tmp, -1);
2335 tmp = NULL;
2336 return NULL;
2337 }
2338
2339 tmp->prefs = prefs_global;
2340
2341 ast_string_field_set(tmp,exten, "s");
2343
2344 tmp->jb = jb_new();
2349 jb_setconf(tmp->jb,&jbconf);
2350
2352
2353 tmp->hold_signaling = 1;
2355
2356 return tmp;
2357}
static int maxjitterbuffer
Definition: chan_iax2.c:359
static int maxjitterinterps
Definition: chan_iax2.c:361
static void pvt_destructor(void *obj)
Definition: chan_iax2.c:2269
static int resyncthreshold
Definition: chan_iax2.c:360
static int jittertargetextra
Definition: chan_iax2.c:362
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
struct chan_iax2_pvt::signaling_queue signaling_queue
struct chan_iax2_pvt::@122 dpentries
char hold_signaling
Definition: chan_iax2.c:960
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::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::dpentries, chan_iax2_pvt::exten, chan_iax2_pvt::hold_signaling, chan_iax2_pvt::host, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_new(), jb_setconf(), chan_iax2_pvt::jbid, jittertargetextra, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, maxjitterbuffer, maxjitterinterps, NULL, chan_iax2_pvt::pingid, chan_iax2_pvt::prefs, prefs_global, pvt_destructor(), jb_conf::resync_threshold, resyncthreshold, chan_iax2_pvt::signaling_queue, and jb_conf::target_extra.

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

5133{
5134 char *outkey = NULL;
5135
5136 if (ast_strlen_zero(data))
5137 return;
5138
5139 pds->peer = strsep(&data, "/");
5140 pds->exten = strsep(&data, "/");
5141 pds->options = data;
5142
5143 if (pds->exten) {
5144 data = pds->exten;
5145 pds->exten = strsep(&data, "@");
5146 pds->context = data;
5147 }
5148
5149 if (strchr(pds->peer, '@')) {
5150 data = pds->peer;
5151 pds->username = strsep(&data, "@");
5152 pds->peer = data;
5153 }
5154
5155 if (pds->username) {
5156 data = pds->username;
5157 pds->username = strsep(&data, ":");
5158 pds->password = strsep(&data, ":");
5159 outkey = data;
5160 }
5161
5162 data = pds->peer;
5163 pds->peer = strsep(&data, ":");
5164 pds->port = data;
5165
5166 /*
5167 * Check for a key name wrapped in [] in the password position.
5168 * If found, move it to the key field instead.
5169 * Also allow for both key and secret to be specified, now that
5170 * encryption is possible with RSA authentication.
5171 */
5172
5173 if (pds->password && (pds->password[0] == '[')) { /* key (then maybe secret) */
5174 pds->key = ast_strip_quoted(pds->password, "[", "]");
5175 if (ast_strlen_zero(outkey)) {
5176 pds->password = NULL;
5177 ast_debug(1, "Outkey (%s), no secret\n", pds->key);
5178 } else {
5179 pds->password = outkey;
5180 ast_debug(1, "Outkey (%s) and secret (%s)\n", pds->key, pds->password);
5181 }
5182 } else if (outkey && (outkey[0] == '[')) { /* secret, then key */
5183 pds->key = ast_strip_quoted(outkey, "[", "]");
5184 if (ast_strlen_zero(pds->password)) {
5185 ast_debug(1, "Outkey (%s), no secret\n", pds->key);
5186 } else {
5187 ast_debug(1, "Outkey (%s) and secret (%s)\n", pds->key, pds->password);
5188 }
5189 }
5190}
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 2046 of file chan_iax2.c.

2047{
2048 struct iax2_peer *peer = obj, *peer2 = arg;
2049 const char *name = arg;
2050
2051 return !strcmp(peer->name, flags & OBJ_KEY ? name : peer2->name) ?
2052 CMP_MATCH | CMP_STOP : 0;
2053}
uint64_t flags
Definition: chan_iax2.c:631

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

13602{
13603 struct iax2_peer *peer = obj;
13604
13606
13607 return 0;
13608}

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

◆ peer_destructor()

static void peer_destructor ( void *  obj)
static

Definition at line 12986 of file chan_iax2.c.

12987{
12988 struct iax2_peer *peer = obj;
12989 int callno = peer->callno;
12990
12991 ast_free_acl_list(peer->acl);
12992
12993 if (callno > 0) {
12997 }
12998
12999 register_peer_exten(peer, 0);
13000
13001 if (peer->dnsmgr)
13003
13004 if (peer->mwi_event_sub) {
13006 }
13007
13009
13011}
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 2035 of file chan_iax2.c.

2036{
2037 const struct iax2_peer *peer = obj;
2038 const char *name = obj;
2039
2040 return ast_str_hash(flags & OBJ_KEY ? name : peer->name);
2041}
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 14901 of file chan_iax2.c.

14902{
14903 struct iax2_peer *peer = obj;
14904
14905 if (peer->sockfd < 0)
14906 peer->sockfd = defaultsockfd;
14907
14908 return 0;
14909}

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

12917{
12918 struct ast_sockaddr addr;
12919 int nonlocal = 1;
12920 int port = IAX_DEFAULT_PORTNO;
12921 int sockfd = defaultsockfd;
12922 char *tmp;
12923 char *host;
12924 char *portstr;
12925
12926 tmp = ast_strdupa(srcaddr);
12927 ast_sockaddr_split_hostport(tmp, &host, &portstr, 0);
12928
12929 if (portstr) {
12930 port = atoi(portstr);
12931 if (port < 1)
12932 port = IAX_DEFAULT_PORTNO;
12933 }
12934
12935 addr.ss.ss_family = AST_AF_UNSPEC;
12936 if (!ast_get_ip(&addr, host)) {
12937 struct ast_netsock *sock;
12938
12939 if (check_srcaddr(&addr) == 0) {
12940 /* ip address valid. */
12941 ast_sockaddr_set_port(&addr, port);
12942
12943 if (!(sock = ast_netsock_find(netsock, &addr)))
12944 sock = ast_netsock_find(outsock, &addr);
12945 if (sock) {
12946 sockfd = ast_netsock_sockfd(sock);
12947 nonlocal = 0;
12948 } else {
12949 /* INADDR_ANY matches anyway! */
12950 ast_sockaddr_parse(&addr, "0.0.0.0", 0);
12951 ast_sockaddr_set_port(&addr, port);
12952 if (ast_netsock_find(netsock, &addr)) {
12953 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12954 if (sock) {
12955 sockfd = ast_netsock_sockfd(sock);
12956 ast_netsock_unref(sock);
12957 nonlocal = 0;
12958 } else {
12959 nonlocal = 2;
12960 }
12961 }
12962 }
12963 }
12964 }
12965
12966 peer->sockfd = sockfd;
12967
12968 if (nonlocal == 1) {
12970 "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12971 srcaddr,
12972 peer->name);
12973 return -1;
12974 } else if (nonlocal == 2) {
12976 "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12977 srcaddr,
12978 peer->name);
12979 return -1;
12980 } else {
12981 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12982 return 0;
12983 }
12984}
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:12893
static int socket_read(int *id, int fd, short events, void *cbdata)
Definition: chan_iax2.c:9955
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, and ast_sockaddr::ss.

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

3866{
3867 int res = 0;
3868 if (peer->maxms) {
3869 if (peer->lastms < 0) {
3870 ast_copy_string(status, "UNREACHABLE", statuslen);
3871 } else if (peer->lastms > peer->maxms) {
3872 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
3873 res = 1;
3874 } else if (peer->lastms) {
3875 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
3876 res = 1;
3877 } else {
3878 ast_copy_string(status, "UNKNOWN", statuslen);
3879 }
3880 } else {
3881 ast_copy_string(status, "Unmonitored", statuslen);
3882 res = -1;
3883 }
3884 return res;
3885}

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

2705{
2706 struct peercnt *peercnt;
2707 int res = 0;
2708 struct peercnt tmp;
2709
2710 ast_sockaddr_copy(&tmp.addr, addr);
2711
2712 /* Reasoning for peercnts container lock: Two identical ip addresses
2713 * could be added by different threads at the "same time". Without the container
2714 * lock, both threads could alloc space for the same object and attempt
2715 * to link to table. With the lock, one would create the object and link
2716 * to table while the other would find the already created peercnt object
2717 * rather than creating a new one. */
2719 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
2721 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
2723 /* create and set defaults */
2726 /* guarantees it does not go away after unlocking table
2727 * ao2_find automatically adds this */
2729 } else {
2731 return -1;
2732 }
2733
2734 /* check to see if the address has hit its callno limit. If not increment cur. */
2735 if (peercnt->limit > peercnt->cur) {
2736 peercnt->cur++;
2737 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_sockaddr_stringify_addr(addr));
2738 } else { /* max num call numbers for this peer has been reached! */
2739 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_sockaddr_stringify_addr(addr));
2740 res = -1;
2741 }
2742
2743 /* clean up locks and ref count */
2746 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */
2747
2748 return res;
2749}
static void set_peercnt_limit(struct peercnt *peercnt)
Definition: chan_iax2.c:2626

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

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

2543{
2544 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
2545 return !ast_sockaddr_cmp_addr(&peercnt1->addr, &peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
2546}

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

2533{
2534 const struct peercnt *peercnt = obj;
2535
2537 return 0;
2538 }
2539 return ast_sockaddr_hash(&peercnt->addr);
2540}

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

2677{
2678 /* this function turns off and on custom callno limits set by peer registration */
2679 struct peercnt *peercnt;
2680 struct peercnt tmp;
2681
2682 ast_sockaddr_copy(&tmp.addr, sockaddr);
2683
2684 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
2685 peercnt->reg = reg;
2686 if (limit) {
2687 peercnt->limit = limit;
2688 } else {
2690 }
2691 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_sockaddr_stringify_addr(sockaddr), peercnt->limit, peercnt->reg);
2692 ao2_ref(peercnt, -1); /* decrement ref from find */
2693 }
2694}
unsigned char reg
Definition: chan_iax2.c:1061

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

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

◆ peercnt_remove()

static void peercnt_remove ( struct peercnt peercnt)
static

Definition at line 2755 of file chan_iax2.c.

2756{
2757 struct ast_sockaddr addr;
2758
2759 ast_sockaddr_copy(&addr, &peercnt->addr);
2760
2761 /*
2762 * Container locked here since peercnt may be unlinked from
2763 * list. If left unlocked, peercnt_add could try and grab this
2764 * entry from the table and modify it at the "same time" this
2765 * thread attempts to unlink it.
2766 */
2768 peercnt->cur--;
2769 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_sockaddr_stringify_addr(&addr));
2770 /* if this was the last connection from the peer remove it from table */
2771 if (peercnt->cur == 0) {
2772 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */
2773 }
2775}

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

2796{
2797 struct peercnt *peercnt;
2798 struct peercnt tmp;
2799
2800 ast_sockaddr_copy(&tmp.addr, addr);
2801
2802 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
2804 ao2_ref(peercnt, -1); /* decrement ref from find */
2805 }
2806 return 0;
2807}
static void peercnt_remove(struct peercnt *peercnt)
Definition: chan_iax2.c:2755

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

Referenced by __find_callno(), and complete_transfer().

◆ peercnt_remove_cb()

static int peercnt_remove_cb ( const void *  obj)
static

Definition at line 2781 of file chan_iax2.c.

2782{
2783 struct peercnt *peercnt = (struct peercnt *) obj;
2784
2786 ao2_ref(peercnt, -1); /* decrement ref from scheduler */
2787
2788 return 0;
2789}

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

14219{
14220 struct ao2_iterator i;
14221 struct iax2_peer *peer;
14222
14223 i = ao2_iterator_init(peers, 0);
14224 while ((peer = ao2_iterator_next(&i))) {
14225 iax2_poke_peer(peer, 0);
14226 peer_unref(peer);
14227 }
14229}

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

2666{
2667 struct addr_range *addr_range = obj;
2668
2669 return addr_range->delme ? CMP_MATCH : 0;
2670}

References CMP_MATCH, and addr_range::delme.

Referenced by reload_config().

◆ prune_peers()

static void prune_peers ( void  )
static

Definition at line 13664 of file chan_iax2.c.

13665{
13666 struct iax2_peer *peer;
13667 struct ao2_iterator i;
13668
13669 i = ao2_iterator_init(peers, 0);
13670 while ((peer = ao2_iterator_next(&i))) {
13672 unlink_peer(peer);
13673 }
13674 peer_unref(peer);
13675 }
13677}

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

13649{
13650 struct iax2_user *user;
13651 struct ao2_iterator i;
13652
13653 i = ao2_iterator_init(users, 0);
13654 while ((user = ao2_iterator_next(&i))) {
13657 }
13659 }
13661}

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

14919{
14920 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14921
14922 /* The frames_received field is used to hold whether we're matching
14923 * against a full frame or not ... */
14924
14925 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14926 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14927}

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

2270{
2271 struct chan_iax2_pvt *pvt = obj;
2272 struct iax_frame *cur = NULL;
2273 struct signaling_queue_entry *s = NULL;
2274
2275 ast_mutex_lock(&iaxsl[pvt->callno]);
2276
2278
2280 pvt->callno_entry = 0;
2281
2282 /* Already gone */
2284
2285 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) {
2286 /* Cancel any pending transmissions */
2287 cur->retries = -1;
2288 }
2289
2291
2292 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
2294 }
2295
2296 if (pvt->reg) {
2297 pvt->reg->callno = 0;
2298 }
2299
2300 if (!pvt->owner) {
2301 jb_frame frame;
2302 if (pvt->vars) {
2304 pvt->vars = NULL;
2305 }
2306
2307 while (jb_getall(pvt->jb, &frame) == JB_OK) {
2308 iax2_frame_free(frame.data);
2309 }
2310
2311 jb_destroy(pvt->jb);
2313 }
2314}
static void free_signaling_queue_entry(struct signaling_queue_entry *s)
Definition: chan_iax2.c:2221
static void sched_delay_remove(struct ast_sockaddr *addr, callno_entry entry)
Definition: chan_iax2.c:3127
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
Definition: chan_iax2.c:965
struct signaling_queue_entry * next
Definition: chan_iax2.c:967

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

14912{
14913 const struct chan_iax2_pvt *pvt = obj;
14914
14915 return pvt->peercallno;
14916}

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

2245{
2246 struct signaling_queue_entry *qe;
2247
2248 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
2249 return 1; /* do not queue this frame */
2250 } else if (!(qe = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
2251 return -1; /* out of memory */
2252 }
2253
2254 /* copy ast_frame into our queue entry */
2255 qe->f = *f;
2256 if (qe->f.datalen) {
2257 /* if there is data in this frame copy it over as well */
2258 if (!(qe->f.data.ptr = ast_malloc(qe->f.datalen))) {
2260 return -1;
2261 }
2262 memcpy(qe->f.data.ptr, f->data.ptr, qe->f.datalen);
2263 }
2265
2266 return 0;
2267}

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

8161{
8162 struct ast_iax2_full_hdr fh;
8163 fh.scallno = htons(src | IAX_FLAG_FULL);
8164 fh.dcallno = htons(dst);
8165 fh.ts = 0;
8166 fh.oseqno = 0;
8167 fh.iseqno = 0;
8168 fh.type = AST_FRAME_IAX;
8170 iax_outputframe(NULL, &fh, 0, addr, 0);
8171
8172 ast_debug(1, "Raw Hangup %s, src=%d, dst=%d\n", ast_sockaddr_stringify(addr), src, dst);
8173 return ast_sendto(sockfd, &fh, sizeof(fh), 0, addr);
8174}
@ 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 4457 of file chan_iax2.c.

4458{
4459 struct ast_variable *var = NULL;
4460 struct ast_variable *tmp;
4461 struct iax2_peer *peer=NULL;
4462 time_t regseconds = 0, nowtime;
4463 int dynamic=0;
4464 char *str_addr, *str_port;
4465
4468
4469 if (peername) {
4470 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
4471 if (!var && !ast_sockaddr_isnull(addr)) {
4472 var = ast_load_realtime("iaxpeers", "name", peername, "host", str_addr, SENTINEL);
4473 }
4474 } else if (!ast_sockaddr_isnull(addr)) {
4475 var = ast_load_realtime("iaxpeers", "ipaddr", str_addr, "port", str_port, SENTINEL);
4476 if (var) {
4477 /* We'll need the peer name in order to build the structure! */
4478 for (tmp = var; tmp; tmp = tmp->next) {
4479 if (!strcasecmp(tmp->name, "name"))
4480 peername = tmp->value;
4481 }
4482 }
4483 }
4484 if (!var && peername) { /* Last ditch effort */
4485 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
4486 /*!\note
4487 * If this one loaded something, then we need to ensure that the host
4488 * field matched. The only reason why we can't have this as a criteria
4489 * is because we only have the IP address and the host field might be
4490 * set as a name (and the reverse PTR might not match).
4491 */
4492 if (var && !ast_sockaddr_isnull(addr)) {
4493 for (tmp = var; tmp; tmp = tmp->next) {
4494 if (!strcasecmp(tmp->name, "host")) {
4495 struct ast_sockaddr *hostaddr = NULL;
4496
4498 || ast_sockaddr_cmp_addr(hostaddr, addr)) {
4499 /* No match */
4501 var = NULL;
4502 }
4503 ast_free(hostaddr);
4504 break;
4505 }
4506 }
4507 }
4508 }
4509 if (!var)
4510 return NULL;
4511
4512 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
4513
4514 if (!peer) {
4516 return NULL;
4517 }
4518
4519 for (tmp = var; tmp; tmp = tmp->next) {
4520 /* Make sure it's not a user only... */
4521 if (!strcasecmp(tmp->name, "type")) {
4522 if (strcasecmp(tmp->value, "friend") &&
4523 strcasecmp(tmp->value, "peer")) {
4524 /* Whoops, we weren't supposed to exist! */
4525 peer = peer_unref(peer);
4526 break;
4527 }
4528 } else if (!strcasecmp(tmp->name, "regseconds")) {
4529 ast_get_time_t(tmp->value, &regseconds, 0, NULL);
4530 } else if (!strcasecmp(tmp->name, "ipaddr")) {
4531 int setport = ast_sockaddr_port(&peer->addr);
4533 ast_log(LOG_WARNING, "Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->value, tmp->name);
4534 } else {
4535 ast_sockaddr_parse(&peer->addr, tmp->value, 0);
4536 }
4537 ast_sockaddr_set_port(&peer->addr, setport);
4538 } else if (!strcasecmp(tmp->name, "port")) {
4539 int bindport;
4540 if (ast_parse_arg(tmp->value, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535)) {
4541 bindport = IAX_DEFAULT_PORTNO;
4542 }
4543 ast_sockaddr_set_port(&peer->addr, bindport);
4544 } else if (!strcasecmp(tmp->name, "host")) {
4545 if (!strcasecmp(tmp->value, "dynamic"))
4546 dynamic = 1;
4547 }
4548 }
4549
4551
4554 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
4555 if (peer->expire > -1) {
4556 if (!AST_SCHED_DEL(sched, peer->expire)) {
4557 peer->expire = -1;
4558 peer_unref(peer);
4559 }
4560 }
4562 if (peer->expire == -1)
4563 peer_unref(peer);
4564 }
4565 ao2_link(peers, peer);
4566 if (ast_test_flag64(peer, IAX_DYNAMIC))
4567 reg_source_db(peer);
4568 } else {
4570 }
4571
4573 time(&nowtime);
4574 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
4575 memset(&peer->addr, 0, sizeof(peer->addr));
4576 realtime_update_peer(peer->name, &peer->addr, 0);
4577 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
4578 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
4579 }
4580 else {
4581 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
4582 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
4583 }
4584 }
4585
4586 return peer;
4587}
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:13014
static void reg_source_db(struct iax2_peer *p)
Definition: chan_iax2.c:9130
static int global_rtautoclear
Definition: chan_iax2.c:553
#define IAX_RTIGNOREREGEXPIRE
Definition: chan_iax2.c:542
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Definition: main/config.c:3726
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, ast_variable::name, ast_variable::next, NULL, PARSE_ADDR, PARSE_IN_RANGE, PARSE_PORT_FORBID, PARSE_UINT32, peer_ref(), peer_unref(), realtime_update_peer(), reg_source_db(), SENTINEL, ast_variable::value, 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 4664 of file chan_iax2.c.

4665{
4666 char regseconds[20];
4667 const char *sysname = ast_config_AST_SYSTEM_NAME;
4668 char *syslabel = NULL;
4669 char *port;
4670
4671 if (ast_strlen_zero(sysname)) /* No system name, disable this */
4672 sysname = NULL;
4674 syslabel = "regserver";
4675
4676 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
4677 port = ast_strdupa(ast_sockaddr_stringify_port(sockaddr));
4678 ast_update_realtime("iaxpeers", "name", peername,
4679 "ipaddr", ast_sockaddr_isnull(sockaddr) ? "" : ast_sockaddr_stringify_addr(sockaddr),
4680 "port", ast_sockaddr_isnull(sockaddr) ? "" : port,
4681 "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslabel can be NULL */
4682}
#define IAX_RTSAVE_SYSNAME
Definition: chan_iax2.c:530
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
Definition: main/config.c:3879
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:171

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

4590{
4591 struct ast_variable *var;
4592 struct ast_variable *tmp;
4593 struct iax2_user *user=NULL;
4594 char *str_addr, *str_port;
4595
4596 str_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
4597 str_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
4598
4599 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
4600 if (!var)
4601 var = ast_load_realtime("iaxusers", "name", username, "host", str_addr, SENTINEL);
4602 if (!var && !ast_sockaddr_isnull(addr)) {
4603 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", str_addr, "port", str_port, SENTINEL);
4604 if (!var)
4605 var = ast_load_realtime("iaxusers", "ipaddr", str_addr, "port", str_port, SENTINEL);
4606 }
4607 if (!var) { /* Last ditch effort */
4608 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
4609 /*!\note
4610 * If this one loaded something, then we need to ensure that the host
4611 * field matched. The only reason why we can't have this as a criteria
4612 * is because we only have the IP address and the host field might be
4613 * set as a name (and the reverse PTR might not match).
4614 */
4615 if (var) {
4616 for (tmp = var; tmp; tmp = tmp->next) {
4617 if (!strcasecmp(tmp->name, "host")) {
4618 struct ast_sockaddr *hostaddr = NULL;
4619
4621 || ast_sockaddr_cmp_addr(hostaddr, addr)) {
4622 /* No match */
4624 var = NULL;
4625 }
4626 ast_free(hostaddr);
4627 break;
4628 }
4629 }
4630 }
4631 }
4632 if (!var)
4633 return NULL;
4634
4635 tmp = var;
4636 while(tmp) {
4637 /* Make sure it's not a peer only... */
4638 if (!strcasecmp(tmp->name, "type")) {
4639 if (strcasecmp(tmp->value, "friend") &&
4640 strcasecmp(tmp->value, "user")) {
4641 return NULL;
4642 }
4643 }
4644 tmp = tmp->next;
4645 }
4646
4648
4650
4651 if (!user)
4652 return NULL;
4653
4657 } else {
4659 }
4660
4661 return user;
4662}
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:13339

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, ast_variable::name, ast_variable::next, NULL, PARSE_PORT_FORBID, SENTINEL, user, ast_variable::value, 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 9130 of file chan_iax2.c.

9131{
9132 char data[80];
9133 char *expiry;
9134
9135 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
9136 return;
9137 }
9138
9139 expiry = strrchr(data, ':');
9140 if (!expiry) {
9141 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
9142 return;
9143 }
9144 *expiry++ = '\0';
9145
9146 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
9147 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
9148 return;
9149 }
9150
9151 p->expiry = atoi(expiry);
9152
9153 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
9155
9156 iax2_poke_peer(p, 0);
9157 if (p->expire > -1) {
9158 if (!AST_SCHED_DEL(sched, p->expire)) {
9159 p->expire = -1;
9160 peer_unref(p);
9161 }
9162 }
9163
9164 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
9165
9166 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
9167 if (p->expire == -1) {
9168 peer_unref(p);
9169 }
9170
9171 if (iax2_regfunk) {
9172 iax2_regfunk(p->name, 1);
9173 }
9174
9175 register_peer_exten(p, 1);
9176}
@ 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 9042 of file chan_iax2.c.

9043{
9044 char multi[256];
9045 char *stringp, *ext;
9047 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
9048 stringp = multi;
9049 while((ext = strsep(&stringp, "&"))) {
9050 if (onoff) {
9053 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
9054 } else
9056 }
9057 }
9058}
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:6943
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition: pbx.c:4963
const ast_string_field regexten
Definition: chan_iax2.c:623

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

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

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

9363{
9364 struct iax_ie_data ied;
9365 struct iax2_peer *p;
9366 char challenge[10];
9367 const char *peer_name;
9368 int sentauthmethod;
9369
9370 peer_name = ast_strdupa(iaxs[callno]->peer);
9371
9372 /* SLD: third call to find_peer in registration */
9374 if ((p = find_peer(peer_name, 1))) {
9376 }
9377
9379 if (!iaxs[callno])
9380 goto return_unref;
9381
9382 memset(&ied, 0, sizeof(ied));
9383 /* The selection of which delayed reject is sent may leak information,
9384 * if it sets a static response. For example, if a host is known to only
9385 * use MD5 authentication, then an RSA response would indicate that the
9386 * peer does not exist, and vice-versa.
9387 * Therefore, we use whatever the last peer used (which may vary over the
9388 * course of a server, which should leak minimal information). */
9389 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : IAX_AUTH_MD5;
9390 if (!p) {
9391 iaxs[callno]->authmethods = sentauthmethod;
9392 }
9393 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
9394 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
9395 /* Build the challenge */
9396 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
9399 }
9400 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
9401
9402return_unref:
9403 if (p) {
9404 peer_unref(p);
9405 }
9406
9407 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
9408}
@ 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 9410 of file chan_iax2.c.

9411{
9412 struct iax2_registry *reg;
9413 /* Start pessimistic */
9414 struct iax_ie_data ied;
9415 char peer[256] = "";
9416 char challenge[256] = "";
9417 int res;
9418 int authmethods = 0;
9419 if (ies->authmethods)
9420 authmethods = ies->authmethods;
9421 if (ies->username)
9422 ast_copy_string(peer, ies->username, sizeof(peer));
9423 if (ies->challenge)
9425 memset(&ied, 0, sizeof(ied));
9426 reg = iaxs[callno]->reg;
9427 if (reg) {
9428
9429 if (ast_sockaddr_cmp(&reg->addr, addr)) {
9430 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_sockaddr_stringify(addr));
9431 return -1;
9432 }
9433 if (ast_strlen_zero(reg->secret)) {
9434 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
9436 return -1;
9437 }
9440 if (reg->secret[0] == '[') {
9441 char tmpkey[256];
9442 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
9443 tmpkey[strlen(tmpkey) - 1] = '\0';
9444 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, addr, NULL);
9445 } else
9446 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, addr, NULL);
9447 if (!res) {
9449 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
9450 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
9451 } else
9452 return -1;
9453 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
9454 } else
9455 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
9456 return -1;
9457}

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

7447{
7448 switch(regstate) {
7450 return "Unregistered";
7451 case REG_STATE_REGSENT:
7452 return "Request Sent";
7453 case REG_STATE_AUTHSENT:
7454 return "Auth. Sent";
7456 return "Registered";
7457 case REG_STATE_REJECTED:
7458 return "Rejected";
7459 case REG_STATE_TIMEOUT:
7460 return "Timeout";
7461 case REG_STATE_NOAUTH:
7462 return "No Authentication";
7463 default:
7464 return "Unknown";
7465 }
7466}

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

14280{
14281 return reload_config(0);
14282}

References reload_config().

Referenced by set_config().

◆ reload_config()

static int reload_config ( int  forced_reload)
static

Definition at line 14230 of file chan_iax2.c.

14231{
14232 static const char config[] = "iax.conf";
14233 struct iax2_registry *reg;
14234
14235 if (set_config(config, 1, forced_reload) > 0) {
14236 prune_peers();
14237 prune_users();
14243 memset(&debugaddr, '\0', sizeof(debugaddr));
14244
14247 iax2_do_register(reg);
14249
14250 /* Qualify hosts, too */
14252 }
14253
14256 ast_unload_realtime("iaxpeers");
14257
14258 return 0;
14259}
@ 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:2665
static void poke_all_peers(void)
Definition: chan_iax2.c:14218
static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
Definition: chan_iax2.c:2651

References ao2_callback, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_unload_realtime(), callno_limits, calltoken_ignores, config, debugaddr, iax2_registry::entry, iax2_do_register(), iax_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 2501 of file chan_iax2.c.

2502{
2503 if (!pvt->peercallno) {
2504 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
2505 return;
2506 }
2507
2509}

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

2483{
2484 if (!pvt->transfercallno) {
2485 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
2486 return;
2487 }
2488
2490}

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

3056{
3057 callno_entry entry = PTR_TO_CALLNO_ENTRY(obj);
3058 struct call_number_pool *pool;
3059
3060 /* We lock here primarily to ensure thread safety of the
3061 * total_nonval_callno_used check and decrement */
3063
3064 if (!CALLNO_ENTRY_IS_VALIDATED(entry)) {
3067 } else {
3069 "Attempted to decrement total non calltoken validated "
3070 "callnumbers below zero. Callno is: %d\n",
3072 }
3073 }
3074
3076 pool = &callno_pool;
3077 } else {
3078 pool = &callno_pool_trunk;
3079 }
3080
3081 ast_assert(pool->capacity > pool->available);
3082
3083 /* This clears the validated flag */
3084 entry = CALLNO_ENTRY_GET_CALLNO(entry);
3085
3086 pool->numbers[pool->available] = entry;
3087 pool->available++;
3088
3090
3091 return 0;
3092}
#define PTR_TO_CALLNO_ENTRY(a)
Definition: chan_iax2.c:975

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

4991{
4992 struct iax2_user *user = NULL;
4993 struct iax2_peer *peer = NULL;
4994
4995 if (ast_strlen_zero(name)) {
4996 return; /* no username given */
4997 }
4998
4999 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
5000 user->calltoken_required = CALLTOKEN_YES;
5001 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
5003 }
5004
5005 if (peer) {
5006 peer_unref(peer);
5007 }
5008 if (user) {
5010 }
5011}

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

4909{
4910 struct chan_iax2_pvt *pvt = iaxs[callno];
4911 int frametype = f->af.frametype;
4912 int subclass = f->af.subclass.integer;
4913 struct {
4914 struct ast_iax2_full_hdr fh;
4915 struct iax_ie_data ied;
4916 } data = {
4917 .ied.buf = { 0 },
4918 .ied.pos = 0,
4919 };
4920 /* total len - header len gives us the frame's IE len */
4921 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
4922
4923 if (!pvt) {
4924 return; /* this should not be possible if called from socket_process() */
4925 }
4926
4927 /*
4928 * Check to make sure last frame sent is valid for call token resend
4929 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog
4930 * 2. Frame should _NOT_ already have a destination callno
4931 * 3. Frame must be a valid iax_frame subclass capable of starting dialog
4932 * 4. Pvt must have a calltoken_ie_len which represents the number of
4933 * bytes at the end of the frame used for the previous calltoken ie.
4934 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length
4935 * 6. Total length of f->data must be _LESS_ than size of our data struct
4936 * because f->data must be able to fit within data.
4937 */
4938 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
4939 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
4940 (f->datalen > sizeof(data))) {
4941
4942 return; /* ignore resend, token was not valid for the dialog */
4943 }
4944
4945 /* token is valid
4946 * 1. Copy frame data over
4947 * 2. Redo calltoken IE, it will always be the last ie in the frame.
4948 * NOTE: Having the ie always be last is not protocol specified,
4949 * it is only an implementation choice. Since we only expect the ie to
4950 * be last for frames we have sent, this can no way be affected by
4951 * another end point.
4952 * 3. Remove frame from queue
4953 * 4. Free old frame
4954 * 5. Clear previous seqnos
4955 * 6. Resend with CALLTOKEN ie.
4956 */
4957
4958 /* ---1.--- */
4959 memcpy(&data, f->data, f->datalen);
4960 data.ied.pos = ie_data_pos;
4961
4962 /* ---2.--- */
4963 /* move to the beginning of the calltoken ie so we can write over it */
4964 data.ied.pos -= pvt->calltoken_ie_len;
4965 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
4966
4967 /* make sure to update token length incase it ever has to be stripped off again */
4968 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */
4969
4970 /* ---3.--- */
4971 AST_LIST_REMOVE(&frame_queue[callno], f, list);
4972
4973 /* ---4.--- */
4974 iax2_frame_free(f);
4975
4976 /* ---5.--- */
4977 pvt->oseqno = 0;
4978 pvt->rseqno = 0;
4979 pvt->iseqno = 0;
4980 pvt->aseqno = 0;
4981 if (pvt->peercallno) {
4983 pvt->peercallno = 0;
4984 }
4985
4986 /* ---6.--- */
4987 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
4988}
static int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
Definition: chan_iax2.c:3158

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

9822{
9823 int i;
9824 unsigned int length, offset = 0;
9825 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
9826
9827 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
9828 length = ies->ospblocklength[i];
9829 if (length != 0) {
9830 if (length > IAX_MAX_OSPBLOCK_SIZE) {
9831 /* OSP token block length wrong, clear buffer */
9832 offset = 0;
9833 break;
9834 } else {
9835 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
9836 offset += length;
9837 }
9838 } else {
9839 break;
9840 }
9841 }
9842 *(full_osptoken + offset) = '\0';
9843 if (strlen(full_osptoken) != offset) {
9844 /* OSP token length wrong, clear buffer */
9845 *full_osptoken = '\0';
9846 }
9847
9848 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
9849}
#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 9810 of file chan_iax2.c.

9811{
9812 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
9813 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
9814 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
9815 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
9816 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
9817 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
9818 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
9819}
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:751

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

3128{
3129 int i;
3130 struct peercnt *peercnt;
3131 struct peercnt tmp;
3132
3133 ast_sockaddr_copy(&tmp.addr, addr);
3134
3135 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
3136 /* refcount is incremented with ao2_find. keep that ref for the scheduler */
3137 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_sockaddr_stringify_addr(addr), MIN_REUSE_TIME);
3139 if (i == -1) {
3140 ao2_ref(peercnt, -1);
3141 }
3142 }
3143
3145 sched,
3146 MIN_REUSE_TIME * 1000,
3148 CALLNO_ENTRY_TO_PTR(entry));
3149}

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

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

4317{
4318 int type, len;
4319 int ret;
4320 int needfree = 0;
4321
4322 /*
4323 * Clear fr->af.data if there is no data in the buffer. Things
4324 * like AST_CONTROL_HOLD without a suggested music class must
4325 * have a NULL pointer.
4326 */
4327 if (!fr->af.datalen) {
4328 memset(&fr->af.data, 0, sizeof(fr->af.data));
4329 }
4330
4331 /* Attempt to recover wrapped timestamps */
4332 unwrap_timestamp(fr);
4333
4334 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
4335 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
4336 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
4337 else {
4338#if 0
4339 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
4340#endif
4341 fr->af.delivery = ast_tv(0,0);
4342 }
4343
4345 len = 0;
4346
4347 if(fr->af.frametype == AST_FRAME_VOICE) {
4350 } else if(fr->af.frametype == AST_FRAME_CNG) {
4352 }
4353
4354 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
4355 if (tsout)
4356 *tsout = fr->ts;
4357 __do_deliver(fr);
4358 return -1;
4359 }
4360
4361 /* insert into jitterbuffer */
4362 /* TODO: Perhaps we could act immediately if it's not droppable and late */
4363 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
4364 calc_rxstamp(iaxs[fr->callno],fr->ts));
4365 if (ret == JB_DROP) {
4366 needfree++;
4367 } else if (ret == JB_SCHED) {
4369 }
4370 if (tsout)
4371 *tsout = fr->ts;
4372 if (needfree) {
4373 /* Free our iax frame */
4374 iax2_frame_free(fr);
4375 return -1;
4376 }
4377 return 0;
4378}
static void unwrap_timestamp(struct iax_frame *fr)
Definition: chan_iax2.c:4146
static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
Definition: chan_iax2.c:6324
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 2209 of file chan_iax2.c.

2210{
2211 unsigned short callno = PTR_TO_CALLNO(vid);
2212 ast_mutex_lock(&iaxsl[callno]);
2213 if (iaxs[callno]) {
2214 ast_debug(1, "Really destroying %d now...\n", callno);
2215 iax2_destroy(callno);
2216 }
2217 ast_mutex_unlock(&iaxsl[callno]);
2218 return 0;
2219}

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

4873{
4874 struct {
4875 struct ast_iax2_full_hdr f;
4876 struct iax_ie_data ied;
4877 } data;
4878 size_t size = sizeof(struct ast_iax2_full_hdr);
4879
4880 if (ied) {
4881 size += ied->pos;
4882 memcpy(&data.ied, ied->buf, ied->pos);
4883 }
4884
4885 data.f.scallno = htons(0x8000 | callno);
4886 data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS);
4887 data.f.ts = htonl(ts);
4888 data.f.iseqno = seqno;
4889 data.f.oseqno = 0;
4890 data.f.type = AST_FRAME_IAX;
4891 data.f.csub = compress_subclass(command);
4892
4893 iax_outputframe(NULL, &data.f, 0, addr, size - sizeof(struct ast_iax2_full_hdr));
4894
4895 return ast_sendto(sockfd, &data, size, 0, addr);
4896}
#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 7871 of file chan_iax2.c.

7872{
7874 /* Control frame should not go out on the wire. */
7875 ast_debug(2, "Callno %d: Blocked sending control frame %d.\n",
7876 i->callno, command);
7877 return 0;
7878 }
7879 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
7880}
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:7852
static int iax2_is_control_frame_allowed(int subtype)
Definition: chan_iax2.c:1430

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

7897{
7898 int call_num = i->callno;
7899 /* It is assumed that the callno has already been locked */
7901 if (!iaxs[call_num])
7902 return -1;
7903 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
7904}

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

7907{
7908 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
7909}

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

7883{
7884 int res;
7885 ast_mutex_lock(&iaxsl[callno]);
7886 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
7887 ast_mutex_unlock(&iaxsl[callno]);
7888 return res;
7889}

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

7912{
7913 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
7914}

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

1878{
1879#ifdef SCHED_MULTITHREADED
1880 if (schedule_action(__send_lagrq, data))
1881#endif
1882 __send_lagrq(data);
1883 return 0;
1884}
static void __send_lagrq(const void *data)
Definition: chan_iax2.c:1853

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

3476{
3477 int res;
3478 int callno = f->callno;
3479
3480 /* Don't send if there was an error, but return error instead */
3481 if (!callno || !iaxs[callno] || iaxs[callno]->error)
3482 return -1;
3483
3484 /* Called with iaxsl held */
3485 if (iaxdebug) {
3486 ast_debug(8, "Sending %u on %d/%d to %s\n", f->ts, callno, iaxs[callno]->peercallno, ast_sockaddr_stringify(&iaxs[callno]->addr));
3487 }
3488 if (f->transfer) {
3489 iax_outputframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
3490 res = ast_sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0, &iaxs[callno]->transfer);
3491 } else {
3492 iax_outputframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
3493 res = ast_sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0, &iaxs[callno]->addr);
3494 }
3495 if (res < 0) {
3496 if (iaxdebug)
3497 ast_debug(1, "Received error: %s\n", strerror(errno));
3498 handle_error();
3499 } else
3500 res = 0;
3501
3502 return res;
3503}
static int handle_error(void)
Definition: chan_iax2.c:3428

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

1814{
1815#ifdef SCHED_MULTITHREADED
1816 if (schedule_action(__send_ping, data))
1817#endif
1818 __send_ping(data);
1819
1820 return 0;
1821}
static void __send_ping(const void *data)
Definition: chan_iax2.c:1789

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

2232{
2233 struct signaling_queue_entry *s = NULL;
2234
2235 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
2236 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
2238 }
2239 pvt->hold_signaling = 0;
2240}

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

9592{
9593 int res = 0;
9594 struct iax_frame *fr;
9595 struct ast_iax2_meta_hdr *meta;
9596 struct ast_iax2_meta_trunk_hdr *mth;
9597 int calls = 0;
9598
9599 /* Point to frame */
9600 fr = (struct iax_frame *)tpeer->trunkdata;
9601 /* Point to meta data */
9602 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
9603 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
9604 if (tpeer->trunkdatalen) {
9605 /* We're actually sending a frame, so fill the meta trunk header and meta header */
9606 meta->zeros = 0;
9607 meta->metacmd = IAX_META_TRUNK;
9609 meta->cmddata = IAX_META_TRUNK_MINI;
9610 else
9611 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
9612 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
9613 /* And the rest of the ast_iax2 header */
9615 fr->retrans = -1;
9616 fr->transfer = 0;
9617 /* Any appropriate call will do */
9618 fr->data = fr->afdata;
9619 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
9620 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
9621 calls = tpeer->calls;
9622#if 0
9623 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));
9624#endif
9625 /* Reset transmit trunk side data */
9626 tpeer->trunkdatalen = 0;
9627 tpeer->calls = 0;
9628 }
9629 if (res < 0)
9630 return res;
9631 return calls;
9632}
static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
Definition: chan_iax2.c:6145
static int transmit_trunk(struct iax_frame *f, struct ast_sockaddr *addr, int sockfd)
Definition: chan_iax2.c:3462
#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 13696 of file chan_iax2.c.

13697{
13698 struct ast_config *cfg, *ucfg;
13699 iax2_format capability;
13700 struct ast_variable *v;
13701 char *cat;
13702 const char *utype;
13703 const char *tosval;
13704 int format;
13705 int portno = IAX_DEFAULT_PORTNO;
13706 int x;
13707 int mtuv;
13708 int subscribe_network_change = 1;
13709 struct iax2_user *user;
13710 struct iax2_peer *peer;
13711 struct ast_netsock *ns;
13712 struct ast_flags config_flags = { (reload && !forced) ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13713 struct ast_sockaddr bindaddr;
13714 struct iax2_codec_pref prefs_new;
13715
13716 cfg = ast_config_load(config_file, config_flags);
13717
13718 if (!cfg) {
13719 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13720 return -1;
13721 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13722 ucfg = ast_config_load("users.conf", config_flags);
13723 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13724 return 0;
13725 /* Otherwise we need to reread both files */
13727 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13728 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13729 ast_config_destroy(ucfg);
13730 return 0;
13731 }
13732 if (!cfg) {
13733 /* should have been able to load the config here */
13734 ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file);
13735 return -1;
13736 }
13737 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13738 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13739 return 0;
13740 } else { /* iax.conf changed, gotta reread users.conf, too */
13742 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13743 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
13744 ast_config_destroy(cfg);
13745 return 0;
13746 }
13747 }
13748
13749 if (reload) {
13751 }
13752
13753 ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0);
13754
13755 /* Setup new codec prefs */
13757
13758 /* Reset Global Flags */
13759 memset(&globalflags, 0, sizeof(globalflags));
13762
13763#ifdef SO_NO_CHECK
13764 nochecksums = 0;
13765#endif
13766 /* Reset default parking lot */
13767 default_parkinglot[0] = '\0';
13768
13774
13775 maxauthreq = 3;
13776
13777 srvlookup = 0;
13778 iax2_authmethods = 0;
13779
13780 v = ast_variable_browse(cfg, "general");
13781
13782 /* Seed initial tos value */
13783 tosval = ast_variable_retrieve(cfg, "general", "tos");
13784 if (tosval) {
13785 if (ast_str2tos(tosval, &qos.tos))
13786 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13787 }
13788 /* Seed initial cos value */
13789 tosval = ast_variable_retrieve(cfg, "general", "cos");
13790 if (tosval) {
13791 if (ast_str2cos(tosval, &qos.cos))
13792 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13793 }
13794 while(v) {
13795 if (!strcasecmp(v->name, "bindport")) {
13796 if (reload) {
13797 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13798 }
13799 else if (ast_parse_arg(v->value, PARSE_UINT32 | PARSE_IN_RANGE, &portno, 1024, 65535)) {
13800 portno = IAX_DEFAULT_PORTNO;
13801 }
13802 } else if (!strcasecmp(v->name, "pingtime")){
13803 ping_time = atoi(v->value);
13804 }
13805 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13806 if (reload) {
13807 if (atoi(v->value) != iaxthreadcount)
13808 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13809 } else {
13810 iaxthreadcount = atoi(v->value);
13811 if (iaxthreadcount < 1) {
13812 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13813 iaxthreadcount = 1;
13814 } else if (iaxthreadcount > 256) {
13815 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13816 iaxthreadcount = 256;
13817 }
13818 }
13819 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13820 if (reload) {
13822 iaxmaxthreadcount = atoi(v->value);
13824 } else {
13825 iaxmaxthreadcount = atoi(v->value);
13826 if (iaxmaxthreadcount < 0) {
13827 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13829 } else if (iaxmaxthreadcount > 256) {
13830 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13831 iaxmaxthreadcount = 256;
13832 }
13833 }
13834 } else if (!strcasecmp(v->name, "nochecksums")) {
13835#ifdef SO_NO_CHECK
13836 if (ast_true(v->value))
13837 nochecksums = 1;
13838 else
13839 nochecksums = 0;
13840#else
13841 if (ast_true(v->value))
13842 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13843#endif
13844 }
13845 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13846 maxjitterbuffer = atoi(v->value);
13847 else if (!strcasecmp(v->name, "resyncthreshold"))
13848 resyncthreshold = atoi(v->value);
13849 else if (!strcasecmp(v->name, "maxjitterinterps"))
13850 maxjitterinterps = atoi(v->value);
13851 else if (!strcasecmp(v->name, "jittertargetextra"))
13852 jittertargetextra = atoi(v->value);
13853 else if (!strcasecmp(v->name, "lagrqtime"))
13854 lagrq_time = atoi(v->value);
13855 else if (!strcasecmp(v->name, "maxregexpire"))
13856 max_reg_expire = atoi(v->value);
13857 else if (!strcasecmp(v->name, "minregexpire"))
13858 min_reg_expire = atoi(v->value);
13859 else if (!strcasecmp(v->name, "bindaddr")) {
13860 if (reload) {
13861 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13862 } else {
13863
13864 if (!ast_parse_arg(v->value, PARSE_ADDR, NULL)) {
13865
13867
13868 if (!ast_sockaddr_port(&bindaddr)) {
13870 }
13871
13872 if (!(ns = ast_netsock_bindaddr(netsock, io, &bindaddr, qos.tos, qos.cos, socket_read, NULL))) {
13873 ast_log(LOG_WARNING, "Unable to apply binding to '%s' at line %d\n", v->value, v->lineno);
13874 } else {
13875 ast_verb(2, "Binding IAX2 to address %s\n", ast_sockaddr_stringify(&bindaddr));
13876
13877 if (defaultsockfd < 0) {
13879 }
13881 }
13882
13883 } else {
13884 ast_log(LOG_WARNING, "Invalid address '%s' specified, at line %d\n", v->value, v->lineno);
13885 }
13886 }
13887 } else if (!strcasecmp(v->name, "auth")) {
13890 ast_log(LOG_WARNING, "Default auth method is set to deprecated 'plaintext' at line %d of iax.conf\n", v->lineno);
13891 }
13892 } else if (!strcasecmp(v->name, "authdebug")) {
13893 authdebug = ast_true(v->value);
13894 } else if (!strcasecmp(v->name, "encryption")) {
13896 if (!iax2_encryption) {
13898 }
13899 } else if (!strcasecmp(v->name, "forceencryption")) {
13900 if (ast_false(v->value)) {
13902 } else {
13904 if (iax2_encryption) {
13906 }
13907 }
13908 } else if (!strcasecmp(v->name, "transfer")) {
13909 if (!strcasecmp(v->value, "mediaonly")) {
13911 } else if (ast_true(v->value)) {
13913 } else
13915 } else if (!strcasecmp(v->name, "codecpriority")) {
13916 if(!strcasecmp(v->value, "caller"))
13918 else if(!strcasecmp(v->value, "disabled"))
13920 else if(!strcasecmp(v->value, "reqonly")) {
13923 }
13924 } else if (!strcasecmp(v->name, "jitterbuffer"))
13926 else if (!strcasecmp(v->name, "delayreject"))
13928 else if (!strcasecmp(v->name, "allowfwdownload"))
13930 else if (!strcasecmp(v->name, "rtcachefriends"))
13932 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13934 else if (!strcasecmp(v->name, "rtupdate"))
13936 else if (!strcasecmp(v->name, "rtsavesysname"))
13938 else if (!strcasecmp(v->name, "trunktimestamps"))
13940 else if (!strcasecmp(v->name, "rtautoclear")) {
13941 int i = atoi(v->value);
13942 if(i > 0)
13944 else
13945 i = 0;
13947 } else if (!strcasecmp(v->name, "trunkfreq")) {
13948 trunkfreq = atoi(v->value);
13949 if (trunkfreq < 10) {
13950 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n");
13951 trunkfreq = 10;
13952 } else if (trunkfreq > 1000) {
13953 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n");
13954 trunkfreq = 1000;
13955 }
13956 if (timer) {
13958 }
13959 } else if (!strcasecmp(v->name, "trunkmtu")) {
13960 mtuv = atoi(v->value);
13961 if (mtuv == 0 )
13963 else if (mtuv >= 172 && mtuv < 4000)
13964 global_max_trunk_mtu = mtuv;
13965 else
13966 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13967 mtuv, v->lineno);
13968 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13969 trunkmaxsize = atoi(v->value);
13970 if (trunkmaxsize == 0)
13972 } else if (!strcasecmp(v->name, "autokill")) {
13973 if (sscanf(v->value, "%30d", &x) == 1) {
13974 if (x >= 0)
13975 autokill = x;
13976 else
13977 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13978 } else if (ast_true(v->value)) {
13980 } else {
13981 autokill = 0;
13982 }
13983 } else if (!strcasecmp(v->name, "bandwidth")) {
13984 if (!strcasecmp(v->value, "low")) {
13985 capability = iax2_codec_pref_from_bitfield(&prefs_new,
13987 } else if (!strcasecmp(v->value, "medium")) {
13988 capability = iax2_codec_pref_from_bitfield(&prefs_new,
13990 } else if (!strcasecmp(v->value, "high")) {
13991 capability = iax2_codec_pref_from_bitfield(&prefs_new,
13993 } else {
13994 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13995 }
13996 } else if (!strcasecmp(v->name, "allow")) {
13997 iax2_parse_allow_disallow(&prefs_new, &capability, v->value, 1);
13998 } else if (!strcasecmp(v->name, "disallow")) {
13999 iax2_parse_allow_disallow(&prefs_new, &capability, v->value, 0);
14000 } else if (!strcasecmp(v->name, "register")) {
14001 iax2_register(v->value, v->lineno);
14002 } else if (!strcasecmp(v->name, "iaxcompat")) {
14003 iaxcompat = ast_true(v->value);
14004 } else if (!strcasecmp(v->name, "regcontext")) {
14006 /* Create context if it doesn't exist already */
14008 } else if (!strcasecmp(v->name, "tos")) {
14009 if (ast_str2tos(v->value, &qos.tos))
14010 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
14011 } else if (!strcasecmp(v->name, "cos")) {
14012 if (ast_str2cos(v->value, &qos.cos))
14013 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
14014 } else if (!strcasecmp(v->name, "parkinglot")) {
14016 } else if (!strcasecmp(v->name, "accountcode")) {
14018 } else if (!strcasecmp(v->name, "mohinterpret")) {
14020 } else if (!strcasecmp(v->name, "mohsuggest")) {
14022 } else if (!strcasecmp(v->name, "amaflags")) {
14023 format = ast_channel_string2amaflag(v->value);
14024 if (format < 0) {
14025 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
14026 } else {
14027 amaflags = format;
14028 }
14029 } else if (!strcasecmp(v->name, "language")) {
14030 ast_copy_string(language, v->value, sizeof(language));
14031 } else if (!strcasecmp(v->name, "maxauthreq")) {
14032 maxauthreq = atoi(v->value);
14033 if (maxauthreq < 0)
14034 maxauthreq = 0;
14035 } else if (!strcasecmp(v->name, "adsi")) {
14036 adsi = ast_true(v->value);
14037 } else if (!strcasecmp(v->name, "srvlookup")) {
14038 srvlookup = ast_true(v->value);
14039 } else if (!strcasecmp(v->name, "connectedline")) {
14040 if (ast_true(v->value)) {
14042 } else if (!strcasecmp(v->value, "send")) {
14045 } else if (!strcasecmp(v->value, "receive")) {
14048 } else {
14050 }
14051 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
14052 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
14053 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
14054 }
14055 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
14056 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
14057 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);
14058 }
14059 } else if (!strcasecmp(v->name, "calltokenoptional")) {
14060 if (add_calltoken_ignore(v->value)) {
14061 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
14062 return -1;
14063 }
14064 } else if (!strcasecmp(v->name, "calltokenexpiration")) {
14065 int temp = -1;
14066 sscanf(v->value, "%u", &temp);
14067 if( temp <= 0 ){
14068 ast_log(LOG_WARNING, "Invalid calltokenexpiration value %s. Should be integer greater than 0.\n", v->value);
14069 } else {
14070 max_calltoken_delay = temp;
14071 }
14072 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
14073 if (ast_true(v->value)) {
14074 subscribe_network_change = 1;
14075 } else if (ast_false(v->value)) {
14076 subscribe_network_change = 0;
14077 } else {
14078 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
14079 }
14080 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
14081 if (ast_true(v->value)) {
14083 } else if (ast_false(v->value)) {
14085 } else {
14086 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
14087 }
14088 }/*else if (strcasecmp(v->name,"type")) */
14089 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
14090 v = v->next;
14091 }
14092
14093 if (subscribe_network_change) {
14095 } else {
14097 }
14098
14099 if (defaultsockfd < 0) {
14100
14102
14103 if (!(ns = ast_netsock_bindaddr(netsock, io, &bindaddr, qos.tos, qos.cos, socket_read, NULL))) {
14104 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
14105 } else {
14106 ast_verb(2, "Binding IAX2 to default address %s\n", ast_sockaddr_stringify(&bindaddr));
14109 }
14110 }
14111 if (reload) {
14114 if (!outsock) {
14115 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14116 return -1;
14117 }
14119 }
14120
14122 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
14125 }
14126 prefs_global = prefs_new;
14127 iax2_capability = capability;
14128
14129 if (ucfg) {
14130 struct ast_variable *gen;
14131 int genhasiax;
14132 int genregisteriax;
14133 const char *hasiax, *registeriax;
14134
14135 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
14136 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
14137 gen = ast_variable_browse(ucfg, "general");
14138 cat = ast_category_browse(ucfg, NULL);
14139 while (cat) {
14140 if (strcasecmp(cat, "general")) {
14141 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
14142 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
14143 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
14144 /* Start with general parameters, then specific parameters, user and peer */
14145 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
14146 if (user) {
14148 user = user_unref(user);
14149 }
14150 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
14151 if (peer) {
14152 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
14153 reg_source_db(peer);
14154 }
14155 ao2_link(peers, peer);
14156 peer = peer_unref(peer);
14157 }
14158 }
14159 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
14160 char tmp[256];
14161 const char *host = ast_variable_retrieve(ucfg, cat, "host");
14162 const char *username = ast_variable_retrieve(ucfg, cat, "username");
14163 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
14164 if (!host)
14165 host = ast_variable_retrieve(ucfg, "general", "host");
14166 if (!username)
14167 username = ast_variable_retrieve(ucfg, "general", "username");
14168 if (!secret)
14169 secret = ast_variable_retrieve(ucfg, "general", "secret");
14170 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
14171 if (!ast_strlen_zero(secret))
14172 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
14173 else
14174 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
14175 iax2_register(tmp, 0);
14176 }
14177 }
14178 }
14179 cat = ast_category_browse(ucfg, cat);
14180 }
14181 ast_config_destroy(ucfg);
14182 }
14183
14184 cat = ast_category_browse(cfg, NULL);
14185 while(cat) {
14186 if (strcasecmp(cat, "general")) {
14187 utype = ast_variable_retrieve(cfg, cat, "type");
14188 if (!strcasecmp(cat, "callnumberlimits")) {
14190 } else if (utype) {
14191 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
14192 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
14193 if (user) {
14195 user = user_unref(user);
14196 }
14197 }
14198 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
14199 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
14200 if (peer) {
14201 if (ast_test_flag64(peer, IAX_DYNAMIC))
14202 reg_source_db(peer);
14203 ao2_link(peers, peer);
14204 peer = peer_unref(peer);
14205 }
14206 } else if (strcasecmp(utype, "user")) {
14207 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
14208 }
14209 } else
14210 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
14211 }
14212 cat = ast_category_browse(cfg, cat);
14213 }
14214 ast_config_destroy(cfg);
14215 return 1;
14216}
int ast_str2tos(const char *value, unsigned int *tos)
Convert a string to the appropriate TOS value.
Definition: acl.c:983
int ast_str2cos(const char *value, unsigned int *cos)
Convert a string to the appropriate COS value.
Definition: acl.c:969
static struct ast_generator gen
static const char config_file[]
Definition: cdr_odbc.c:54
static int iaxcompat
Definition: chan_iax2.c:371
static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL
Definition: chan_iax2.c:1041
static uint16_t DEFAULT_MAXCALLNO_LIMIT
Definition: chan_iax2.c:1039
static int add_calltoken_ignore(const char *addr)
Definition: chan_iax2.c:2868
#define MAX_TRUNKDATA
Definition: chan_iax2.c:364
static int iax2_register(const char *value, int lineno)
Definition: chan_iax2.c:9006
static int max_reg_expire
Definition: chan_iax2.c:384
static void set_config_destroy(void)
Definition: chan_iax2.c:13679
static int reload(void)
Definition: chan_iax2.c:14279
#define IAX_ALLOWFWDOWNLOAD
Definition: chan_iax2.c:547
static uint16_t global_maxcallno
Definition: chan_iax2.c:1043
static void build_callno_limits(struct ast_variable *v)
Definition: chan_iax2.c:2813
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
@ CONFIG_FLAG_FILEUNCHANGED
#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:869
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
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:6164
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, 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 10244 of file chan_iax2.c.

10245{
10246 iax2_lock_owner(callno);
10247 if (iaxs[callno] && iaxs[callno]->owner) {
10248 struct ast_channel *owner;
10249 const char *name;
10250
10251 owner = iaxs[callno]->owner;
10252 if (causecode) {
10253 ast_channel_hangupcause_set(owner, causecode);
10254 }
10256 ast_channel_ref(owner);
10257 ast_channel_unlock(owner);
10258 ast_mutex_unlock(&iaxsl[callno]);
10259 ast_set_hangupsource(owner, name, 0);
10260 ast_channel_unref(owner);
10261 ast_mutex_lock(&iaxsl[callno]);
10262 }
10263}
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2997
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:2468
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3008

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

2627{
2628 uint16_t limit = global_maxcallno;
2629 struct addr_range *addr_range;
2630 struct ast_sockaddr addr;
2631
2632 ast_sockaddr_copy(&addr, &peercnt->addr);
2633
2634 if (peercnt->reg && peercnt->limit) {
2635 return; /* this peercnt has a custom limit set by a registration */
2636 }
2637
2639 limit = addr_range->limit;
2640 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_sockaddr_stringify(&addr));
2641 ao2_ref(addr_range, -1);
2642 }
2643
2644 peercnt->limit = limit;
2645}

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

2652{
2653 struct peercnt *peercnt = obj;
2654
2656 ast_debug(1, "Reset limits for peercnts table\n");
2657
2658 return 0;
2659}

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

1184{
1188}
ast_cond_t cond
Definition: app_sla.c:336
ast_mutex_t lock
Definition: app_sla.c:337

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

12187{
12188 int res = socket_process_helper(thread);
12191 }
12192 return res;
12193}
static int socket_process_helper(struct iax2_thread *thread)
Definition: chan_iax2.c:10265
int ast_callid_threadassoc_remove(void)
Removes callid from thread storage of the calling thread.
Definition: logger.c:2314

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

10266{
10267 struct ast_sockaddr addr;
10268 int res;
10269 int updatehistory=1;
10270 int new = NEW_PREVENT;
10271 int dcallno = 0;
10272 char decrypted = 0;
10273 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
10274 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
10275 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
10276 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
10277 struct iax_frame *fr;
10278 struct iax_frame *cur;
10279 struct ast_frame f = { 0, };
10280 struct ast_channel *c = NULL;
10281 struct iax2_dpcache *dp;
10282 struct iax2_peer *peer;
10283 struct iax_ies ies;
10284 struct iax_ie_data ied0, ied1;
10285 iax2_format format;
10286 int fd;
10287 int exists;
10288 int minivid = 0;
10289 char empty[32]=""; /* Safety measure */
10290 struct iax_frame *duped_fr;
10291 char host_pref_buf[128];
10292 char caller_pref_buf[128];
10293 struct iax2_codec_pref pref;
10294 char *using_prefs = "mine";
10295
10296 /* allocate an iax_frame with 4096 bytes of data buffer */
10297 fr = ast_alloca(sizeof(*fr) + 4096);
10298 memset(fr, 0, sizeof(*fr));
10299 fr->afdatalen = 4096; /* From ast_alloca() above */
10300
10301 /* Copy frequently used parameters to the stack */
10302 res = thread->buf_len;
10303 fd = thread->iofd;
10304 ast_sockaddr_copy(&addr, &thread->ioaddr);
10305
10306 if (res < sizeof(*mh)) {
10307 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
10308 return 1;
10309 }
10310 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
10311 if (res < sizeof(*vh)) {
10312 ast_log(LOG_WARNING, "Rejecting packet from '%s' that is flagged as a video frame but is too short\n",
10313 ast_sockaddr_stringify(&addr));
10314 return 1;
10315 }
10316
10317 /* This is a video frame, get call number */
10318 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &addr, new, fd, 0);
10319 minivid = 1;
10320 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
10321 return socket_process_meta(res, meta, &addr, fd, fr);
10322
10323#ifdef DEBUG_SUPPORT
10324 if (res >= sizeof(*fh))
10325 iax_outputframe(NULL, fh, 1, &addr, res - sizeof(*fh));
10326#endif
10327 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10328 if (res < sizeof(*fh)) {
10329 ast_log(LOG_WARNING, "Rejecting packet from '%s' that is flagged as a full frame but is too short\n",
10330 ast_sockaddr_stringify(&addr));
10331 return 1;
10332 }
10333
10334 /* Get the destination call number */
10335 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
10336
10337
10338 /* check to make sure this full frame isn't encrypted before we attempt
10339 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the
10340 * callno is not found here, that just means one hasn't been allocated for
10341 * this connection yet. */
10342 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &addr, NEW_PREVENT, fd, 1))) {
10344 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
10345 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10346 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10348 return 1;
10349 }
10350 decrypted = 1;
10351 }
10353 }
10354
10355 /* Retrieve the type and subclass */
10356 f.frametype = fh->type;
10357 if (f.frametype == AST_FRAME_VIDEO) {
10359 if (!f.subclass.format) {
10360 return 1;
10361 }
10362 if ((fh->csub >> 6) & 0x1) {
10363 f.subclass.frame_ending = 1;
10364 }
10365 } else if (f.frametype == AST_FRAME_VOICE) {
10367 if (!f.subclass.format) {
10368 return 1;
10369 }
10370 } else {
10372 }
10373
10374 /* Deal with POKE/PONG without allocating a callno */
10376 /* Reply back with a PONG, but don't care about the result. */
10377 send_apathetic_reply(1, ntohs(fh->scallno), &addr, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10378 return 1;
10379 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
10380 /* Ignore */
10381 return 1;
10382 }
10383
10384 f.datalen = res - sizeof(*fh);
10385 if (f.datalen) {
10386 if (f.frametype == AST_FRAME_IAX) {
10387 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
10388 char subclass[40];
10389 iax_frame_subclass2str(f.subclass.integer, subclass, sizeof(subclass));
10390 ast_log(LOG_WARNING, "Undecodable %s frame received from '%s'\n", subclass, ast_sockaddr_stringify(&addr));
10391 ast_variables_destroy(ies.vars);
10392 return 1;
10393 }
10394 f.data.ptr = NULL;
10395 f.datalen = 0;
10396 } else {
10397 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
10398 memset(&ies, 0, sizeof(ies));
10399 }
10400 } else {
10401 if (f.frametype == AST_FRAME_IAX)
10402 f.data.ptr = NULL;
10403 else
10404 f.data.ptr = empty;
10405 memset(&ies, 0, sizeof(ies));
10406 }
10407
10408 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
10409 /* only set NEW_ALLOW if calltoken checks out */
10410 if (handle_call_token(fh, &ies, &addr, fd)) {
10411 ast_variables_destroy(ies.vars);
10412 return 1;
10413 }
10414
10415 if (ies.calltoken && ies.calltokendata) {
10416 /* if we've gotten this far, and the calltoken ie data exists,
10417 * then calltoken validation _MUST_ have taken place. If calltoken
10418 * data is provided, it is always validated regardless of any
10419 * calltokenoptional or requirecalltoken options */
10421 } else {
10422 new = NEW_ALLOW;
10423 }
10424 }
10425 } else {
10426 /* Don't know anything about it yet */
10428 f.subclass.integer = 0;
10429 memset(&ies, 0, sizeof(ies));
10430 }
10431
10432 if (!fr->callno) {
10433 int check_dcallno = 0;
10434
10435 /*
10436 * We enforce accurate destination call numbers for ACKs. This forces the other
10437 * end to know the destination call number before call setup can complete.
10438 *
10439 * Discussed in the following thread:
10440 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html
10441 */
10442
10443 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10444 check_dcallno = 1;
10445 }
10446
10447 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &addr, new, fd, check_dcallno))) {
10448 ast_debug(1, "Received frame without existent call number (%d)\n", ntohs(mh->callno) & ~IAX_FLAG_FULL);
10450 send_apathetic_reply(1, ntohs(fh->scallno), &addr, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10452 send_apathetic_reply(1, ntohs(fh->scallno), &addr, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10453 } else {
10454 ast_log(LOG_WARNING, "Silently dropping frame without existent call number: %d\n", ntohs(mh->callno) & ~IAX_FLAG_FULL);
10455 }
10456 ast_variables_destroy(ies.vars);
10457 return 1;
10458 }
10459 }
10460
10461 if (fr->callno > 0) {
10462 ast_callid mount_callid;
10464 if (iaxs[fr->callno] && ((mount_callid = iax_pvt_callid_get(fr->callno)))) {
10465 /* Bind to thread */
10466 ast_callid_threadassoc_add(mount_callid);
10467 }
10468 }
10469
10470 if (!fr->callno || !iaxs[fr->callno]) {
10471 /* A call arrived for a nonexistent destination. Unless it's an "inval"
10472 frame, reply with an inval */
10473 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10474 /* We can only raw hangup control frames */
10475 if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10479 (f.frametype != AST_FRAME_IAX))
10480 raw_hangup(&addr, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10481 fd);
10482 }
10483 if (fr->callno > 0){
10485 }
10486 ast_variables_destroy(ies.vars);
10487 return 1;
10488 }
10489 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10490 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10491 ast_log(LOG_WARNING, "Packet Decrypt Failed!\n");
10492 ast_variables_destroy(ies.vars);
10494 return 1;
10495 }
10496 decrypted = 1;
10497 }
10498
10499#ifdef DEBUG_SUPPORT
10500 if (decrypted) {
10501 iax_outputframe(NULL, fh, 3, &addr, res - sizeof(*fh));
10502 }
10503#endif
10504
10505 if (iaxs[fr->callno]->owner && fh->type == AST_FRAME_IAX &&
10506 (fh->csub == IAX_COMMAND_HANGUP
10507 || fh->csub == IAX_COMMAND_REJECT
10508 || fh->csub == IAX_COMMAND_REGREJ
10509 || fh->csub == IAX_COMMAND_TXREJ)) {
10510 struct ast_control_pvt_cause_code *cause_code;
10511 int data_size = sizeof(*cause_code);
10512 char subclass[40] = "";
10513
10514 /* get subclass text */
10515 iax_frame_subclass2str(fh->csub, subclass, sizeof(subclass));
10516
10517 /* add length of "IAX2 " */
10518 data_size += 5;
10519 /* for IAX hangup frames, add length of () and number */
10520 data_size += 3;
10521 if (ies.causecode > 9) {
10522 data_size++;
10523 }
10524 if (ies.causecode > 99) {
10525 data_size++;
10526 }
10527 /* add length of subclass */
10528 data_size += strlen(subclass);
10529
10530 cause_code = ast_alloca(data_size);
10531 memset(cause_code, 0, data_size);
10533
10534 cause_code->ast_cause = ies.causecode;
10535 snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "IAX2 %s(%d)", subclass, ies.causecode);
10536
10538 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10539 ast_queue_control_data(iaxs[fr->callno]->owner, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
10540 ast_channel_hangupcause_hash_set(iaxs[fr->callno]->owner, cause_code, data_size);
10542 }
10543 if (!iaxs[fr->callno]) {
10544 ast_variables_destroy(ies.vars);
10546 return 1;
10547 }
10548 }
10549
10550 /* count this frame */
10551 iaxs[fr->callno]->frames_received++;
10552
10553 if (!ast_sockaddr_cmp(&addr, &iaxs[fr->callno]->addr) && !minivid &&
10554 f.subclass.integer != IAX_COMMAND_TXCNT && /* for attended transfer */
10555 f.subclass.integer != IAX_COMMAND_TXACC) { /* for attended transfer */
10556 unsigned short new_peercallno;
10557
10558 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10559 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10560 if (iaxs[fr->callno]->peercallno) {
10562 }
10563 iaxs[fr->callno]->peercallno = new_peercallno;
10565 }
10566 }
10567 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10568 if (iaxdebug)
10569 ast_debug(1, "Received packet %d, (%u, %d)\n", fh->oseqno, f.frametype, f.subclass.integer);
10570 /* Check if it's out of order (and not an ACK or INVAL) */
10571 fr->oseqno = fh->oseqno;
10572 fr->iseqno = fh->iseqno;
10573 fr->ts = ntohl(fh->ts);
10574#ifdef IAXTESTS
10575 if (test_resync) {
10576 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10577 fr->ts += test_resync;
10578 }
10579#endif /* IAXTESTS */
10580#if 0
10581 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10582 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10583 (f.subclass == IAX_COMMAND_NEW ||
10586 f.subclass == IAX_COMMAND_REJECT)) ) )
10587#endif
10588 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10589 updatehistory = 0;
10590 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10591 (iaxs[fr->callno]->iseqno ||
10593 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */
10594 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */
10595 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
10597 (f.frametype != AST_FRAME_IAX))) {
10598 if (
10602 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */
10603 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */
10604 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
10607 (f.frametype != AST_FRAME_IAX)) {
10608 /* If it's not an ACK packet, it's out of order. */
10609 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %u, subclass = %d)\n",
10610 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10611 /* Check to see if we need to request retransmission,
10612 * and take sequence number wraparound into account */
10613 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10614 /* If we've already seen it, ack it XXX There's a border condition here XXX */
10615 if ((f.frametype != AST_FRAME_IAX) ||
10617 ast_debug(1, "Acking anyway\n");
10618 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
10619 we have anything to send, we'll retransmit and get an ACK back anyway XXX */
10621 }
10622 } else {
10623 /* Send a VNAK requesting retransmission */
10624 iax2_vnak(fr->callno);
10625 }
10626 ast_variables_destroy(ies.vars);
10628 return 1;
10629 }
10630 } else {
10631 /* Increment unless it's an ACK or VNAK */
10632 if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10637 (f.frametype != AST_FRAME_IAX))
10638 iaxs[fr->callno]->iseqno++;
10639 }
10640 /* Ensure text frames are NULL-terminated */
10641 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10642 if (res < thread->buf_size)
10643 thread->buf[res++] = '\0';
10644 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
10645 thread->buf[res - 1] = '\0';
10646 }
10647
10648 /* Handle implicit ACKing unless this is an INVAL, and only if this is
10649 from the real peer, not the transfer peer */
10650 if (!ast_sockaddr_cmp(&addr, &iaxs[fr->callno]->addr) &&
10652 (f.frametype != AST_FRAME_IAX))) {
10653 unsigned char x;
10654 int call_to_destroy;
10655 /* First we have to qualify that the ACKed value is within our window */
10656 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10657 x = fr->iseqno;
10658 else
10659 x = iaxs[fr->callno]->oseqno;
10660 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10661 /* The acknowledgement is within our window. Time to acknowledge everything
10662 that it says to */
10663 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10664 /* Ack the packet with the given timestamp */
10665 if (iaxdebug)
10666 ast_debug(1, "Cancelling transmission of packet %d\n", x);
10667 call_to_destroy = 0;
10668 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10669 /* If it's our call, and our timestamp, mark -1 retries */
10670 if (x == cur->oseqno) {
10671 cur->retries = -1;
10672 /* Destroy call if this is the end */
10673 if (cur->final)
10674 call_to_destroy = fr->callno;
10675 }
10676 }
10677 if (call_to_destroy) {
10678 if (iaxdebug)
10679 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10680 ast_mutex_lock(&iaxsl[call_to_destroy]);
10681 iax2_destroy(call_to_destroy);
10682 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10683 }
10684 }
10685 /* Note how much we've received acknowledgement for */
10686 if (iaxs[fr->callno])
10687 iaxs[fr->callno]->rseqno = fr->iseqno;
10688 else {
10689 /* Stop processing now */
10690 ast_variables_destroy(ies.vars);
10692 return 1;
10693 }
10694 } else {
10695 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10696 }
10697 }
10698 if (ast_sockaddr_cmp(&addr, &iaxs[fr->callno]->addr) &&
10699 ((f.frametype != AST_FRAME_IAX) ||
10702 /* Only messages we accept from a transfer host are TXACC and TXCNT */
10703 ast_variables_destroy(ies.vars);
10705 return 1;
10706 }
10707
10708 /* when we receive the first full frame for a new incoming channel,
10709 it is safe to start the PBX on the channel because we have now
10710 completed a 3-way handshake with the peer */
10711 if ((f.frametype == AST_FRAME_VOICE) ||
10712 (f.frametype == AST_FRAME_VIDEO) ||
10713 (f.frametype == AST_FRAME_IAX)) {
10719 ast_variables_destroy(ies.vars);
10721 return 1;
10722 }
10723 }
10724
10725 if (ies.vars) {
10726 struct ast_datastore *variablestore = NULL;
10727 struct ast_variable *var, *prev = NULL;
10728 AST_LIST_HEAD(, ast_var_t) *varlist;
10729
10731 if (!iaxs[fr->callno]) {
10732 ast_variables_destroy(ies.vars);
10734 return 1;
10735 }
10736 if ((c = iaxs[fr->callno]->owner)) {
10737 varlist = ast_calloc(1, sizeof(*varlist));
10739
10740 if (variablestore && varlist) {
10741 variablestore->data = varlist;
10742 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10743 AST_LIST_HEAD_INIT(varlist);
10744 ast_debug(1, "I can haz IAX vars?\n");
10745 for (var = ies.vars; var; var = var->next) {
10746 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10747 if (prev) {
10748 ast_free(prev);
10749 }
10750 prev = var;
10751 if (!newvar) {
10752 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
10753 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10754 } else {
10755 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10756 }
10757 }
10758 if (prev) {
10759 ast_free(prev);
10760 }
10761 ies.vars = NULL;
10762 ast_channel_datastore_add(c, variablestore);
10763 } else {
10764 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10765 if (variablestore) {
10766 ast_datastore_free(variablestore);
10767 }
10768 if (varlist) {
10769 ast_free(varlist);
10770 }
10771 }
10773 } else {
10774 /* No channel yet, so transfer the variables directly over to the pvt,
10775 * for later inheritance. */
10776 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10777 for (var = ies.vars; var && var->next; var = var->next);
10778 if (var) {
10779 var->next = iaxs[fr->callno]->iaxvars;
10780 iaxs[fr->callno]->iaxvars = ies.vars;
10781 ies.vars = NULL;
10782 }
10783 }
10784 }
10785
10786 if (ies.vars) {
10787 ast_debug(1, "I have IAX variables, but they were not processed\n");
10788 }
10789 }
10790
10791 /* once we receive our first IAX Full Frame that is not CallToken related, send all
10792 * queued signaling frames that were being held. */
10795 }
10796
10797 if (f.frametype == AST_FRAME_VOICE) {
10800 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_format_get_name(f.subclass.format));
10801 if (iaxs[fr->callno]->owner) {
10803 if (iaxs[fr->callno]) {
10804 if (iaxs[fr->callno]->owner) {
10806 if (native) {
10811 }
10812 ao2_ref(native, -1);
10813 }
10815 }
10816 } else {
10817 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10818 /* Free remote variables (if any) */
10819 if (ies.vars) {
10820 ast_variables_destroy(ies.vars);
10821 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
10822 ies.vars = NULL;
10823 }
10825 return 1;
10826 }
10827 }
10828 }
10829 }
10830 if (f.frametype == AST_FRAME_VIDEO) {
10832 ast_debug(1, "Ooh, video format changed to %s\n", ast_format_get_name(f.subclass.format));
10834 }
10835 }
10836 if (f.frametype == AST_FRAME_IAX) {
10838 /* Handle the IAX pseudo frame itself */
10839 if (iaxdebug)
10840 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10841
10842 /* Update last ts unless the frame's timestamp originated with us. */
10843 if (iaxs[fr->callno]->last < fr->ts &&
10847 iaxs[fr->callno]->last = fr->ts;
10848 if (iaxdebug)
10849 ast_debug(1, "For call=%d, set last=%u\n", fr->callno, fr->ts);
10850 }
10852 if (!iaxs[fr->callno]->first_iax_message) {
10854 }
10855 switch(f.subclass.integer) {
10856 case IAX_COMMAND_ACK:
10857 /* Do nothing */
10858 break;
10859 case IAX_COMMAND_QUELCH:
10862 if (ies.musiconhold) {
10863 const char *moh_suggest;
10864
10866 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10867 break;
10868 }
10869
10870 /*
10871 * We already hold the owner lock so we do not
10872 * need to check iaxs[fr->callno] after it returns.
10873 */
10874 moh_suggest = iaxs[fr->callno]->mohsuggest;
10875 iax2_queue_hold(fr->callno, moh_suggest);
10877 }
10878 }
10879 break;
10883 if (!iaxs[fr->callno]) {
10884 break;
10885 }
10886
10888 if (!iaxs[fr->callno]->owner) {
10889 break;
10890 }
10891
10892 /*
10893 * We already hold the owner lock so we do not
10894 * need to check iaxs[fr->callno] after it returns.
10895 */
10898 }
10899 break;
10900 case IAX_COMMAND_TXACC:
10901 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10902 /* Ack the packet with the given timestamp */
10903 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10904 /* Cancel any outstanding txcnt's */
10905 if (cur->transfer) {
10906 cur->retries = -1;
10907 }
10908 }
10909 memset(&ied1, 0, sizeof(ied1));
10911 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10913 }
10914 break;
10915 case IAX_COMMAND_NEW:
10916 /* Ignore if it's already up */
10918 break;
10919 if (ies.provverpres && ies.serviceident && !(ast_sockaddr_isnull(&addr))) {
10921 check_provisioning(&addr, fd, ies.serviceident, ies.provver);
10923 if (!iaxs[fr->callno]) {
10924 break;
10925 }
10926 }
10927 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
10928 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10929 int new_callno;
10930 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10931 fr->callno = new_callno;
10932 }
10933 /* For security, always ack immediately */
10934 if (delayreject)
10936 if (check_access(fr->callno, &addr, &ies)) {
10937 /* They're not allowed on */
10939 if (authdebug) {
10940 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n",
10942 }
10943 break;
10944 }
10947 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10948 break;
10949 }
10950 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10951 const char *context, *exten, *cid_num;
10952
10954 exten = ast_strdupa(iaxs[fr->callno]->exten);
10955 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10956
10957 /* This might re-enter the IAX code and need the lock */
10959 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10961
10962 if (!iaxs[fr->callno]) {
10963 break;
10964 }
10965 } else
10966 exists = 0;
10967 /* Get OSP token if it does exist */
10968 save_osptoken(fr, &ies);
10970 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10971 memset(&ied0, 0, sizeof(ied0));
10972 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10974 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10975 if (!iaxs[fr->callno]) {
10976 break;
10977 }
10978 if (authdebug) {
10979 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n",
10981 }
10982 } else {
10983 /* Select an appropriate format */
10984
10987 using_prefs = "reqonly";
10988 } else {
10989 using_prefs = "disabled";
10990 }
10991 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10992 memset(&pref, 0, sizeof(pref));
10993 strcpy(caller_pref_buf, "disabled");
10994 strcpy(host_pref_buf, "disabled");
10995 } else {
10996 struct ast_format *tmpfmt;
10997 using_prefs = "mine";
10998 /* If the information elements are in here... use them */
10999 if (ies.codec_prefs)
11000 iax2_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11001 if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11002 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
11004 pref = iaxs[fr->callno]->rprefs;
11005 using_prefs = "caller";
11006 } else {
11007 pref = iaxs[fr->callno]->prefs;
11008 }
11009 } else
11010 pref = iaxs[fr->callno]->prefs;
11011
11012 format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability);
11013 iax2_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11014 iax2_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11015 }
11016 if (!format) {
11018 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11019 if (!format) {
11020 memset(&ied0, 0, sizeof(ied0));
11021 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11023 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11024 if (!iaxs[fr->callno]) {
11025 break;
11026 }
11027 if (authdebug) {
11030 struct ast_str *peer_form_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11031
11033 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11035 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11037 } else {
11038 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11040 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11043 }
11044 }
11045 } else {
11046 /* Pick one... */
11048 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11049 format = 0;
11050 } else {
11052 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11053 memset(&pref, 0, sizeof(pref));
11055 strcpy(caller_pref_buf,"disabled");
11056 strcpy(host_pref_buf,"disabled");
11057 } else {
11058 struct ast_format *tmpfmt;
11059 using_prefs = "mine";
11060 if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11061 /* Do the opposite of what we tried above. */
11063 pref = iaxs[fr->callno]->prefs;
11064 } else {
11065 pref = iaxs[fr->callno]->rprefs;
11066 using_prefs = "caller";
11067 }
11068 format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11069 } else /* if no codec_prefs IE do it the old way */
11071 }
11072 }
11073
11074 if (!format) {
11077 struct ast_str *peer_form_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11078
11079 memset(&ied0, 0, sizeof(ied0));
11080 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11082 ast_log(LOG_ERROR, "No best format in '%s'???\n", iax2_getformatname_multiple(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, &cap_buf));
11083 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11084 if (!iaxs[fr->callno]) {
11085 break;
11086 }
11087 if (authdebug) {
11088 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11090 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11093 }
11095 break;
11096 }
11097 }
11098 }
11099 if (format) {
11100 /* No authentication required, let them in */
11101 memset(&ied1, 0, sizeof(ied1));
11102 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11104 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11105 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11107 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
11108 "%srequested format = %s,\n"
11109 "%srequested prefs = %s,\n"
11110 "%sactual format = %s,\n"
11111 "%shost prefs = %s,\n"
11112 "%spriority = %s\n",
11117 caller_pref_buf,
11119 iax2_getformatname(format),
11121 host_pref_buf,
11123 using_prefs);
11124
11125 iaxs[fr->callno]->chosenformat = format;
11126
11127 /* Since this is a new call, we should go ahead and set the callid for it. */
11130 } else {
11132 /* If this is a TBD call, we're ready but now what... */
11133 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_sockaddr_stringify(&addr));
11134 }
11135 }
11136 }
11137 break;
11138 }
11141 else
11142 iaxs[fr->callno]->encmethods = 0;
11143 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
11145 break;
11146 case IAX_COMMAND_DPREQ:
11147 /* Request status in the dialplan */
11149 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
11150 if (iaxcompat) {
11151 /* Spawn a thread for the lookup */
11152 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
11153 } else {
11154 /* Just look it up */
11155 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
11156 }
11157 }
11158 break;
11159 case IAX_COMMAND_HANGUP:
11161 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
11162 /* Set hangup cause according to remote and hangupsource */
11163 if (iaxs[fr->callno]->owner) {
11164 set_hangup_source_and_cause(fr->callno, ies.causecode);
11165 if (!iaxs[fr->callno]) {
11166 break;
11167 }
11168 }
11169
11170 /* Send ack immediately, before we destroy */
11172 iax2_destroy(fr->callno);
11173 break;
11174 case IAX_COMMAND_REJECT:
11175 /* Set hangup cause according to remote and hangup source */
11176 if (iaxs[fr->callno]->owner) {
11177 set_hangup_source_and_cause(fr->callno, ies.causecode);
11178 if (!iaxs[fr->callno]) {
11179 break;
11180 }
11181 }
11182
11184 if (iaxs[fr->callno]->owner && authdebug)
11185 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
11187 ies.cause ? ies.cause : "<Unknown>");
11188 ast_debug(1, "Immediately destroying %d, having received reject\n",
11189 fr->callno);
11190 }
11191 /* Send ack immediately, before we destroy */
11193 fr->ts, NULL, 0, fr->iseqno);
11195 iaxs[fr->callno]->error = EPERM;
11196 iax2_destroy(fr->callno);
11197 break;
11199 {
11201 if (!iaxs[fr->callno]) {
11202 /* Initiating call went away before we could transfer. */
11203 break;
11204 }
11205 if (iaxs[fr->callno]->owner) {
11206 struct ast_channel *owner = iaxs[fr->callno]->owner;
11207 char *context = ast_strdupa(iaxs[fr->callno]->context);
11208
11209 ast_channel_ref(owner);
11210 ast_channel_unlock(owner);
11212
11213 if (ast_bridge_transfer_blind(1, owner, ies.called_number,
11215 ast_log(LOG_WARNING, "Blind transfer of '%s' to '%s@%s' failed\n",
11216 ast_channel_name(owner), ies.called_number,
11217 context);
11218 }
11219
11220 ast_channel_unref(owner);
11222 }
11223
11224 break;
11225 }
11226 case IAX_COMMAND_ACCEPT:
11227 /* Ignore if call is already up or needs authentication or is a TBD */
11229 break;
11231 /* Send ack immediately, before we destroy */
11233 iax2_destroy(fr->callno);
11234 break;
11235 }
11236 if (ies.format) {
11237 iaxs[fr->callno]->peerformat = ies.format;
11238 } else {
11239 if (iaxs[fr->callno]->owner)
11241 else
11243 }
11244 ast_verb(3, "Call accepted by %s (format %s)\n", ast_sockaddr_stringify(&addr),
11246 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
11247 memset(&ied0, 0, sizeof(ied0));
11248 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11250 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11251 if (!iaxs[fr->callno]) {
11252 break;
11253 }
11254 if (authdebug) {
11257
11258 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
11262 }
11263 } else {
11265
11268 if (iaxs[fr->callno] && iaxs[fr->callno]->owner && native) {
11270
11271 /* Switch us to use a compatible format */
11273 iaxs[fr->callno]->peerformat, &iaxs[fr->callno]->rprefs,
11274 native);
11276 ast_verb(3, "Format for call is %s\n", ast_format_cap_get_names(ast_channel_nativeformats(iaxs[fr->callno]->owner), &cap_buf));
11277
11278 /* Setup read/write formats properly. */
11284 }
11285
11286 ao2_cleanup(native);
11287 }
11288 if (iaxs[fr->callno]) {
11290 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
11291 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
11292 iax2_dprequest(dp, fr->callno);
11294 }
11295 break;
11296 case IAX_COMMAND_POKE:
11297 /* Send back a pong packet with the original timestamp */
11299 break;
11300 case IAX_COMMAND_PING:
11301 {
11302 struct iax_ie_data pingied;
11303 construct_rr(iaxs[fr->callno], &pingied);
11304 /* Send back a pong packet with the original timestamp */
11305 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
11306 }
11307 break;
11308 case IAX_COMMAND_PONG:
11309 /* Calculate ping time */
11310 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
11311 /* save RR info */
11312 save_rr(fr, &ies);
11313
11314 /* Good time to write jb stats for this call */
11316
11317 if (iaxs[fr->callno]->peerpoke) {
11318 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
11319 peer = iaxs[fr->callno]->peerpoke;
11320 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
11321 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
11322 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %u\n", peer->name, iaxs[fr->callno]->pingtime);
11324 blob = ast_json_pack("{s: s, s: I}",
11325 "peer_status", "Reachable",
11326 "time", (ast_json_int_t)iaxs[fr->callno]->pingtime);
11327 ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
11328 }
11329 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
11330 if (iaxs[fr->callno]->pingtime > peer->maxms) {
11331 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%u ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
11333 blob = ast_json_pack("{s: s, s: I}",
11334 "peer_status", "Lagged",
11335 "time", (ast_json_int_t)iaxs[fr->callno]->pingtime);
11336 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
11337 }
11338 }
11340 peer->lastms = iaxs[fr->callno]->pingtime;
11341 if (peer->smoothing && (peer->lastms > -1))
11342 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
11343 else if (peer->smoothing && peer->lastms < 0)
11344 peer->historicms = (0 + peer->historicms) / 2;
11345 else
11346 peer->historicms = iaxs[fr->callno]->pingtime;
11347
11348 /* Remove scheduled iax2_poke_noanswer */
11349 if (peer->pokeexpire > -1) {
11350 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
11351 peer_unref(peer);
11352 peer->pokeexpire = -1;
11353 }
11354 }
11355 /* Schedule the next cycle */
11356 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
11358 else
11360 if (peer->pokeexpire == -1)
11361 peer_unref(peer);
11362 /* and finally send the ack */
11364 /* And wrap up the qualify call */
11365 iax2_destroy(fr->callno);
11366 peer->callno = 0;
11367 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
11368 }
11369 break;
11370 case IAX_COMMAND_LAGRQ:
11371 case IAX_COMMAND_LAGRP:
11372 f.src = "LAGRQ";
11373 f.mallocd = 0;
11374 f.offset = 0;
11375 f.samples = 0;
11376 iax_frame_wrap(fr, &f);
11378 /* Received a LAGRQ - echo back a LAGRP */
11380 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
11381 } else {
11382 /* Received LAGRP in response to our LAGRQ */
11383 unsigned int ts;
11384 /* This is a reply we've been given, actually measure the difference */
11385 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
11386 iaxs[fr->callno]->lag = ts - fr->ts;
11387 if (iaxdebug)
11388 ast_debug(1, "Peer %s lag measured as %dms\n",
11389 ast_sockaddr_stringify(&addr), iaxs[fr->callno]->lag);
11390 }
11391 break;
11394 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>");
11395 break;
11396 }
11397 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
11398 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
11399 .subclass.integer = AST_CONTROL_HANGUP,
11400 };
11402 "I don't know how to authenticate %s to %s\n",
11403 ies.username ? ies.username : "<unknown>", ast_sockaddr_stringify(&addr));
11404 iax2_queue_frame(fr->callno, &hangup_fr);
11405 }
11406 break;
11408 /* For security, always ack immediately */
11409 if (delayreject)
11411 /* Ignore once we've started */
11413 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>");
11414 break;
11415 }
11416 if (authenticate_verify(iaxs[fr->callno], &ies)) {
11417 if (authdebug)
11418 ast_log(LOG_WARNING, "Host %s failed to authenticate as %s\n", ast_sockaddr_stringify(&addr),
11419 iaxs[fr->callno]->username);
11420 memset(&ied0, 0, sizeof(ied0));
11422 break;
11423 }
11424 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
11425 /* This might re-enter the IAX code and need the lock */
11427 } else
11428 exists = 0;
11429 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
11430 if (authdebug)
11431 ast_log(LOG_WARNING, "Rejected connect attempt from %s, request '%s@%s' does not exist\n",
11433 iaxs[fr->callno]->exten,
11434 iaxs[fr->callno]->context);
11435 memset(&ied0, 0, sizeof(ied0));
11436 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11438 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11439 if (!iaxs[fr->callno]) {
11440 break;
11441 }
11442 } else {
11443 /* Select an appropriate format */
11446 using_prefs = "reqonly";
11447 } else {
11448 using_prefs = "disabled";
11449 }
11450 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
11451 memset(&pref, 0, sizeof(pref));
11452 strcpy(caller_pref_buf, "disabled");
11453 strcpy(host_pref_buf, "disabled");
11454 } else {
11455 struct ast_format *tmpfmt;
11456 using_prefs = "mine";
11457 if (ies.codec_prefs)
11458 iax2_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11459 if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11461 pref = iaxs[fr->callno]->rprefs;
11462 using_prefs = "caller";
11463 } else {
11464 pref = iaxs[fr->callno]->prefs;
11465 }
11466 } else /* if no codec_prefs IE do it the old way */
11467 pref = iaxs[fr->callno]->prefs;
11468 format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability);
11469 iax2_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11470 iax2_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11471 }
11472 if (!format) {
11475 struct ast_str *peer_form_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11476
11478 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11481 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11482 }
11483 if (!format) {
11484 if (authdebug) {
11486 ast_log(LOG_WARNING, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11488 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11490 } else {
11491 ast_log(LOG_WARNING, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11493 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11496 }
11497 }
11498 memset(&ied0, 0, sizeof(ied0));
11499 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11501 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11502 if (!iaxs[fr->callno]) {
11503 break;
11504 }
11505 } else {
11506 /* Pick one... */
11508 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11509 format = 0;
11510 } else {
11512 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11513 memset(&pref, 0, sizeof(pref));
11515 ? iaxs[fr->callno]->peerformat
11517 strcpy(caller_pref_buf,"disabled");
11518 strcpy(host_pref_buf,"disabled");
11519 } else {
11520 struct ast_format *tmpfmt;
11521 using_prefs = "mine";
11522 if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11523 /* Do the opposite of what we tried above. */
11525 pref = iaxs[fr->callno]->prefs;
11526 } else {
11527 pref = iaxs[fr->callno]->rprefs;
11528 using_prefs = "caller";
11529 }
11530 format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11531 } else /* if no codec_prefs IE do it the old way */
11533 }
11534 }
11535 if (!format) {
11538 struct ast_str *peer_form_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11539
11540 ast_log(LOG_ERROR, "No best format in %s???\n",
11542 if (authdebug) {
11544 ast_log(LOG_WARNING, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11546 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11548 } else {
11549 ast_log(LOG_WARNING, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11551 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11554 }
11555 }
11556 memset(&ied0, 0, sizeof(ied0));
11557 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11559 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11560 if (!iaxs[fr->callno]) {
11561 break;
11562 }
11563 }
11564 }
11565 }
11566 if (format) {
11567 /* Authentication received */
11568 memset(&ied1, 0, sizeof(ied1));
11569 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11571 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11572 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11573 char authmethodnames[AUTH_METHOD_NAMES_BUFSIZE];
11575 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11576 "%srequested auth methods = (%s),\n"
11577 "%sactual auth method = %s,\n"
11578 "%sencrypted = %s,\n"
11579 "%srequested format = %s,\n"
11580 "%srequested prefs = %s,\n"
11581 "%sactual format = %s,\n"
11582 "%shost prefs = %s,\n"
11583 "%spriority = %s\n",
11586 auth_method_names(iaxs[fr->callno]->authmethods, authmethodnames),
11590 IAX_CALLENCRYPTED(iaxs[fr->callno]) ? "yes" : "no",
11594 caller_pref_buf,
11596 iax2_getformatname(format),
11598 host_pref_buf,
11600 using_prefs);
11601
11602 /* Unlike unauthenticated calls, we don't need to store
11603 * the chosen format for channel creation.
11604 * However, this is helpful for __get_from_jb. */
11605 iaxs[fr->callno]->chosenformat = format;
11606
11608 c = ast_iax2_new(fr->callno, AST_STATE_RING, format,
11609 &iaxs[fr->callno]->rprefs, NULL, NULL, 1);
11610 if (!c) {
11611 iax2_destroy(fr->callno);
11612 } else if (ies.vars) {
11613 struct ast_datastore *variablestore;
11614 struct ast_variable *var, *prev = NULL;
11615 AST_LIST_HEAD(, ast_var_t) *varlist;
11616 varlist = ast_calloc(1, sizeof(*varlist));
11618 if (variablestore && varlist) {
11619 variablestore->data = varlist;
11620 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11621 AST_LIST_HEAD_INIT(varlist);
11622 ast_debug(1, "I can haz IAX vars? w00t\n");
11623 for (var = ies.vars; var; var = var->next) {
11624 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11625 if (prev)
11626 ast_free(prev);
11627 prev = var;
11628 if (!newvar) {
11629 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11630 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11631 } else {
11632 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11633 }
11634 }
11635 if (prev)
11636 ast_free(prev);
11637 ies.vars = NULL;
11638 ast_channel_datastore_add(c, variablestore);
11639 } else {
11640 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11641 if (variablestore)
11642 ast_datastore_free(variablestore);
11643 if (varlist)
11644 ast_free(varlist);
11645 }
11646 }
11647 } else {
11649 /* If this is a TBD call, we're ready but now what... */
11650 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_sockaddr_stringify(&addr));
11652 goto immediatedial;
11653 }
11654 }
11655 }
11656 }
11657 break;
11658 case IAX_COMMAND_DIAL:
11659immediatedial:
11662 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11663 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11664 if (authdebug)
11665 ast_log(LOG_WARNING, "Rejected dial attempt from %s, request '%s@%s' does not exist\n",
11667 iaxs[fr->callno]->exten,
11668 iaxs[fr->callno]->context);
11669 memset(&ied0, 0, sizeof(ied0));
11670 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11672 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11673 if (!iaxs[fr->callno]) {
11674 break;
11675 }
11676 } else {
11679 ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11685 iaxs[fr->callno]->peerformat, &iaxs[fr->callno]->rprefs,
11686 NULL, NULL, 1);
11687 if (!c) {
11688 iax2_destroy(fr->callno);
11689 } else if (ies.vars) {
11690 struct ast_datastore *variablestore;
11691 struct ast_variable *var, *prev = NULL;
11692 AST_LIST_HEAD(, ast_var_t) *varlist;
11693 varlist = ast_calloc(1, sizeof(*varlist));
11695 ast_debug(1, "I can haz IAX vars? w00t\n");
11696 if (variablestore && varlist) {
11697 variablestore->data = varlist;
11698 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11699 AST_LIST_HEAD_INIT(varlist);
11700 for (var = ies.vars; var; var = var->next) {
11701 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11702 if (prev)
11703 ast_free(prev);
11704 prev = var;
11705 if (!newvar) {
11706 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11707 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11708 } else {
11709 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11710 }
11711 }
11712 if (prev)
11713 ast_free(prev);
11714 ies.vars = NULL;
11715 ast_channel_datastore_add(c, variablestore);
11716 } else {
11717 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11718 if (variablestore)
11719 ast_datastore_free(variablestore);
11720 if (varlist)
11721 ast_free(varlist);
11722 }
11723 }
11724 }
11725 }
11726 break;
11727 case IAX_COMMAND_INVAL:
11728 iaxs[fr->callno]->error = ENOTCONN;
11729 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11730 iax2_destroy(fr->callno);
11731 ast_debug(1, "Destroying call %d\n", fr->callno);
11732 break;
11733 case IAX_COMMAND_VNAK:
11734 ast_debug(1, "Received VNAK: resending outstanding frames\n");
11735 /* Force retransmission */
11736 vnak_retransmit(fr->callno, fr->iseqno);
11737 break;
11738 case IAX_COMMAND_REGREQ:
11739 case IAX_COMMAND_REGREL:
11740 /* For security, always ack immediately */
11741 if (delayreject)
11743 if (register_verify(fr->callno, &addr, &ies)) {
11744 if (!iaxs[fr->callno]) {
11745 break;
11746 }
11747 /* Send delayed failure */
11749 break;
11750 }
11751 if (!iaxs[fr->callno]) {
11752 break;
11753 }
11756
11758 ast_sockaddr_setnull(&addr);
11759 }
11760 if (update_registry(&addr, fr->callno, ies.devicetype, fd, ies.refresh)) {
11761 ast_log(LOG_WARNING, "Registry error\n");
11762 }
11763 if (!iaxs[fr->callno]) {
11764 break;
11765 }
11766 if (ies.provverpres && ies.serviceident && !(ast_sockaddr_isnull(&addr))) {
11768 check_provisioning(&addr, fd, ies.serviceident, ies.provver);
11770 }
11771 break;
11772 }
11774 break;
11775 case IAX_COMMAND_REGACK:
11776 if (iax2_ack_registry(&ies, &addr, fr->callno)) {
11777 ast_log(LOG_WARNING, "Registration failure\n");
11778 }
11779 /* Send ack immediately, before we destroy */
11781 iax2_destroy(fr->callno);
11782 break;
11783 case IAX_COMMAND_REGREJ:
11784 if (iaxs[fr->callno]->reg) {
11785 if (authdebug) {
11786 ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n",
11787 iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>",
11788 ast_sockaddr_stringify(&addr));
11789 }
11790 iax2_publish_registry(iaxs[fr->callno]->reg->username, ast_sockaddr_stringify(&addr), "Rejected", S_OR(ies.cause, "<unknown>"));
11792 }
11793 /* Send ack immediately, before we destroy */
11795 iax2_destroy(fr->callno);
11796 break;
11798 /* Authentication request */
11799 if (registry_rerequest(&ies, fr->callno, &addr)) {
11800 memset(&ied0, 0, sizeof(ied0));
11801 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11803 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11804 }
11805 break;
11806 case IAX_COMMAND_TXREJ:
11807 while (iaxs[fr->callno]
11808 && iaxs[fr->callno]->bridgecallno
11811 }
11812 if (!iaxs[fr->callno]) {
11813 break;
11814 }
11815
11817 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11818 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11819
11820 if (!iaxs[fr->callno]->bridgecallno) {
11821 break;
11822 }
11823
11824 if (iaxs[iaxs[fr->callno]->bridgecallno]
11828 }
11830 break;
11832 while (iaxs[fr->callno]
11833 && iaxs[fr->callno]->bridgecallno
11836 }
11837 if (!iaxs[fr->callno]) {
11838 break;
11839 }
11840
11841 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
11843 } else if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) {
11845 } else {
11846 if (iaxs[fr->callno]->bridgecallno) {
11848 }
11849 break;
11850 }
11851 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11852
11853 if (!iaxs[fr->callno]->bridgecallno) {
11854 break;
11855 }
11856
11857 if (!iaxs[iaxs[fr->callno]->bridgecallno]
11861 break;
11862 }
11863
11864 /* Both sides are ready */
11865
11866 /* XXX what isn't checked here is that both sides match transfer types. */
11867
11868 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11869 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
11871
11874
11875 memset(&ied0, 0, sizeof(ied0));
11876 memset(&ied1, 0, sizeof(ied1));
11879 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11880 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11881 } else {
11882 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
11884
11889
11890 /* Stop doing lag & ping requests */
11891 stop_stuff(fr->callno);
11893
11894 memset(&ied0, 0, sizeof(ied0));
11895 memset(&ied1, 0, sizeof(ied1));
11898 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11899 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11900 }
11902 break;
11903 case IAX_COMMAND_TXREQ:
11904 try_transfer(iaxs[fr->callno], &ies);
11905 break;
11906 case IAX_COMMAND_TXCNT:
11907 if (iaxs[fr->callno]->transferring)
11909 break;
11910 case IAX_COMMAND_TXREL:
11911 /* Send ack immediately, rather than waiting until we've changed addresses */
11913 complete_transfer(fr->callno, &ies);
11914 stop_stuff(fr->callno); /* for attended transfer to work with libiax */
11915 break;
11917 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11918 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11919 /* Cancel any outstanding frames and start anew */
11920 if (cur->transfer) {
11921 cur->retries = -1;
11922 }
11923 }
11924 /* Start sending our media to the transfer address, but otherwise leave the call as-is */
11926 }
11927 break;
11928 case IAX_COMMAND_RTKEY:
11929 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11931 "we've been told to rotate our encryption key, "
11932 "but this isn't an encrypted call. bad things will happen.\n"
11933 );
11934 break;
11935 }
11936
11937 IAX_DEBUGDIGEST("Receiving", ies.challenge);
11938
11939 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11940 break;
11941 case IAX_COMMAND_DPREP:
11942 complete_dpreply(iaxs[fr->callno], &ies);
11943 break;
11945 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11946 break;
11948 /* Firmware download */
11951 break;
11952 }
11953 memset(&ied0, 0, sizeof(ied0));
11954 res = iax_firmware_append(&ied0, ies.devicetype, ies.fwdesc);
11955 if (res < 0)
11956 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11957 else if (res > 0)
11958 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11959 else
11960 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11961 break;
11963 {
11964 struct iax_frame *cur;
11965 /* find last sent frame */
11966 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11967 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11968 }
11969 break;
11970 }
11971 default:
11972 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11973 memset(&ied0, 0, sizeof(ied0));
11975 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11976 }
11977 /* Free remote variables (if any) */
11978 if (ies.vars) {
11979 ast_variables_destroy(ies.vars);
11980 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11981 ies.vars = NULL;
11982 }
11983
11984 /* Don't actually pass these frames along */
11985 if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11990 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) {
11992 }
11993 }
11995 return 1;
11996 }
11997 /* Unless this is an ACK or INVAL frame, ack it */
11998 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
12000 } else if (minivid) {
12002 if (iaxs[fr->callno]->videoformat > 0) {
12003 if (ntohs(vh->ts) & 0x8000LL) {
12004 f.subclass.frame_ending = 1;
12005 }
12007 if (!f.subclass.format) {
12008 ast_variables_destroy(ies.vars);
12010 return 1;
12011 }
12012 } else {
12013 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
12014 iax2_vnak(fr->callno);
12015 ast_variables_destroy(ies.vars);
12017 return 1;
12018 }
12019 f.datalen = res - sizeof(*vh);
12020 if (f.datalen)
12021 f.data.ptr = thread->buf + sizeof(*vh);
12022 else
12023 f.data.ptr = NULL;
12024#ifdef IAXTESTS
12025 if (test_resync) {
12026 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
12027 } else
12028#endif /* IAXTESTS */
12029 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
12030 } else {
12031 /* A mini frame */
12033 if (iaxs[fr->callno]->voiceformat > 0) {
12035 if (!f.subclass.format) {
12036 ast_variables_destroy(ies.vars);
12038 return 1;
12039 }
12040 } else {
12041 ast_debug(1, "Received mini frame before first full voice frame\n");
12042 iax2_vnak(fr->callno);
12043 ast_variables_destroy(ies.vars);
12045 return 1;
12046 }
12047 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
12048 if (f.datalen < 0) {
12049 ast_log(LOG_WARNING, "Datalen < 0?\n");
12050 ast_variables_destroy(ies.vars);
12052 return 1;
12053 }
12054 if (f.datalen)
12055 f.data.ptr = thread->buf + sizeof(*mh);
12056 else
12057 f.data.ptr = NULL;
12058#ifdef IAXTESTS
12059 if (test_resync) {
12060 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
12061 } else
12062#endif /* IAXTESTS */
12063 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
12064 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
12065 }
12066
12067 /* Don't pass any packets until we're started */
12068 if (!iaxs[fr->callno]
12070 ast_variables_destroy(ies.vars);
12072 return 1;
12073 }
12074
12075 if (f.frametype == AST_FRAME_CONTROL) {
12077 /* Control frame not allowed to come from the wire. */
12078 ast_debug(2, "Callno %d: Blocked receiving control frame %d.\n",
12079 fr->callno, f.subclass.integer);
12080 ast_variables_destroy(ies.vars);
12082 return 1;
12083 }
12086 if (iaxs[fr->callno]
12088 /* We are not configured to allow receiving these updates. */
12089 ast_debug(2, "Callno %d: Config blocked receiving control frame %d.\n",
12090 fr->callno, f.subclass.integer);
12091 ast_variables_destroy(ies.vars);
12093 return 1;
12094 }
12095 }
12096
12098 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
12101 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
12103 }
12105 }
12106 }
12107
12110 && iaxs[fr->callno]) {
12112
12113 /*
12114 * Process a received connected line update.
12115 *
12116 * Initialize defaults.
12117 */
12119 connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
12120 connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
12121
12123 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
12124 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
12126
12128 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
12130 S_COR(connected.id.number.valid, connected.id.number.str, ""),
12131 S_COR(connected.id.name.valid, connected.id.name.str, ""),
12132 NULL);
12133 ast_channel_caller(iaxs[fr->callno]->owner)->id.number.presentation = connected.id.number.presentation;
12134 ast_channel_caller(iaxs[fr->callno]->owner)->id.name.presentation = connected.id.name.presentation;
12136 }
12137 }
12139 }
12140
12141 /* Common things */
12142 f.src = "IAX2";
12143 f.mallocd = 0;
12144 f.offset = 0;
12145 f.len = 0;
12146 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
12148 /* We need to byteswap incoming slinear samples from network byte order */
12151 } else
12152 f.samples = 0;
12153 iax_frame_wrap(fr, &f);
12154
12155 /* If this is our most recent packet, use it as our basis for timestamping */
12156 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
12157 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
12158 fr->outoforder = 0;
12159 } else {
12160 if (iaxdebug && iaxs[fr->callno]) {
12161 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);
12162 }
12163 fr->outoforder = 1;
12164 }
12166 if (iaxs[fr->callno]) {
12167 duped_fr = iaxfrdup2(fr);
12168 if (duped_fr) {
12169 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
12170 }
12171 }
12172 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
12173 iaxs[fr->callno]->last = fr->ts;
12174#if 1
12175 if (iaxdebug)
12176 ast_debug(8, "For call=%d, set last=%u\n", fr->callno, fr->ts);
12177#endif
12178 }
12179
12180 /* Always run again */
12181 ast_variables_destroy(ies.vars);
12183 return 1;
12184}
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:4494
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1104
#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:7927
static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
Definition: chan_iax2.c:9810
static int update_registry(struct ast_sockaddr *addr, int callno, char *devtype, int fd, unsigned short refresh)
Definition: chan_iax2.c:9184
#define AUTH_METHOD_NAMES_BUFSIZE
Definition: chan_iax2.c:431
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:10033
static int iax2_queue_hold(int callno, const char *musicclass)
Queue a hold frame on the ast_channel owner.
Definition: chan_iax2.c:3349
static int check_provisioning(struct ast_sockaddr *addr, int sockfd, char *si, unsigned int ver)
Definition: chan_iax2.c:9781
static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int)
Definition: chan_iax2.c:7911
static int auth_fail(int callno, int failcode)
Definition: chan_iax2.c:9498
static const char * auth_method_labels[]
Name of effective auth method.
Definition: chan_iax2.c:423
static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
Definition: chan_iax2.c:4908
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:5030
static void vnak_retransmit(int callno, int last)
Definition: chan_iax2.c:9560
static int registry_rerequest(struct iax_ies *ies, int callno, struct ast_sockaddr *addr)
Definition: chan_iax2.c:9410
static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
Definition: chan_iax2.c:9794
static int complete_transfer(int callno, struct iax_ies *ies)
Definition: chan_iax2.c:8831
static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
Definition: chan_iax2.c:4316
static void iax_pvt_callid_new(int callno)
Definition: chan_iax2.c:1210
static int iax2_queue_unhold(int callno)
Queue an unhold frame on the ast_channel owner.
Definition: chan_iax2.c:3372
static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
Definition: chan_iax2.c:8750
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:8583
static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
Definition: chan_iax2.c:8784
static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
Definition: chan_iax2.c:9763
static struct iax_frame * iaxfrdup2(struct iax_frame *fr)
Definition: chan_iax2.c:2359
static void set_hangup_source_and_cause(int callno, unsigned char causecode)
Definition: chan_iax2.c:10244
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:2231
static int authenticate_request(int call_num)
Definition: chan_iax2.c:8197
static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
Definition: chan_iax2.c:9821
static iax2_format iax2_codec_choose(struct iax2_codec_pref *pref, iax2_format formats)
Definition: chan_iax2.c:1954
static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
Definition: chan_iax2.c:6655
static char * auth_method_names(int authmethods, char *restrict buf)
Get names of all auth methods.
Definition: chan_iax2.c:439
static int raw_hangup(struct ast_sockaddr *addr, unsigned short src, unsigned short dst, int sockfd)
Definition: chan_iax2.c:8160
static int iax2_ack_registry(struct iax_ies *ies, struct ast_sockaddr *addr, int callno)
Acknowledgment received for OUR registration.
Definition: chan_iax2.c:8898
static int iax2_vnak(int callno)
Definition: chan_iax2.c:9555
static int registry_authrequest(int callno)
Definition: chan_iax2.c:9362
#define IAX_DELAYPBXSTART
Definition: chan_iax2.c:546
static void stop_stuff(int callno)
Definition: chan_iax2.c:9459
static void log_jitterstats(unsigned short callno)
Definition: chan_iax2.c:9851
static ast_callid iax_pvt_callid_get(int callno)
Definition: chan_iax2.c:1200
static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
Definition: chan_iax2.c:8248
static int register_verify(int callno, struct ast_sockaddr *addr, struct iax_ies *ies)
Verify inbound registration.
Definition: chan_iax2.c:8343
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2039
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:7307
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5721
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:8790
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:4304
#define AST_CHANNEL_NAME
Definition: channel.h:173
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:5762
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:1989
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:185
@ 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:2295
#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:458
int frames_received
Definition: chan_iax2.c:954
const ast_string_field outkey
Definition: chan_iax2.c:886
const ast_string_field mohsuggest
Definition: chan_iax2.c:886
unsigned short bridgecallno
Definition: chan_iax2.c:929
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 10033 of file chan_iax2.c.

10035{
10036 unsigned char metatype;
10037 struct ast_iax2_meta_trunk_mini *mtm;
10038 struct ast_iax2_meta_trunk_hdr *mth;
10039 struct ast_iax2_meta_trunk_entry *mte;
10040 struct iax2_trunk_peer *tpeer;
10041 unsigned int ts;
10042 void *ptr;
10043 struct timeval rxtrunktime;
10044 struct ast_frame f = { 0, };
10045
10046 if (packet_len < sizeof(*meta)) {
10047 ast_log(LOG_WARNING, "Rejecting packet from '%s' that is flagged as a meta frame but is too short\n",
10049 return 1;
10050 }
10051
10052 if (meta->metacmd != IAX_META_TRUNK)
10053 return 1;
10054
10055 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
10056 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
10057 (int) (sizeof(*meta) + sizeof(*mth)));
10058 return 1;
10059 }
10060 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
10061 ts = ntohl(mth->ts);
10062 metatype = meta->cmddata;
10063 packet_len -= (sizeof(*meta) + sizeof(*mth));
10064 ptr = mth->data;
10065 tpeer = find_tpeer(addr, sockfd);
10066 if (!tpeer) {
10067 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s': No matching peer\n",
10069 return 1;
10070 }
10071 tpeer->trunkact = ast_tvnow();
10072 if (!ts || ast_tvzero(tpeer->rxtrunktime))
10073 tpeer->rxtrunktime = tpeer->trunkact;
10074 rxtrunktime = tpeer->rxtrunktime;
10075 ast_mutex_unlock(&tpeer->lock);
10076 while (packet_len >= sizeof(*mte)) {
10077 /* Process channels */
10078 unsigned short callno, trunked_ts, len;
10079
10080 if (metatype == IAX_META_TRUNK_MINI) {
10081 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
10082 ptr += sizeof(*mtm);
10083 packet_len -= sizeof(*mtm);
10084 len = ntohs(mtm->len);
10085 callno = ntohs(mtm->mini.callno);
10086 trunked_ts = ntohs(mtm->mini.ts);
10087 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
10088 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
10089 ptr += sizeof(*mte);
10090 packet_len -= sizeof(*mte);
10091 len = ntohs(mte->len);
10092 callno = ntohs(mte->callno);
10093 trunked_ts = 0;
10094 } else {
10095 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s': dropping\n", ast_sockaddr_stringify(addr));
10096 break;
10097 }
10098 /* Stop if we don't have enough data */
10099 if (len > packet_len)
10100 break;
10101 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, addr, NEW_PREVENT, sockfd, 0);
10102 if (!fr->callno)
10103 continue;
10104
10105 /* If it's a valid call, deliver the contents. If not, we
10106 drop it, since we don't have a scallno to use for an INVAL */
10107 /* Process as a mini frame */
10108 memset(&f, 0, sizeof(f));
10110 if (!iaxs[fr->callno]) {
10111 /* drop it */
10112 } else if (iaxs[fr->callno]->voiceformat == 0) {
10113 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
10114 iax2_vnak(fr->callno);
10116 iaxs[fr->callno]->voiceformat))) {
10117 f.datalen = len;
10118 if (f.datalen >= 0) {
10119 if (f.datalen)
10120 f.data.ptr = ptr;
10121 else
10122 f.data.ptr = NULL;
10123 if (trunked_ts)
10124 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
10125 else
10126 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
10127 /* Don't pass any packets until we're started */
10129 struct iax_frame *duped_fr;
10130
10131 /* Common things */
10132 f.src = "IAX2";
10133 f.mallocd = 0;
10134 f.offset = 0;
10135 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
10137 else
10138 f.samples = 0;
10139 fr->outoforder = 0;
10140 iax_frame_wrap(fr, &f);
10141 duped_fr = iaxfrdup2(fr);
10142 if (duped_fr)
10143 schedule_delivery(duped_fr, 1, 1, &fr->ts);
10144 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
10145 iaxs[fr->callno]->last = fr->ts;
10146 }
10147 } else {
10148 ast_log(LOG_WARNING, "Datalen < 0?\n");
10149 }
10150 }
10152 ptr += len;
10153 packet_len -= len;
10154 }
10155
10156 return 1;
10157}
static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
Definition: chan_iax2.c:6174
unsigned char data[0]
Definition: iax2.h:279
struct timeval rxtrunktime
Definition: chan_iax2.c:669

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

9956{
9957 struct iax2_thread *thread;
9958 time_t t;
9959 static time_t last_errtime = 0;
9960 struct ast_iax2_full_hdr *fh;
9961
9962 if (!(thread = find_idle_thread())) {
9963 time(&t);
9964 if (t != last_errtime) {
9965 last_errtime = t;
9966 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
9967 }
9968 usleep(1);
9969 return 1;
9970 }
9971
9972 thread->iofd = fd;
9973 thread->buf_len = ast_recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, &thread->ioaddr);
9974 thread->buf_size = sizeof(thread->readbuf);
9975 thread->buf = thread->readbuf;
9976 if (thread->buf_len < 0) {
9977 if (errno != ECONNREFUSED && errno != EAGAIN)
9978 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
9979 handle_error();
9980 thread->iostate = IAX_IOSTATE_IDLE;
9981 signal_condition(&thread->lock, &thread->cond);
9982 return 1;
9983 }
9984 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
9985 thread->iostate = IAX_IOSTATE_IDLE;
9986 signal_condition(&thread->lock, &thread->cond);
9987 return 1;
9988 }
9989
9990 /* Determine if this frame is a full frame; if so, and any thread is currently
9991 processing a full frame for the same callno from this peer, then drop this
9992 frame (and the peer will retransmit it) */
9993 fh = (struct ast_iax2_full_hdr *) thread->buf;
9994 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
9995 struct iax2_thread *cur = NULL;
9996 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
9997
10000 if ((cur->ffinfo.callno == callno) &&
10001 !ast_sockaddr_cmp_addr(&cur->ffinfo.addr, &thread->ioaddr))
10002 break;
10003 }
10004 if (cur) {
10005 /* we found another thread processing a full frame for this call,
10006 so queue it up for processing later. */
10009 thread->iostate = IAX_IOSTATE_IDLE;
10010 signal_condition(&thread->lock, &thread->cond);
10011 return 1;
10012 } else {
10013 /* this thread is going to process this frame, so mark it */
10014 thread->ffinfo.callno = callno;
10015 ast_sockaddr_copy(&thread->ffinfo.addr, &thread->ioaddr);
10016 thread->ffinfo.type = fh->type;
10017 thread->ffinfo.csub = fh->csub;
10019 }
10021 }
10022
10023 /* Mark as ready and send on its way */
10024 thread->iostate = IAX_IOSTATE_READY;
10025#ifdef DEBUG_SCHED_MULTITHREAD
10026 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
10027#endif
10028 signal_condition(&thread->lock, &thread->cond);
10029
10030 return 1;
10031}
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:9924
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:1164
struct iax2_thread::@128 ffinfo
unsigned short callno
Definition: chan_iax2.c:1163

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

9764{
9765 pthread_t newthread;
9766 struct dpreq_data *dpr;
9767
9768 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
9769 return;
9770
9771 dpr->callno = callno;
9772 ast_copy_string(dpr->context, context, sizeof(dpr->context));
9773 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
9774 if (callerid)
9776 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
9777 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
9778 }
9779}
static void * dp_lookup_thread(void *data)
Definition: chan_iax2.c:9752
#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 12818 of file chan_iax2.c.

12819{
12820 struct iax2_thread *thread;
12821 int threadcount = 0;
12822 int x;
12823 for (x = 0; x < iaxthreadcount; x++) {
12824 thread = ast_calloc(1, sizeof(*thread));
12825 if (thread) {
12827 thread->threadnum = ++threadcount;
12828 ast_mutex_init(&thread->lock);
12829 ast_cond_init(&thread->cond, NULL);
12830 ast_mutex_init(&thread->init_lock);
12831 ast_cond_init(&thread->init_cond, NULL);
12832
12833 ast_mutex_lock(&thread->init_lock);
12834
12836 ast_log(LOG_WARNING, "Failed to create new thread!\n");
12837 ast_mutex_destroy(&thread->lock);
12838 ast_cond_destroy(&thread->cond);
12839 ast_mutex_unlock(&thread->init_lock);
12840 ast_mutex_destroy(&thread->init_lock);
12841 ast_cond_destroy(&thread->init_cond);
12843 thread = NULL;
12844 continue;
12845 }
12846 /* Wait for the thread to be ready */
12847 ast_cond_wait(&thread->init_cond, &thread->init_lock);
12848
12849 /* Done with init_lock */
12850 ast_mutex_unlock(&thread->init_lock);
12851
12855 }
12856 }
12858 ast_log(LOG_ERROR, "Failed to create new thread!\n");
12859 return -1;
12860 }
12861 ast_verb(2, "%d helper threads started\n", threadcount);
12862 return 0;
12863}
static void * network_thread(void *ignore)
Definition: chan_iax2.c:12793

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

9460{
9461 iax2_destroy_helper(iaxs[callno]);
9462}

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

2492{
2493 if (!pvt->peercallno) {
2494 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
2495 return;
2496 }
2497
2499}

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

2473{
2474 if (!pvt->transfercallno) {
2475 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
2476 return;
2477 }
2478
2480}

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

9643{
9644 int res, processed = 0, totalcalls = 0;
9645 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
9646 struct timeval now = ast_tvnow();
9647
9648 if (iaxtrunkdebug) {
9649 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
9650 }
9651
9652 if (timer) {
9653 if (ast_timer_ack(timer, 1) < 0) {
9654 ast_log(LOG_ERROR, "Timer failed acknowledge\n");
9655 return 0;
9656 }
9657 }
9658
9659 /* For each peer that supports trunking... */
9661 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
9662 processed++;
9663 res = 0;
9664 ast_mutex_lock(&tpeer->lock);
9665 /* We can drop a single tpeer per pass. That makes all this logic
9666 substantially easier */
9667 if (!drop && iax2_trunk_expired(tpeer, &now)) {
9668 /* Take it out of the list, but don't free it yet, because it
9669 could be in use */
9671 drop = tpeer;
9672 } else {
9673 res = send_trunk(tpeer, &now);
9674 trunk_timed++;
9675 if (iaxtrunkdebug) {
9676 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",
9678 res,
9679 (res != 1) ? "s" : "",
9680 tpeer->trunkdatalen,
9681 tpeer->trunkdataalloc);
9682 }
9683 }
9684 totalcalls += res;
9685 res = 0;
9686 ast_mutex_unlock(&tpeer->lock);
9687 }
9690
9691 if (drop) {
9692 ast_mutex_lock(&drop->lock);
9693 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it,
9694 because by the time they could get tpeerlock, we've already grabbed it */
9695 ast_debug(1, "Dropping unused iax2 trunk peer '%s'\n", ast_sockaddr_stringify(&drop->addr));
9696 if (drop->trunkdata) {
9697 ast_free(drop->trunkdata);
9698 drop->trunkdata = NULL;
9699 }
9700 ast_mutex_unlock(&drop->lock);
9701 ast_mutex_destroy(&drop->lock);
9702 ast_free(drop);
9703 }
9704
9705 if (iaxtrunkdebug) {
9706 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
9707 }
9708 iaxtrunkdebug = 0;
9709
9710 return 1;
9711}
static int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
Definition: chan_iax2.c:9634
static int totalcalls
Definition: pbx.c:794
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 14936 of file chan_iax2.c.

14937{
14938 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14939
14940 /* The frames_received field is used to hold whether we're matching
14941 * against a full frame or not ... */
14942
14943 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14944 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14945}

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

14930{
14931 const struct chan_iax2_pvt *pvt = obj;
14932
14933 return pvt->transfercallno;
14934}

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

◆ transmit_frame()

static int transmit_frame ( void *  data)
static

Definition at line 4380 of file chan_iax2.c.

4381{
4382 struct iax_frame *fr = data;
4383
4385
4386 fr->sentyet = 1;
4387
4388 if (iaxs[fr->callno]) {
4389 send_packet(fr);
4390 }
4391
4392 if (fr->retries < 0) {
4394 /* No retransmit requested */
4395 iax_frame_free(fr);
4396 } else {
4397 /* We need reliable delivery. Schedule a retransmission */
4399 fr->retries++;
4402 }
4403
4404 return 0;
4405}

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

3463{
3464 int res;
3465 res = ast_sendto(sockfd, f->data, f->datalen, 0, addr);
3466
3467 if (res < 0) {
3468 ast_debug(1, "Received error: %s\n", strerror(errno));
3469 handle_error();
3470 } else
3471 res = 0;
3472 return res;
3473}

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

8751{
8752 int newcall = 0;
8753 struct iax_ie_data ied;
8754 struct ast_sockaddr new = { {0,} };
8755
8756 memset(&ied, 0, sizeof(ied));
8757 if (!ast_sockaddr_isnull(&ies->apparent_addr)) {
8758 ast_sockaddr_copy(&new, &ies->apparent_addr);
8759 }
8760 if (ies->callno) {
8761 newcall = ies->callno;
8762 }
8763 if (!newcall || ast_sockaddr_isnull(&new)) {
8764 ast_log(LOG_WARNING, "Invalid transfer request\n");
8765 return -1;
8766 }
8767 pvt->transfercallno = newcall;
8768 ast_sockaddr_copy(&pvt->transfer, &new);
8769 pvt->transferid = ies->transferid;
8770 /* only store by transfercallno if this is a new transfer,
8771 * just in case we get a duplicate TXREQ */
8772 if (pvt->transferring == TRANSFER_NONE) {
8774 }
8776
8777 if (ies->transferid) {
8779 }
8780 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
8781 return 0;
8782}
static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
Definition: chan_iax2.c:2472
#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 1906 of file chan_iax2.c.

1907{
1908 /* If the SC_LOG flag is set, return 2^csub otherwise csub */
1909 if (csub & IAX_FLAG_SC_LOG) {
1910 /* special case for 'compressed' -1 */
1911 if (csub == 0xff)
1912 return -1;
1913 else
1914 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
1915 }
1916 else
1917 return csub;
1918}

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

9062{
9063 if (peer->expire > -1) {
9064 if (!AST_SCHED_DEL(sched, peer->expire)) {
9065 peer->expire = -1;
9066 peer_unref(peer);
9067 }
9068 }
9069
9070 if (peer->pokeexpire > -1) {
9071 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
9072 peer->pokeexpire = -1;
9073 peer_unref(peer);
9074 }
9075 }
9076
9077 ao2_unlink(peers, peer);
9078}

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

14895{
14898 return __unload_module();
14899}
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 4146 of file chan_iax2.c.

4147{
4148 /* Video mini frames only encode the lower 15 bits of the session
4149 * timestamp, but other frame types (e.g. audio) encode 16 bits. */
4150 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
4151 const int lower_mask = (1 << ts_shift) - 1;
4152 const int upper_mask = ~lower_mask;
4153 const int last_upper = iaxs[fr->callno]->last & upper_mask;
4154
4155 if ( (fr->ts & upper_mask) == last_upper ) {
4156 const int x = fr->ts - iaxs[fr->callno]->last;
4157 const int threshold = (ts_shift == 15) ? 25000 : 50000;
4158
4159 if (x < -threshold) {
4160 /* Sudden big jump backwards in timestamp:
4161 What likely happened here is that miniframe timestamp has circled but we haven't
4162 gotten the update from the main packet. We'll just pretend that we did, and
4163 update the timestamp appropriately. */
4164 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
4165 if (iaxdebug)
4166 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
4167 } else if (x > threshold) {
4168 /* Sudden apparent big jump forwards in timestamp:
4169 What's likely happened is this is an old miniframe belonging to the previous
4170 top 15 or 16-bit timestamp that has turned up out of order.
4171 Adjust the timestamp appropriately. */
4172 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
4173 if (iaxdebug)
4174 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
4175 }
4176 }
4177}
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 4181 of file chan_iax2.c.

4182{
4183 int when;
4184
4185 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
4186
4187 when = jb_next(pvt->jb) - when;
4188
4189 if (when <= 0) {
4190 /* XXX should really just empty until when > 0.. */
4191 when = 1;
4192 }
4193
4194 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
4195 CALLNO_TO_PTR(pvt->callno));
4196}
static int get_from_jb(const void *p)
Definition: chan_iax2.c:4301

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

3595{
3596 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
3597 struct ast_iax2_full_hdr *fh = f->data;
3598 struct ast_frame af;
3599
3600 /* if frame is encrypted. decrypt before updating it. */
3601 if (f->encmethods) {
3602 decode_frame(&f->mydcx, fh, &af, &f->datalen);
3603 }
3604 /* Mark this as a retransmission */
3605 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
3606 /* Update iseqno */
3607 f->iseqno = iaxs[f->callno]->iseqno;
3608 fh->iseqno = f->iseqno;
3609
3610 /* Now re-encrypt the frame */
3611 if (f->encmethods) {
3612 /* since this is a retransmit frame, create a new random padding
3613 * before re-encrypting. */
3614 build_rand_pad(f->semirand, sizeof(f->semirand));
3615 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
3616 }
3617 return 0;
3618}

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

9185{
9186
9187 /* Called from IAX thread only, with proper iaxsl lock */
9188 struct iax_ie_data ied = {
9189 .pos = 0,
9190 };
9191 struct iax2_peer *p;
9192 int msgcount;
9193 char data[80];
9194 uint16_t version;
9195 const char *peer_name;
9196 int res = -1;
9197 char *str_addr;
9198
9199 peer_name = ast_strdupa(iaxs[callno]->peer);
9200
9201 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
9203 if (!(p = find_peer(peer_name, 1))) {
9205 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
9206 return -1;
9207 }
9209 if (!iaxs[callno])
9210 goto return_unref;
9211
9213 if (!ast_sockaddr_isnull(addr)) {
9214 time_t nowtime;
9215 time(&nowtime);
9216 realtime_update_peer(peer_name, addr, nowtime);
9217 } else {
9218 realtime_update_peer(peer_name, addr, 0);
9219 }
9220 }
9221
9222 /* treat an unspecified refresh interval as the minimum */
9223 if (!refresh) {
9225 }
9226 if (refresh > max_reg_expire) {
9227 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
9230 } else if (refresh < min_reg_expire) {
9231 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
9234 } else {
9235 p->expiry = refresh;
9236 }
9237
9238 if (ast_sockaddr_cmp(&p->addr, addr)) {
9239 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
9240
9241 if (iax2_regfunk) {
9242 iax2_regfunk(p->name, 1);
9243 }
9244
9245 /* modify entry in peercnts table as _not_ registered */
9246 peercnt_modify((unsigned char) 0, 0, &p->addr);
9247
9248 /* Stash the IP address from which they registered */
9250
9252
9253 snprintf(data, sizeof(data), "%s:%d", ast_sockaddr_stringify(addr), p->expiry);
9254
9256 ast_db_put("IAX/Registry", p->name, data);
9257 ast_verb(3, "Registered IAX2 '%s' (%s) at %s\n",
9258 p->name,
9259 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED",
9262 blob = ast_json_pack("{s: s, s: s, s: i}",
9263 "peer_status", "Registered",
9264 "address", str_addr,
9265 "port", ast_sockaddr_port(addr));
9266 register_peer_exten(p, 1);
9267 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
9268 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
9269 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n",
9270 p->name,
9271 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
9273 blob = ast_json_pack("{s: s}",
9274 "peer_status", "Unregistered");
9275 register_peer_exten(p, 0);
9276 ast_db_del("IAX/Registry", p->name);
9277 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
9278 }
9279
9281
9282 /* Update the host */
9283 /* Verify that the host is really there */
9285 }
9286
9287 /* modify entry in peercnts table as registered */
9288 if (p->maxcallno) {
9289 peercnt_modify((unsigned char) 1, p->maxcallno, &p->addr);
9290 }
9291
9292 /* Make sure our call still exists, an INVAL at the right point may make it go away */
9293 if (!iaxs[callno]) {
9294 res = -1;
9295 goto return_unref;
9296 }
9297
9298 /* Store socket fd */
9299 p->sockfd = fd;
9300 /* Setup the expiry */
9301 if (p->expire > -1) {
9302 if (!AST_SCHED_DEL(sched, p->expire)) {
9303 p->expire = -1;
9304 peer_unref(p);
9305 }
9306 }
9307
9308 if (p->expiry && !ast_sockaddr_isnull(addr)) {
9309 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
9310 if (p->expire == -1)
9311 peer_unref(p);
9312 }
9315 if (!ast_sockaddr_isnull(addr)) {
9316 struct ast_sockaddr peer_addr;
9317
9318 ast_sockaddr_copy(&peer_addr, &p->addr);
9319
9321 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
9322 if (!ast_strlen_zero(p->mailbox)) {
9323 int new, old;
9324 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
9325
9327 if (msg) {
9328 struct ast_mwi_state *mwi_state = stasis_message_data(msg);
9329 new = mwi_state->new_msgs;
9330 old = mwi_state->old_msgs;
9331 } else { /* Fall back on checking the mailbox directly */
9332 ast_app_inboxcount(p->mailbox, &new, &old);
9333 }
9334
9335 if (new > 255) {
9336 new = 255;
9337 }
9338 if (old > 255) {
9339 old = 255;
9340 }
9341 msgcount = (old << 8) | new;
9342
9343 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
9344 }
9348 }
9349 }
9350 if (iax_firmware_get_version(devtype, &version)) {
9352 }
9353
9354 res = 0;
9355
9356return_unref:
9357 peer_unref(p);
9358
9359 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
9360}
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: db.c:335
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 2069 of file chan_iax2.c.

2070{
2071 struct iax2_user *user = obj, *user2 = arg;
2072 const char *name = arg;
2073
2074 return !strcmp(user->name, flags & OBJ_KEY ? name : user2->name) ?
2075 CMP_MATCH | CMP_STOP : 0;
2076}
uint64_t flags
Definition: chan_iax2.c:591

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

13611{
13612 struct iax2_user *user = obj;
13613
13615
13616 return 0;
13617}

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

◆ user_destructor()

static void user_destructor ( void *  obj)
static

Definition at line 13325 of file chan_iax2.c.

13326{
13327 struct iax2_user *user = obj;
13328
13329 ast_free_acl_list(user->acl);
13330 free_context(user->contexts);
13331 if(user->vars) {
13333 user->vars = NULL;
13334 }
13336}

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

2059{
2060 const struct iax2_user *user = obj;
2061 const char *name = obj;
2062
2063 return ast_str_hash(flags & OBJ_KEY ? name : user->name);
2064}

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

9561{
9562 struct iax_frame *f;
9563
9565 /* Send a copy immediately */
9566 if (((unsigned char) (f->oseqno - last) < 128) &&
9567 (f->retries >= 0)) {
9568 send_packet(f);
9569 }
9570 }
9571}
struct iax_frame * last
Definition: chan_iax2.c:1005

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

5466{
5467 unsigned short callno = pvt->callno;
5468
5469 if (!pvt->peercallno) {
5470 /* We don't know the remote side's call number, yet. :( */
5471 int count = 10;
5472 while (count-- && pvt && !pvt->peercallno) {
5473 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
5474 pvt = iaxs[callno];
5475 }
5476 if (!pvt || !pvt->peercallno) {
5477 return -1;
5478 }
5479 }
5480
5481 return 0;
5482}

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 15186 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 352 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 501 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 15186 of file chan_iax2.c.

◆ auth_method_labels

const char* auth_method_labels[]
static

Name of effective auth method.

Definition at line 423 of file chan_iax2.c.

Referenced by socket_process_helper().

◆ authdebug

int authdebug = 0
static

◆ autokill

int autokill = 0
static

Definition at line 370 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 1034 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 991 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 988 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 994 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 1037 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 14765 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 1250 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 1039 of file chan_iax2.c.

Referenced by set_config().

◆ DEFAULT_MAXCALLNO_LIMIT_NONVAL

uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192
static

Definition at line 1041 of file chan_iax2.c.

Referenced by set_config().

◆ default_parkinglot

char default_parkinglot[AST_MAX_CONTEXT]
static

Definition at line 346 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 502 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 1005 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 341 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 1043 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 1046 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 553 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 504 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 483 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 503 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 394 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 14755 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:1601
static void iax2_free_variable_datastore(void *)
Definition: chan_iax2.c:1625

Definition at line 1595 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 1227 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 transferring a call are stored here.

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

Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().

◆ iaxcompat

int iaxcompat = 0
static

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

Referenced by complete_dpreply(), dp_lookup(), and find_cache().

◆ iaxdefaulttimeout

int iaxdefaulttimeout = 5
static

Definition at line 376 of file chan_iax2.c.

Referenced by find_cache().

◆ iaxdynamicthreadcount

int iaxdynamicthreadcount = 0
static

Definition at line 746 of file chan_iax2.c.

Referenced by find_idle_thread(), and iax2_process_thread().

◆ iaxdynamicthreadnum

int iaxdynamicthreadnum = 0
static

Definition at line 747 of file chan_iax2.c.

Referenced by find_idle_thread().

◆ iaxmaxthreadcount

int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT
static

Definition at line 745 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:14602

Definition at line 14674 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 1198 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 744 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 487 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:10188
static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: chan_iax2.c:10159

Definition at line 10238 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 480 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 362 of file chan_iax2.c.

Referenced by new_iax(), and set_config().

◆ lagrq_time

int lagrq_time = 10
static

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

Referenced by vnak_retransmit().

◆ last_authmethod

int last_authmethod = 0
static

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

Referenced by handle_call_token(), and set_config().

◆ max_reg_expire

int max_reg_expire
static

Definition at line 384 of file chan_iax2.c.

Referenced by set_config(), and update_registry().

◆ max_retries

int max_retries = 4
static

Definition at line 356 of file chan_iax2.c.

Referenced by __attempt_transmit(), and load_module().

◆ maxauthreq

int maxauthreq = 3
static

Definition at line 355 of file chan_iax2.c.

Referenced by build_user(), and set_config().

◆ maxjitterbuffer

int maxjitterbuffer =1000
static

Definition at line 359 of file chan_iax2.c.

Referenced by new_iax(), and set_config().

◆ maxjitterinterps

int maxjitterinterps =10
static

Definition at line 361 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 508 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 353 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 351 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 391 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 12462 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 1031 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 1025 of file chan_iax2.c.

◆ ping_time

int ping_time = 21
static

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

Referenced by new_iax(), and set_config().

◆ sched

struct ast_sched_context* sched
static

Definition at line 481 of file chan_iax2.c.

◆ srvlookup

int srvlookup = 0
static

◆ tdesc

const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)"
static

Definition at line 334 of file chan_iax2.c.

◆ test_losspct

int test_losspct = 0
static

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

Referenced by __unload_module(), iax2_transmit(), and load_objects().

◆ trunk_maxmtu

int trunk_maxmtu
static

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

Referenced by handle_cli_iax2_show_stats(), and reload_config().

◆ trunk_timed

int trunk_timed
static

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

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

◆ trunkmaxsize

int trunkmaxsize = MAX_TRUNKDATA
static

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