Asterisk - The Open Source Telephony Project GIT-master-20e40a9
Loading...
Searching...
No Matches
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.
 
#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.
 
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.
 
static int auth_reject (const void *data)
 
static int authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct ast_sockaddr *addr, struct chan_iax2_pvt *pvt)
 
static int authenticate_reply (struct chan_iax2_pvt *p, struct ast_sockaddr *addr, struct iax_ies *ies, const char *override, const char *okey)
 
static int authenticate_request (int call_num)
 
static int authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies)
 
static int auto_congest (const void *data)
 
static int auto_hangup (const void *data)
 
static void build_callno_limits (struct ast_variable *v)
 
static struct iax2_contextbuild_context (const char *context)
 
static void build_ecx_key (const unsigned char *digest, struct chan_iax2_pvt *pvt)
 
static void build_encryption_keys (const unsigned char *digest, struct chan_iax2_pvt *pvt)
 
static struct iax2_peerbuild_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
 Create peer structure based on configuration.
 
static void build_rand_pad (unsigned char *buf, ssize_t len)
 
static struct iax2_userbuild_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
 Create in-memory user structure from configuration.
 
static int cache_get_callno_locked (const char *data)
 
static unsigned int calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset)
 
static unsigned int calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
 
static unsigned int calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
 
static int calltoken_required (struct ast_sockaddr *addr, const char *name, int subclass)
 
static int check_access (int callno, struct ast_sockaddr *addr, struct iax_ies *ies)
 
static int check_provisioning (struct ast_sockaddr *addr, int sockfd, char *si, unsigned int ver)
 
static int check_srcaddr (struct ast_sockaddr *addr)
 Check if address can be used as packet source.
 
static void cleanup_thread_list (void *head)
 
static struct ast_formatcodec_choose_from_prefs (struct iax2_codec_pref *pref, struct ast_format_cap *cap)
 
static int complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
 
static char * complete_iax2_peers (const char *line, const char *word, int pos, int state, uint64_t flags)
 
static char * complete_iax2_unregister (const char *line, const char *word, int pos, int state)
 
static int complete_transfer (int callno, struct iax_ies *ies)
 
static unsigned char compress_subclass (iax2_format subclass)
 
static void construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
 
static int create_addr (const char *peername, struct ast_channel *c, struct ast_sockaddr *addr, struct create_addr_info *cai)
 
static int create_callno_pools (void)
 
static int decode_frame (ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
 
static int decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
 
static void defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here)
 Queue the last read full frame for processing by a certain thread.
 
static void delete_users (void)
 
static void dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
 
static void * dp_lookup_thread (void *data)
 
static void encmethods_to_str (int e, struct ast_str **buf)
 
static int encrypt_frame (ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
 
static int expire_registry (const void *data)
 
static struct iax2_dpcachefind_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
 
static int find_callno (unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, int new, int sockfd, int full_frame)
 
static int find_callno_locked (unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, int new, int sockfd, int full_frame)
 
static struct iax2_threadfind_idle_thread (void)
 
static struct iax2_peerfind_peer (const char *name, int realtime)
 
static struct iax2_trunk_peerfind_tpeer (struct ast_sockaddr *addr, int fd)
 
static struct iax2_userfind_user (const char *name)
 
static int firmware_show_callback (struct ast_iax2_firmware_header *header, void *user_data)
 
static unsigned int fix_peerts (struct timeval *rxtrunktime, int callno, unsigned int ts)
 
static void free_context (struct iax2_context *con)
 
static void free_signaling_queue_entry (struct signaling_queue_entry *s)
 
static int function_iaxpeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 
static int get_auth_methods (const char *value)
 
static int get_encrypt_methods (const char *s)
 
static int get_from_jb (const void *p)
 
static int get_unused_callno (enum callno_type type, int validated, callno_entry *entry)
 
static int handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct ast_sockaddr *addr, int fd)
 
static char * handle_cli_iax2_provision (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_set_debug_jb (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_set_debug_trunk (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_set_mtu (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Set trunk MTU from CLI.
 
static char * handle_cli_iax2_show_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_show_callno_limits (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_show_firmware (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_show_netstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show one peer in detail.
 
static char * handle_cli_iax2_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_test_losspct (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_iax2_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void handle_deferred_full_frames (struct iax2_thread *thread)
 Handle any deferred full frames for this thread.
 
static int handle_error (void)
 
static int iax2_ack_registry (struct iax_ies *ies, struct ast_sockaddr *addr, int callno)
 Acknowledgment received for OUR registration.
 
static int attribute_pure iax2_allow_new (int frametype, int subclass, int inbound)
 
static int iax2_answer (struct ast_channel *c)
 
static int iax2_append_register (const char *hostname, const char *username, const char *secret, const char *porta)
 
static int iax2_call (struct ast_channel *c, const char *dest, int timeout)
 
static int iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 part of the IAX2 dial plan switch interface
 
static iax2_format iax2_codec_choose (struct iax2_codec_pref *pref, iax2_format formats)
 
static 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 —.
 
static int iax2_digit_begin (struct ast_channel *c, char digit)
 
static int iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration)
 
static int iax2_do_register (struct iax2_registry *reg)
 
static int iax2_do_register_s (const void *data)
 
static void iax2_dprequest (struct iax2_dpcache *dp, int callno)
 
static void * iax2_dup_variable_datastore (void *)
 
static int iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Execute IAX2 dialplan switch.
 
static int iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 switch interface.
 
static int iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan)
 
static void iax2_frame_free (struct iax_frame *fr)
 
static void iax2_free_variable_datastore (void *)
 
const char * iax2_getformatname (iax2_format format)
 iax2 wrapper function for ast_getformatname
 
static const char * iax2_getformatname_multiple (iax2_format format, struct ast_str **codec_buf)
 
static int iax2_getpeername (struct ast_sockaddr addr, char *host, int len)
 
static int iax2_getpeertrunk (struct ast_sockaddr addr)
 
static int iax2_hangup (struct ast_channel *c)
 
static int iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen)
 
static int iax2_is_control_frame_allowed (int subtype)
 
static int iax2_key_rotate (const void *vpvt)
 
static int iax2_lock_callno_unless_destroyed (int callno)
 Acquire the iaxsl[callno] if call exists and not having ongoing hangup.
 
static void iax2_lock_owner (int callno)
 
static int iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 Switch interface.
 
static int iax2_parse_allow_disallow (struct iax2_codec_pref *pref, iax2_format *formats, const char *list, int allowing)
 
static int iax2_poke_noanswer (const void *data)
 
static int iax2_poke_peer (struct iax2_peer *peer, int heldcall)
 
static int iax2_poke_peer_cb (void *obj, void *arg, int flags)
 
static int iax2_poke_peer_s (const void *data)
 
static int iax2_predestroy (int callno)
 
static void * iax2_process_thread (void *data)
 
static void iax2_process_thread_cleanup (void *data)
 
static int iax2_prov_app (struct ast_channel *chan, const char *data)
 
static int iax2_provision (struct ast_sockaddr *end, int sockfd, const char *dest, const char *template, int force)
 
static void iax2_publish_registry (const char *username, const char *domain, const char *status, const char *cause)
 
static int iax2_queryoption (struct ast_channel *c, int option, void *data, int *datalen)
 
static int iax2_queue_frame (int callno, struct ast_frame *f)
 Queue a frame to a call's owning asterisk channel.
 
static int iax2_queue_hangup (int callno)
 Queue a hangup frame on the ast_channel owner.
 
static int iax2_queue_hold (int callno, const char *musicclass)
 Queue a hold frame on the ast_channel owner.
 
static int iax2_queue_unhold (int callno)
 Queue an unhold frame on the ast_channel owner.
 
static struct ast_frameiax2_read (struct ast_channel *c)
 
static int iax2_register (const char *value, int lineno)
 
static struct ast_channeliax2_request (const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
 
static int iax2_sched_add (struct ast_sched_context *sched, int when, ast_sched_cb callback, const void *data)
 
static int iax2_sched_replace (int id, struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data)
 
static int iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
 
static int iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen)
 
static int iax2_sendimage (struct ast_channel *c, struct ast_frame *img)
 
static int iax2_sendtext (struct ast_channel *c, const char *text)
 
static int iax2_setoption (struct ast_channel *c, int option, void *data, int datalen)
 
static int iax2_transfer (struct ast_channel *c, const char *dest)
 
static int iax2_transmit (struct iax_frame *fr)
 
static int iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now)
 
static int iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr)
 
static int iax2_vnak (int callno)
 
static int iax2_write (struct ast_channel *c, struct ast_frame *f)
 
static void iax_debug_output (const char *data)
 
static void iax_error_output (const char *data)
 
static void iax_outputframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct ast_sockaddr *addr, int datalen)
 
static ast_callid iax_pvt_callid_get (int callno)
 
static void iax_pvt_callid_new (int callno)
 
static void iax_pvt_callid_set (int callno, ast_callid callid)
 
static struct iax_frameiaxfrdup2 (struct iax_frame *fr)
 
static void insert_idle_thread (struct iax2_thread *thread)
 
static 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.
 
static int load_objects (void)
 
static void log_jitterstats (unsigned short callno)
 
static int make_trunk (unsigned short callno, int locked)
 
static int manager_iax2_show_netstats (struct mansession *s, const struct message *m)
 
static int manager_iax2_show_peer_list (struct mansession *s, const struct message *m)
 callback to display iax peers in manager format
 
static int manager_iax2_show_peers (struct mansession *s, const struct message *m)
 callback to display iax peers in manager
 
static int manager_iax2_show_registry (struct mansession *s, const struct message *m)
 
static int match (struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
 
static void memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
 
static void memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
 
static void merge_encryption (struct chan_iax2_pvt *p, unsigned int enc)
 
static int network_change_sched_cb (const void *data)
 
static void network_change_stasis_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void network_change_stasis_subscribe (void)
 
static void network_change_stasis_unsubscribe (void)
 
static void * network_thread (void *ignore)
 
static struct chan_iax2_pvtnew_iax (struct ast_sockaddr *addr, const char *host)
 
static void parse_dial_string (char *data, struct parsed_dial_string *pds)
 Parses an IAX dial string into its component parts.
 
static int peer_cmp_cb (void *obj, void *arg, int flags)
 
static int peer_delme_cb (void *obj, void *arg, int flags)
 
static void peer_destructor (void *obj)
 
static int peer_hash_cb (const void *obj, const int flags)
 
static struct iax2_peerpeer_ref (struct iax2_peer *peer)
 
static int peer_set_sock_cb (void *obj, void *arg, int flags)
 
static int peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr)
 Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found.
 
static int peer_status (struct iax2_peer *peer, char *status, int statuslen)
 peer_status: Report Peer status in character string
 
static struct iax2_peerpeer_unref (struct iax2_peer *peer)
 
static int peercnt_add (struct ast_sockaddr *addr)
 
static int peercnt_cmp_cb (void *obj, void *arg, int flags)
 
static int peercnt_hash_cb (const void *obj, const int flags)
 
static void peercnt_modify (unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
 
static void peercnt_remove (struct peercnt *peercnt)
 
static int peercnt_remove_by_addr (struct ast_sockaddr *addr)
 
static int peercnt_remove_cb (const void *obj)
 
static void poke_all_peers (void)
 
static int prune_addr_range_cb (void *obj, void *arg, int flags)
 
static void prune_peers (void)
 
static void prune_users (void)
 
static int pvt_cmp_cb (void *obj, void *arg, int flags)
 
static void pvt_destructor (void *obj)
 
static int pvt_hash_cb (const void *obj, const int flags)
 
static int queue_signalling (struct chan_iax2_pvt *pvt, struct ast_frame *f)
 All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.
 
static int raw_hangup (struct ast_sockaddr *addr, unsigned short src, unsigned short dst, int sockfd)
 
static struct iax2_peerrealtime_peer (const char *peername, struct ast_sockaddr *addr)
 
static void realtime_update_peer (const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
 
static struct iax2_userrealtime_user (const char *username, struct ast_sockaddr *addr)
 
static void reg_source_db (struct iax2_peer *p)
 
static void register_peer_exten (struct iax2_peer *peer, int onoff)
 
static int register_verify (int callno, struct ast_sockaddr *addr, struct iax_ies *ies)
 Verify inbound registration.
 
static int registry_authrequest (int callno)
 
static int registry_rerequest (struct iax_ies *ies, int callno, struct ast_sockaddr *addr)
 
static char * regstate2str (int regstate)
 
static int reload (void)
 
static int reload_config (int forced_reload)
 
static void remove_by_peercallno (struct chan_iax2_pvt *pvt)
 
static void remove_by_transfercallno (struct chan_iax2_pvt *pvt)
 
static int replace_callno (const void *obj)
 
static void requirecalltoken_mark_auto (const char *name, int subclass)
 
static void resend_with_token (int callno, struct iax_frame *f, const char *newtoken)
 
static void save_osptoken (struct iax_frame *fr, struct iax_ies *ies)
 
static void save_rr (struct iax_frame *fr, struct iax_ies *ies)
 
static void sched_delay_remove (struct ast_sockaddr *addr, callno_entry entry)
 
static int schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
 
static int scheduled_destroy (const void *vid)
 
static int send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, int command, int ts, unsigned char seqno, int sockfd, struct iax_ie_data *ied)
 
static int send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
 
static int send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
 
static int send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
 
static int send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int)
 
static int send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int)
 
static int send_lagrq (const void *data)
 
static int send_packet (struct iax_frame *f)
 
static int send_ping (const void *data)
 
static void send_signaling (struct chan_iax2_pvt *pvt)
 This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.
 
static int send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now)
 
static int set_config (const char *config_file, int reload, int forced)
 Load configuration.
 
static void set_config_destroy (void)
 
static void set_hangup_source_and_cause (int callno, unsigned char causecode)
 
static void set_peercnt_limit (struct peercnt *peercnt)
 
static int set_peercnt_limit_all_cb (void *obj, void *arg, int flags)
 
static void signal_condition (ast_mutex_t *lock, ast_cond_t *cond)
 
static int socket_process (struct iax2_thread *thread)
 
static int socket_process_helper (struct iax2_thread *thread)
 
static int socket_process_meta (int packet_len, struct ast_iax2_meta_hdr *meta, struct ast_sockaddr *addr, int sockfd, struct iax_frame *fr)
 
static int socket_read (int *id, int fd, short events, void *cbdata)
 
static void spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid)
 
static int start_network_thread (void)
 
static void stop_stuff (int callno)
 
static void store_by_peercallno (struct chan_iax2_pvt *pvt)
 
static void store_by_transfercallno (struct chan_iax2_pvt *pvt)
 
static int timing_read (int *id, int fd, short events, void *cbdata)
 
static int transfercallno_pvt_cmp_cb (void *obj, void *arg, int flags)
 
static int transfercallno_pvt_hash_cb (const void *obj, const int flags)
 
static int transmit_frame (void *data)
 
static int transmit_trunk (struct iax_frame *f, struct ast_sockaddr *addr, int sockfd)
 
static int try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
 
static iax2_format uncompress_subclass (unsigned char csub)
 
static void unlink_peer (struct iax2_peer *peer)
 
static int unload_module (void)
 
static void unwrap_timestamp (struct iax_frame *fr)
 
static void update_jbsched (struct chan_iax2_pvt *pvt)
 
static int update_packet (struct iax_frame *f)
 
static int update_registry (struct ast_sockaddr *addr, int callno, char *devtype, int fd, unsigned short refresh)
 
static int user_cmp_cb (void *obj, void *arg, int flags)
 
static int user_delme_cb (void *obj, void *arg, int flags)
 
static void user_destructor (void *obj)
 
static int user_hash_cb (const void *obj, const int flags)
 
static struct iax2_useruser_unref (struct iax2_user *user)
 
static 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 = ASTERISK_GPL_KEY , .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 = AST_LIST_HEAD_INIT_VALUE
 
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.
 
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 = AST_MUTEX_INIT_VALUE
 
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 = AST_LIST_HEAD_INIT_VALUE
 
static struct dynamic_list dynamic_list = AST_LIST_HEAD_INIT_VALUE
 
struct { 
 
   struct iax_frame *   first 
 
   struct iax_frame *   last 
 
frame_queue [IAX_MAX_CALLS
 a list of frames that may need to be retransmitted
 
static int global_max_trunk_mtu
 
static uint16_t global_maxcallno
 
static uint16_t global_maxcallno_nonval
 
static int global_rtautoclear = 120
 
static struct ast_flags64 globalflags = { 0 }
 
static int iax2_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.
 
static struct ao2_containeriax_transfercallno_pvts
 Another container of iax2_pvt structures.
 
static int iaxactivethreadcount = 0
 
static int iaxcompat = 0
 
static int iaxdebug = 0
 
static int iaxdefaultdpcache =10 * 60
 
static int iaxdefaulttimeout = 5
 
static int iaxdynamicthreadcount = 0
 
static int iaxdynamicthreadnum = 0
 
static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT
 
static struct ast_custom_function iaxpeer_function
 
static struct chan_iax2_pvtiaxs [IAX_MAX_CALLS]
 an array of iax2 pvt structures
 
static ast_mutex_t iaxsl [ARRAY_LEN(iaxs)]
 chan_iax2_pvt structure locks
 
static int iaxthreadcount = DEFAULT_THREAD_COUNT
 
static int iaxtrunkdebug = 0
 
static struct ast_custom_function iaxvar_function
 
static struct idle_list idle_list = AST_LIST_HEAD_INIT_VALUE
 
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 = AST_LIST_HEAD_INIT_VALUE
 
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 = AST_LIST_HEAD_INIT_VALUE
 
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.

466 { \
467 int idx; \
468 char digest[33] = ""; \
469 \
470 if (!iaxdebug) \
471 break; \
472 \
473 for (idx = 0; idx < 16; idx++) \
474 sprintf(digest + (idx << 1), "%02hhx", (unsigned char) key[idx]); \
475 \
476 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
477 } while(0)
478
479static struct io_context *io;
480static struct ast_sched_context *sched;
481
483
484static int iaxdebug = 0;
485
486static int iaxtrunkdebug = 0;
487
488static int test_losspct = 0;
489#ifdef IAXTESTS
490static int test_late = 0;
491static int test_resync = 0;
492static int test_jit = 0;
493static int test_jitpct = 0;
494#endif /* IAXTESTS */
495
497static char mohinterpret[MAX_MUSICCLASS];
498static char mohsuggest[MAX_MUSICCLASS];
499static int amaflags = 0;
500static int adsi = 0;
501static int delayreject = 0;
502static int iax2_encryption = 0;
503static int iax2_authmethods = 0;
504
505static struct ast_flags64 globalflags = { 0 };
506
507static pthread_t netthreadid = AST_PTHREADT_NULL;
508
509enum iax2_state {
510 IAX_STATE_STARTED = (1 << 0),
511 IAX_STATE_AUTHENTICATED = (1 << 1),
512 IAX_STATE_TBD = (1 << 2),
513};
514
515struct iax2_context {
517 struct iax2_context *next;
518};
519
520
521#define IAX_HASCALLERID (uint64_t)(1LLU << 0) /*!< CallerID has been specified */
522#define IAX_DELME (uint64_t)(1LLU << 1) /*!< Needs to be deleted */
523#define IAX_TEMPONLY (uint64_t)(1LLU << 2) /*!< Temporary (realtime) */
524#define IAX_TRUNK (uint64_t)(1LLU << 3) /*!< Treat as a trunk */
525#define IAX_NOTRANSFER (uint64_t)(1LLU << 4) /*!< Don't native bridge */
526#define IAX_USEJITTERBUF (uint64_t)(1LLU << 5) /*!< Use jitter buffer */
527#define IAX_DYNAMIC (uint64_t)(1LLU << 6) /*!< dynamic peer */
528#define IAX_SENDANI (uint64_t)(1LLU << 7) /*!< Send ANI along with CallerID */
529#define IAX_RTSAVE_SYSNAME (uint64_t)(1LLU << 8) /*!< Save Systname on Realtime Updates */
530#define IAX_ALREADYGONE (uint64_t)(1LLU << 9) /*!< Already disconnected */
531#define IAX_PROVISION (uint64_t)(1LLU << 10) /*!< This is a provisioning request */
532#define IAX_QUELCH (uint64_t)(1LLU << 11) /*!< Whether or not we quelch audio */
533#define IAX_ENCRYPTED (uint64_t)(1LLU << 12) /*!< Whether we should assume encrypted tx/rx */
534#define IAX_KEYPOPULATED (uint64_t)(1LLU << 13) /*!< Whether we have a key populated */
535#define IAX_CODEC_USER_FIRST (uint64_t)(1LLU << 14) /*!< are we willing to let the other guy choose the codec? */
536#define IAX_CODEC_NOPREFS (uint64_t)(1LLU << 15) /*!< Force old behaviour by turning off prefs */
537#define IAX_CODEC_NOCAP (uint64_t)(1LLU << 16) /*!< only consider requested format and ignore capabilities*/
538#define IAX_RTCACHEFRIENDS (uint64_t)(1LLU << 17) /*!< let realtime stay till your reload */
539#define IAX_RTUPDATE (uint64_t)(1LLU << 18) /*!< Send a realtime update */
540#define IAX_RTAUTOCLEAR (uint64_t)(1LLU << 19) /*!< erase me on expire */
541#define IAX_RTIGNOREREGEXPIRE (uint64_t)(1LLU << 21) /*!< When using realtime, ignore registration expiration */
542#define IAX_TRUNKTIMESTAMPS (uint64_t)(1LLU << 22) /*!< Send trunk timestamps */
543#define IAX_TRANSFERMEDIA (uint64_t)(1LLU << 23) /*!< When doing IAX2 transfers, transfer media only */
544#define IAX_MAXAUTHREQ (uint64_t)(1LLU << 24) /*!< Maximum outstanding AUTHREQ restriction is in place */
545#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 */
546#define IAX_ALLOWFWDOWNLOAD (uint64_t)(1LLU << 26) /*!< Allow the FWDOWNL command? */
547#define IAX_IMMEDIATE (uint64_t)(1LLU << 27) /*!< Allow immediate off-hook to extension s */
548#define IAX_SENDCONNECTEDLINE (uint64_t)(1LLU << 28) /*!< Allow sending of connected line updates */
549#define IAX_RECVCONNECTEDLINE (uint64_t)(1LLU << 29) /*!< Allow receiving of connected line updates */
550#define IAX_FORCE_ENCRYPT (uint64_t)(1LLU << 30) /*!< Forces call encryption, if encryption not possible hangup */
551#define IAX_SHRINKCALLERID (uint64_t)(1LLU << 31) /*!< Turn on and off caller id shrinking */
552static int global_rtautoclear = 120;
553
554static int reload_config(int forced_reload);
555
556/*!
557 * \brief Call token validation settings.
558 */
560 /*! \brief Default calltoken required unless the ip is in the ignorelist */
562 /*! \brief Require call token validation. */
563 CALLTOKEN_YES = 1,
564 /*! \brief Require call token validation after a successful registration
565 * using call token validation occurs. */
566 CALLTOKEN_AUTO = 2,
567 /*! \brief Do not require call token validation. */
568 CALLTOKEN_NO = 3,
569};
570
571struct iax2_user {
579 AST_STRING_FIELD(inkeys); /*!< Key(s) this user can use to authenticate to us */
583 AST_STRING_FIELD(parkinglot); /*!< Default parkinglot for device */
584 );
585
586 int authmethods;
587 int encmethods;
588 int amaflags;
589 int adsi;
590 uint64_t flags;
592 int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
593 int curauthreq; /*!< Current number of outstanding AUTHREQs */
594 struct iax2_codec_pref prefs;
595 struct ast_acl_list *acl;
596 struct iax2_context *contexts;
597 struct ast_variable *vars;
598 enum calltoken_peer_enum calltoken_required; /*!< Is calltoken validation required or not, can be YES, NO, or AUTO */
599};
600
601struct iax2_peer {
605 AST_STRING_FIELD(description); /*!< Description of the peer */
608 AST_STRING_FIELD(outkey); /*!< What key we use to talk to this peer */
609
610 AST_STRING_FIELD(regexten); /*!< Extension to register (if regcontext is used) */
611 AST_STRING_FIELD(context); /*!< For transfers only */
612 AST_STRING_FIELD(peercontext); /*!< Context to pass to peer */
613 AST_STRING_FIELD(mailbox); /*!< Mailbox */
616 AST_STRING_FIELD(inkeys); /*!< Key(s) this peer can use to authenticate to us */
617 /* Suggested caller id if registering */
618 AST_STRING_FIELD(cid_num); /*!< Default context (for transfer really) */
619 AST_STRING_FIELD(cid_name); /*!< Default context (for transfer really) */
620 AST_STRING_FIELD(zonetag); /*!< Time Zone */
621 AST_STRING_FIELD(parkinglot); /*!< Default parkinglot for device */
622 );
623 struct iax2_codec_pref prefs;
624 struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
625 struct ast_sockaddr addr;
626 int formats;
627 int sockfd; /*!< Socket to use for transmission */
628 struct ast_sockaddr mask;
629 int adsi;
630 uint64_t flags;
631
632 /* Dynamic Registration fields */
633 struct ast_sockaddr defaddr; /*!< Default address if there is one */
634 int authmethods; /*!< Authentication methods (IAX_AUTH_*) */
635 int encmethods; /*!< Encryption methods (IAX_ENCRYPT_*) */
636
637 int expire; /*!< Schedule entry for expiry */
638 int expiry; /*!< How soon to expire */
639 iax2_format capability; /*!< Capability */
640
641 /* Qualification */
642 int callno; /*!< Call number of POKE request */
643 int pokeexpire; /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
644 int lastms; /*!< How long last response took (in ms), or -1 for no response */
645 int maxms; /*!< Max ms we will accept for the host to be up, 0 to not monitor */
646
647 int pokefreqok; /*!< How often to check if the host is up */
648 int pokefreqnotok; /*!< How often to check when the host has been determined to be down */
649 int historicms; /*!< How long recent average responses took */
650 int smoothing; /*!< Sample over how many units to determine historic ms */
651 uint16_t maxcallno; /*!< Max call number limit for this peer. Set on registration */
652
653 struct ast_mwi_subscriber *mwi_event_sub; /*!< This subscription lets pollmailboxes know which mailboxes need to be polled */
654
655 struct ast_acl_list *acl;
656 enum calltoken_peer_enum calltoken_required; /*!< Is calltoken validation required or not, can be YES, NO, or AUTO */
657
658 struct ast_endpoint *endpoint; /*!< Endpoint structure for this peer */
659};
660
661#define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
662
663struct iax2_trunk_peer {
665 int sockfd;
666 struct ast_sockaddr addr;
667 struct timeval txtrunktime; /*!< Transmit trunktime */
668 struct timeval rxtrunktime; /*!< Receive trunktime */
669 struct timeval lasttxtime; /*!< Last transmitted trunktime */
670 struct timeval trunkact; /*!< Last trunk activity */
671 unsigned int lastsent; /*!< Last sent time */
672 /* Trunk data and length */
673 unsigned char *trunkdata;
674 unsigned int trunkdatalen;
675 unsigned int trunkdataalloc;
676 int trunkmaxmtu;
677 int trunkerror;
678 int calls;
680};
681
683
684enum iax_reg_state {
692};
693
695 TRANSFER_NONE = 0,
706};
707
708struct iax2_registry {
709 struct ast_sockaddr addr; /*!< Who we connect to for registration purposes */
710 char username[80];
711 char secret[80]; /*!< Password or key name in []'s */
712 int expire; /*!< Sched ID of expiration */
713 int refresh; /*!< How often to refresh */
715 int messages; /*!< Message count, low 8 bits = new, high 8 bits = old */
716 int callno; /*!< Associated call number if applicable */
717 struct ast_sockaddr us; /*!< Who the server thinks we are */
718 struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
720 int port;
721 char hostname[];
722};
723
725
726/* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
727#define MIN_RETRY_TIME 100
728#define MAX_RETRY_TIME 10000
729
730#define MAX_JITTER_BUFFER 50
731#define MIN_JITTER_BUFFER 10
732
733#define DEFAULT_TRUNKDATA 640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
734
735#define MAX_TIMESTAMP_SKEW 160 /*!< maximum difference between actual and predicted ts for sending */
736
737/* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
738#define TS_GAP_FOR_JB_RESYNC 5000
739
740/* used for first_iax_message and last_iax_message. If this bit is set it was TX, else RX */
741#define MARK_IAX_SUBCLASS_TX 0x8000
742
745static int iaxdynamicthreadcount = 0;
746static int iaxdynamicthreadnum = 0;
747static int iaxactivethreadcount = 0;
748
749struct iax_rr {
750 int jitter;
751 int losspct;
752 int losscnt;
753 int packets;
754 int delay;
755 int dropped;
756 int ooo;
757};
758
759struct iax2_pvt_ref;
760
761/* We use the high order bit as the validated flag, and the lower 15 as the
762 * actual call number */
763typedef uint16_t callno_entry;
764
765struct chan_iax2_pvt {
766 /*! Socket to send/receive on for this call */
767 int sockfd;
768 /*! ast_callid bound to dialog */
770 /*! Last received voice format */
772 /*! Last received video format */
774 /*! Last sent voice format */
776 /*! Last sent video format */
778 /*! What we are capable of sending */
780 /*! Last received timestamp */
781 unsigned int last;
782 /*! Last sent timestamp - never send the same timestamp twice in a single call */
783 unsigned int lastsent;
784 /*! Timestamp of the last video frame sent */
785 unsigned int lastvsent;
786 /*! Next outgoing timestamp if everything is good */
787 unsigned int nextpred;
788 /*! iax frame subclass that began iax2_pvt entry. 0x8000 bit is set on TX */
790 /*! Last iax frame subclass sent or received for a iax2_pvt. 0x8000 bit is set on TX */
792 /*! True if the last voice we transmitted was not silence/CNG */
793 unsigned int notsilenttx:1;
794 /*! Ping time */
795 unsigned int pingtime;
796 /*! Max time for initial response */
797 int maxtime;
798 /*! Peer Address */
799 struct ast_sockaddr addr;
800 /*! Actual used codec preferences */
801 struct iax2_codec_pref prefs;
802 /*! Requested codec preferences */
803 struct iax2_codec_pref rprefs;
804 /*! Our call number */
805 unsigned short callno;
806 /*! Our callno_entry entry */
808 /*! Peer callno */
809 unsigned short peercallno;
810 /*! Negotiated format, this is only used to remember what format was
811 chosen for an unauthenticated call so that the channel can get
812 created later using the right format. We also use it for
813 authenticated calls to check the format from __get_from_jb. */
815 /*! Peer selected format */
817 /*! Peer capability */
819 /*! timeval that we base our transmission on */
820 struct timeval offset;
821 /*! timeval that we base our delivery on */
822 struct timeval rxcore;
823 /*! The jitterbuffer */
824 jitterbuf *jb;
825 /*! active jb read scheduler id */
826 int jbid;
827 /*! LAG */
828 int lag;
829 /*! Error, as discovered by the manager */
830 int error;
831 /*! Owner if we have one */
832 struct ast_channel *owner;
833 /*! What's our state? */
834 struct ast_flags state;
835 /*! Expiry (optional) */
836 int expiry;
837 /*! Next outgoing sequence number */
838 unsigned char oseqno;
839 /*! Next sequence number they have not yet acknowledged */
840 unsigned char rseqno;
841 /*! Next incoming sequence number */
842 unsigned char iseqno;
843 /*! Last incoming sequence number we have acknowledged */
844 unsigned char aseqno;
845
847 /*! Peer name */
849 /*! Default Context */
851 /*! Caller ID if available */
854 /*! Hidden Caller ID (i.e. ANI) if appropriate */
856 /*! DNID */
858 /*! RDNIS */
860 /*! Requested Extension */
862 /*! Expected Username */
864 /*! Expected Secret */
866 /*! MD5 challenge */
868 /*! Public keys permitted keys for incoming authentication */
870 /*! Private key for outgoing authentication */
872 /*! Preferred language */
874 /*! Hostname/peername for naming purposes */
876
881 /*! received OSP token */
883 /*! Default parkinglot */
885 );
886 /*! AUTHREJ all AUTHREP frames */
887 int authrej;
888 /*! permitted authentication methods */
889 int authmethods;
890 /*! effective authentication method */
891 int eff_auth_method;
892 /*! permitted encryption methods */
893 int encmethods;
894 /*! Encryption AES-128 Key */
896 /*! Decryption AES-128 Key corresponding to ecx */
898 /*! Decryption AES-128 Key used to decrypt peer frames */
900 /*! scheduler id associated with iax_key_rotate
901 * for encrypted calls*/
902 int keyrotateid;
903 /*! 32 bytes of semi-random data */
904 unsigned char semirand[32];
905 /*! Associated registry */
906 struct iax2_registry *reg;
907 /*! Associated peer for poking */
908 struct iax2_peer *peerpoke;
909 /*! IAX_ flags */
910 uint64_t flags;
911 int adsi;
912
913 /*! Transferring status */
915 /*! Transfer identifier */
916 int transferid;
917 /*! Who we are IAX transferring to */
918 struct ast_sockaddr transfer;
919 /*! What's the new call number for the transfer */
920 unsigned short transfercallno;
921 /*! Transfer encrypt AES-128 Key */
923
924 /*! Status of knowledge of peer ADSI capability */
925 int peeradsicpe;
926
927 /*! Callno of native bridge peer. (Valid if nonzero) */
928 unsigned short bridgecallno;
929
930 int pingid; /*!< Transmit PING request */
931 int lagid; /*!< Retransmit lag request */
932 int autoid; /*!< Auto hangup for Dialplan requestor */
933 int authid; /*!< Authentication rejection ID */
934 int authfail; /*!< Reason to report failure */
935 int initid; /*!< Initial peer auto-congest ID (based on qualified peers) */
936 int calling_ton;
937 int calling_tns;
938 int calling_pres;
939 int calling_ani2;
940 int amaflags;
942 /*! variables inherited from the user definition */
943 struct ast_variable *vars;
944 /*! variables transmitted in a NEW packet */
945 struct ast_variable *iaxvars;
946 /*! last received remote rr */
947 struct iax_rr remote_rr;
948 /*! Current base time: (just for stats) */
949 int min;
950 /*! Dropped frame count: (just for stats) */
951 int frames_dropped;
952 /*! received frame count: (just for stats) */
953 int frames_received;
954 /*! Destroying this call initiated. */
956 /*! num bytes used for calltoken ie, even an empty ie should contain 2 */
957 unsigned char calltoken_ie_len;
958 /*! hold all signaling frames from the pbx thread until we have a destination callno */
959 char hold_signaling;
960 /*! frame queue for signaling frames from pbx thread waiting for destination callno */
962};
963
965 struct ast_frame f;
967};
968
969enum callno_type {
972};
973
974#define PTR_TO_CALLNO_ENTRY(a) ((uint16_t)(unsigned long)(a))
975#define CALLNO_ENTRY_TO_PTR(a) ((void *)(unsigned long)(a))
976
977#define CALLNO_ENTRY_SET_VALIDATED(a) ((a) |= 0x8000)
978#define CALLNO_ENTRY_IS_VALIDATED(a) ((a) & 0x8000)
979#define CALLNO_ENTRY_GET_CALLNO(a) ((a) & 0x7FFF)
980
981struct call_number_pool {
982 size_t capacity;
983 size_t available;
985};
986
988
989/*! table of available call numbers */
990static struct call_number_pool callno_pool;
991
992/*! table of available trunk call numbers */
994
995/*!
996 * \brief a list of frames that may need to be retransmitted
997 *
998 * \note The contents of this list do not need to be explicitly destroyed
999 * on module unload. This is because all active calls are destroyed, and
1000 * all frames in this queue will get destroyed as a part of that process.
1001 *
1002 * \note Contents protected by the iaxsl[] locks
1003 */
1005
1007
1008static int randomcalltokendata;
1009
1010static time_t max_calltoken_delay = 10;
1011
1012/*!
1013 * This module will get much higher performance when doing a lot of
1014 * user and peer lookups if the number of buckets is increased from 1.
1015 * However, to maintain old behavior for Asterisk 1.4, these are set to
1016 * 1 by default. When using multiple buckets, search order through these
1017 * containers is considered random, so you will not be able to depend on
1018 * the order the entries are specified in iax.conf for matching order. */
1019#ifdef LOW_MEMORY
1020#define MAX_PEER_BUCKETS 17
1021#else
1022#define MAX_PEER_BUCKETS 563
1023#endif
1024static struct ao2_container *peers;
1025
1026#define MAX_USER_BUCKETS MAX_PEER_BUCKETS
1027static struct ao2_container *users;
1028
1029/*! Table containing peercnt objects for every ip address consuming a callno */
1030static struct ao2_container *peercnts;
1031
1032/*! Table containing custom callno limit rules for a range of ip addresses. */
1033static struct ao2_container *callno_limits;
1034
1035/*! Table containing ip addresses not requiring calltoken validation */
1036static struct ao2_container *calltoken_ignores;
1037
1038static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
1039
1040static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
1041
1042static uint16_t global_maxcallno;
1043
1044/*! Total num of call numbers allowed to be allocated without calltoken validation */
1045static uint16_t global_maxcallno_nonval;
1046
1047static uint16_t total_nonval_callno_used = 0;
1048
1049/*! peer connection private, keeps track of all the call numbers
1050 * consumed by a single ip address */
1051struct peercnt {
1052 /*! ip address consuming call numbers */
1053 struct ast_sockaddr addr;
1054 /*! Number of call numbers currently used by this ip address */
1055 uint16_t cur;
1056 /*! Max call numbers allowed for this ip address */
1057 uint16_t limit;
1058 /*! Specifies whether limit is set by a registration or not, if so normal
1059 * limit setting rules do not apply to this address. */
1060 unsigned char reg;
1061};
1062
1063/*! used by both callno_limits and calltoken_ignores containers */
1064struct addr_range {
1065 /*! ip address range for custom callno limit rule */
1066 struct ast_ha ha;
1067 /*! callno limit for this ip address range, only used in callno_limits container */
1068 uint16_t limit;
1069 /*! delete me marker for reloads */
1070 unsigned char delme;
1071};
1072
1073enum {
1074 /*! Extension exists */
1075 CACHE_FLAG_EXISTS = (1 << 0),
1076 /*! Extension is nonexistent */
1077 CACHE_FLAG_NONEXISTENT = (1 << 1),
1078 /*! Extension can exist */
1079 CACHE_FLAG_CANEXIST = (1 << 2),
1080 /*! Waiting to hear back response */
1081 CACHE_FLAG_PENDING = (1 << 3),
1082 /*! Timed out */
1083 CACHE_FLAG_TIMEOUT = (1 << 4),
1084 /*! Request transmitted */
1085 CACHE_FLAG_TRANSMITTED = (1 << 5),
1086 /*! Timeout */
1087 CACHE_FLAG_UNKNOWN = (1 << 6),
1088 /*! Matchmore */
1089 CACHE_FLAG_MATCHMORE = (1 << 7),
1090};
1091
1092struct iax2_dpcache {
1095 struct timeval orig;
1096 struct timeval expiry;
1097 int flags;
1098 unsigned short callno;
1099 int waiters[256];
1102};
1103
1105
1106static void reg_source_db(struct iax2_peer *p);
1107static struct iax2_peer *realtime_peer(const char *peername, struct ast_sockaddr *addr);
1108static struct iax2_user *realtime_user(const char *username, struct ast_sockaddr *addr);
1109
1110static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
1111static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags);
1112static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
1113
1119};
1120
1121enum iax2_thread_type {
1124};
1125
1126struct iax2_pkt_buf {
1128 size_t len;
1129 unsigned char buf[1];
1130};
1131
1132struct iax2_thread {
1136#ifdef SCHED_MULTITHREADED
1137 void (*schedfunc)(const void *);
1138 const void *scheddata;
1139#endif
1140#ifdef DEBUG_SCHED_MULTITHREAD
1141 char curfunc[80];
1142#endif
1143 int actions;
1144 pthread_t threadid;
1145 int threadnum;
1146 struct ast_sockaddr ioaddr;
1147 unsigned char readbuf[4096];
1148 unsigned char *buf;
1149 ssize_t buf_len;
1150 size_t buf_size;
1151 int iofd;
1152 time_t checktime;
1157 /*! if this thread is processing a full frame,
1158 some information about that frame will be stored
1159 here, so we can avoid dispatching any more full
1160 frames for that callno to other threads */
1161 struct {
1162 unsigned short callno;
1163 struct ast_sockaddr addr;
1164 unsigned char type;
1165 unsigned char csub;
1166 } ffinfo;
1167 /*! Queued up full frames for processing. If more full frames arrive for
1168 * a call which this thread is already processing a full frame for, they
1169 * are queued up here. */
1171 unsigned char stop;
1172};
1173
1174/* Thread lists */
1178
1179static void *iax2_process_thread(void *data);
1180static void iax2_destroy(int callno);
1181
1183{
1187}
1188
1189/*!
1190 * \brief an array of iax2 pvt structures
1191 *
1192 * The container for active chan_iax2_pvt structures is implemented as an
1193 * array for extremely quick direct access to the correct pvt structure
1194 * based on the local call number. The local call number is used as the
1195 * index into the array where the associated pvt structure is stored.
1196 */
1197static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
1198
1200{
1201 return iaxs[callno]->callid;
1202}
1203
1205{
1207}
1208
1209static void iax_pvt_callid_new(int callno)
1210{
1212 char buffer[AST_CALLID_BUFFER_LENGTH];
1213 ast_callid_strnprint(buffer, sizeof(buffer), callid);
1215}
1216
1217/*!
1218 * \brief Another container of iax2_pvt structures
1219 *
1220 * Active IAX2 pvt structs are also stored in this container, if they are a part
1221 * of an active call where we know the remote side's call number. The reason
1222 * for this is that incoming media frames do not contain our call number. So,
1223 * instead of having to iterate the entire iaxs array, we use this container to
1224 * look up calls where the remote side is using a given call number.
1225 */
1226static struct ao2_container *iax_peercallno_pvts;
1227
1228/*!
1229 * \brief chan_iax2_pvt structure locks
1230 *
1231 * These locks are used when accessing a pvt structure in the iaxs array.
1232 * The index used here is the same as used in the iaxs array. It is the
1233 * local call number for the associated pvt struct.
1234 */
1236
1237/*!
1238 * \brief Another container of iax2_pvt structures
1239 *
1240 * Active IAX2 pvt structs used during transferring a call are stored here.
1241 */
1243
1244/* Flag to use with trunk calls, keeping these calls high up. It halves our effective use
1245 but keeps the division between trunked and non-trunked better. */
1246#define TRUNK_CALL_START (IAX_MAX_CALLS / 2)
1247
1248/* Debug routines... */
1249static struct ast_sockaddr debugaddr;
1250
1251static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct ast_sockaddr *addr, int datalen)
1252{
1253 if (iaxdebug ||
1254 (addr && !ast_sockaddr_isnull(&debugaddr) &&
1257 !ast_sockaddr_cmp_addr(&debugaddr, addr))) {
1258
1259 if (iaxdebug) {
1260 iax_showframe(f, fhi, rx, addr, datalen);
1261 } else {
1262 iaxdebug = 1;
1263 iax_showframe(f, fhi, rx, addr, datalen);
1264 iaxdebug = 0;
1265 }
1266 }
1267}
1268
1269static void iax_debug_output(const char *data)
1270{
1271 if (iaxdebug)
1272 ast_verbose("%s", data);
1273}
1274
1275static void iax_error_output(const char *data)
1276{
1277 ast_log(LOG_WARNING, "%s", data);
1278}
1279
1280static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
1281{
1282 va_list args;
1283 char buf[1024];
1284
1285 va_start(args, fmt);
1286 vsnprintf(buf, sizeof(buf), fmt, args);
1287 va_end(args);
1288
1289 ast_log(LOG_ERROR, "%s", buf);
1290}
1291
1292static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
1293{
1294 va_list args;
1295 char buf[1024];
1296
1297 va_start(args, fmt);
1298 vsnprintf(buf, sizeof(buf), fmt, args);
1299 va_end(args);
1300
1301 ast_log(LOG_WARNING, "%s", buf);
1302}
1303
1304static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
1305{
1306 va_list args;
1307 char buf[1024];
1308
1309 va_start(args, fmt);
1310 vsnprintf(buf, sizeof(buf), fmt, args);
1311 va_end(args);
1312
1313 ast_verbose("%s", buf);
1314}
1315
1316static int expire_registry(const void *data);
1317static int iax2_answer(struct ast_channel *c);
1318static int iax2_call(struct ast_channel *c, const char *dest, int timeout);
1319static int iax2_devicestate(const char *data);
1320static int iax2_digit_begin(struct ast_channel *c, char digit);
1321static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
1322static int iax2_do_register(struct iax2_registry *reg);
1323static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
1324static int iax2_hangup(struct ast_channel *c);
1325static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
1326static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
1327static int iax2_provision(struct ast_sockaddr *end, int sockfd, const char *dest, const char *template, int force);
1328static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
1329static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
1330static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
1331static int iax2_sendtext(struct ast_channel *c, const char *text);
1332static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
1333static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen);
1334static int iax2_transfer(struct ast_channel *c, const char *dest);
1335static int iax2_write(struct ast_channel *c, struct ast_frame *f);
1336static int iax2_sched_add(struct ast_sched_context *sched, int when, ast_sched_cb callback, const void *data);
1337
1338static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
1339static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
1340static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
1341static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
1342static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
1343static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
1344static 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);
1345static struct ast_frame *iax2_read(struct ast_channel *c);
1346static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
1347static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
1348static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime);
1349static void *iax2_dup_variable_datastore(void *);
1350static void prune_peers(void);
1351static void prune_users(void);
1352static void iax2_free_variable_datastore(void *);
1353
1354static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
1355static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
1356static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
1357static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
1358static void build_rand_pad(unsigned char *buf, ssize_t len);
1359static int get_unused_callno(enum callno_type type, int validated, callno_entry *entry);
1360static int replace_callno(const void *obj);
1361static void sched_delay_remove(struct ast_sockaddr *addr, callno_entry entry);
1362static void network_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message);
1363static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message);
1364
1365static struct ast_channel_tech iax2_tech = {
1366 .type = "IAX2",
1367 .description = tdesc,
1368 .properties = AST_CHAN_TP_WANTSJITTER,
1369 .requester = iax2_request,
1370 .devicestate = iax2_devicestate,
1371 .send_digit_begin = iax2_digit_begin,
1372 .send_digit_end = iax2_digit_end,
1373 .send_text = iax2_sendtext,
1374 .send_image = iax2_sendimage,
1375 .send_html = iax2_sendhtml,
1376 .call = iax2_call,
1377 .hangup = iax2_hangup,
1378 .answer = iax2_answer,
1379 .read = iax2_read,
1380 .write = iax2_write,
1381 .write_video = iax2_write,
1382 .indicate = iax2_indicate,
1383 .setoption = iax2_setoption,
1384 .queryoption = iax2_queryoption,
1385 .transfer = iax2_transfer,
1386 .fixup = iax2_fixup,
1387 .func_channel_read = acf_channel_read,
1388};
1389
1390/*!
1391 * \internal
1392 * \brief Obtain the owner channel lock if the owner exists.
1393 *
1394 * \param callno IAX2 call id.
1395 *
1396 * \note Assumes the iaxsl[callno] lock is already obtained.
1397 *
1398 * \note
1399 * IMPORTANT NOTE!!! Any time this function is used, even if
1400 * iaxs[callno] was valid before calling it, it may no longer be
1401 * valid after calling it. This function may unlock and lock
1402 * the mutex associated with this callno, meaning that another
1403 * thread may grab it and destroy the call.
1404 */
1405static void iax2_lock_owner(int callno)
1406{
1407 for (;;) {
1408 if (!iaxs[callno] || !iaxs[callno]->owner) {
1409 /* There is no owner lock to get. */
1410 break;
1411 }
1412 if (!ast_channel_trylock(iaxs[callno]->owner)) {
1413 /* We got the lock */
1414 break;
1415 }
1416 /* Avoid deadlock by pausing and trying again */
1417 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
1418 }
1419}
1420
1421/*!
1422 * \internal
1423 * \brief Check if a control subtype is allowed on the wire.
1424 *
1425 * \param subtype Control frame subtype to check if allowed to/from the wire.
1426 *
1427 * \retval non-zero if allowed.
1428 */
1429static int iax2_is_control_frame_allowed(int subtype)
1430{
1431 enum ast_control_frame_type control = subtype;
1432 int is_allowed;
1433
1434 /*
1435 * Note: If we compare the enumeration type, which does not have any
1436 * negative constants, the compiler may optimize this code away.
1437 * Therefore, we must perform an integer comparison here.
1438 */
1439 if (subtype == -1) {
1440 return -1;
1441 }
1442
1443 /* Default to not allowing control frames to pass. */
1444 is_allowed = 0;
1445
1446 /*
1447 * The switch default is not present in order to take advantage
1448 * of the compiler complaining of a missing enum case.
1449 */
1450 switch (control) {
1451 /*
1452 * These control frames make sense to send/receive across the link.
1453 */
1454 case AST_CONTROL_HANGUP:
1455 case AST_CONTROL_RING:
1457 case AST_CONTROL_ANSWER:
1458 case AST_CONTROL_BUSY:
1462 case AST_CONTROL_FLASH:
1463 case AST_CONTROL_WINK:
1464 case AST_CONTROL_OPTION:
1469 case AST_CONTROL_HOLD:
1470 case AST_CONTROL_UNHOLD:
1475 case AST_CONTROL_AOC:
1477 case AST_CONTROL_MCID:
1478 is_allowed = -1;
1479 break;
1480
1481 /*
1482 * These control frames do not make sense to send/receive across the link.
1483 */
1485 /* The control value is deprecated in favor of AST_CONTROL_T38_PARAMETERS. */
1487 /* Across an IAX link the source is still the same. */
1489 /* A success/fail status report from calling ast_transfer() on this machine. */
1490 case AST_CONTROL_CC:
1491 /* The payload contains pointers that are valid for the sending machine only. */
1493 /* Across an IAX link the source is still the same. */
1495 /* The action can only be done by the sending machine. */
1497 /* This frame would cause the call to unexpectedly hangup. */
1499 /* Only meaningful across a bridge on this machine for direct-media exchange. */
1501 /* Intended only for the sending machine's local channel structure. */
1503 /* Intended only for masquerades when calling ast_indicate_data(). */
1505 /* Intended only for internal stream topology manipulation. */
1507 /* Intended only for internal stream topology change notification. */
1514 case AST_CONTROL_PLAYBACK_BEGIN: /* Only supported by app_dial currently */
1515 /* None of these playback stream control frames should go across the link. */
1520 /* None of these media recording control frames should go across the link. */
1521 break;
1522 }
1523 return is_allowed;
1524}
1525
1526static void network_change_stasis_subscribe(void)
1527{
1528 if (!network_change_sub) {
1533 }
1534}
1535
1536static void network_change_stasis_unsubscribe(void)
1537{
1539}
1540
1541static void acl_change_stasis_subscribe(void)
1542{
1543 if (!acl_change_sub) {
1548 }
1549}
1550
1551static void acl_change_stasis_unsubscribe(void)
1552{
1554}
1555
1556static int network_change_sched_cb(const void *data)
1557{
1558 struct iax2_registry *reg;
1562 iax2_do_register(reg);
1563 }
1565
1566 return 0;
1567}
1568
1569static void network_change_stasis_cb(void *data, struct stasis_subscription *sub,
1570 struct stasis_message *message)
1571{
1572 /* This callback is only concerned with network change messages from the system topic. */
1574 return;
1575 }
1576
1577 ast_verb(1, "IAX, got a network change message, renewing all IAX registrations.\n");
1578 if (network_change_sched_id == -1) {
1580 }
1581}
1582
1583static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub,
1584 struct stasis_message *message)
1585{
1587 return;
1588 }
1589
1590 ast_log(LOG_NOTICE, "Reloading chan_iax2 in response to ACL change event.\n");
1591 reload_config(1);
1592}
1593
1595 .type = "IAX2_VARIABLE",
1596 .duplicate = iax2_dup_variable_datastore,
1598};
1599
1600static void *iax2_dup_variable_datastore(void *old)
1601{
1602 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
1603 struct ast_var_t *oldvar, *newvar;
1604
1605 newlist = ast_calloc(sizeof(*newlist), 1);
1606 if (!newlist) {
1607 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
1608 return NULL;
1609 }
1610
1611 AST_LIST_HEAD_INIT(newlist);
1612 AST_LIST_LOCK(oldlist);
1613 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
1614 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
1615 if (newvar)
1616 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
1617 else
1618 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
1619 }
1620 AST_LIST_UNLOCK(oldlist);
1621 return newlist;
1622}
1623
1624static void iax2_free_variable_datastore(void *old)
1625{
1626 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
1627 struct ast_var_t *oldvar;
1628
1629 AST_LIST_LOCK(oldlist);
1630 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
1631 ast_free(oldvar);
1632 }
1633 AST_LIST_UNLOCK(oldlist);
1634 AST_LIST_HEAD_DESTROY(oldlist);
1635 ast_free(oldlist);
1636}
1637
1638
1639/* WARNING: insert_idle_thread should only ever be called within the
1640 * context of an iax2_process_thread() thread.
1641 */
1642static void insert_idle_thread(struct iax2_thread *thread)
1643{
1644 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
1648 } else {
1652 }
1653
1654 return;
1655}
1656
1657static struct iax2_thread *find_idle_thread(void)
1658{
1659 struct iax2_thread *thread = NULL;
1660
1661 /* Pop the head of the idle list off */
1665
1666 /* If we popped a thread off the idle list, just return it */
1667 if (thread) {
1668 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
1669 return thread;
1670 }
1671
1672 /* Pop the head of the dynamic list off */
1676
1677 /* If we popped a thread off the dynamic list, just return it */
1678 if (thread) {
1679 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
1680 return thread;
1681 }
1682
1683 /* If we can't create a new dynamic thread for any reason, return no thread at all */
1685 return NULL;
1686
1687 /* Set default values */
1691
1692 /* Initialize lock and condition */
1693 ast_mutex_init(&thread->lock);
1694 ast_cond_init(&thread->cond, NULL);
1695 ast_mutex_init(&thread->init_lock);
1696 ast_cond_init(&thread->init_cond, NULL);
1697 ast_mutex_lock(&thread->init_lock);
1698
1699 /* Create thread and send it on it's way */
1701 ast_cond_destroy(&thread->cond);
1702 ast_mutex_destroy(&thread->lock);
1703 ast_mutex_unlock(&thread->init_lock);
1704 ast_cond_destroy(&thread->init_cond);
1705 ast_mutex_destroy(&thread->init_lock);
1707 return NULL;
1708 }
1709
1710 /* this thread is not processing a full frame (since it is idle),
1711 so ensure that the field for the full frame call number is empty */
1712 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
1713
1714 /* Wait for the thread to be ready before returning it to the caller */
1715 ast_cond_wait(&thread->init_cond, &thread->init_lock);
1716
1717 /* Done with init_lock */
1718 ast_mutex_unlock(&thread->init_lock);
1719
1720 return thread;
1721}
1722
1723#ifdef SCHED_MULTITHREADED
1724static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
1725{
1726 struct iax2_thread *thread;
1727 static time_t lasterror;
1728 time_t t;
1729
1731 if (thread != NULL) {
1732 thread->schedfunc = func;
1733 thread->scheddata = data;
1734 thread->iostate = IAX_IOSTATE_SCHEDREADY;
1735#ifdef DEBUG_SCHED_MULTITHREAD
1736 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
1737#endif
1738 signal_condition(&thread->lock, &thread->cond);
1739 return 0;
1740 }
1741 time(&t);
1742 if (t != lasterror) {
1743 lasterror = t;
1744 ast_debug(1, "Out of idle IAX2 threads for scheduling! (%s)\n", funcname);
1745 }
1746
1747 return -1;
1748}
1749#define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
1750#endif
1751
1752static int iax2_sched_replace(int id, struct ast_sched_context *con, int when,
1753 ast_sched_cb callback, const void *data)
1754{
1755 return ast_sched_replace(id, con, when, callback, data);
1756}
1757
1758static int iax2_sched_add(struct ast_sched_context *con, int when,
1759 ast_sched_cb callback, const void *data)
1760{
1761 return ast_sched_add(con, when, callback, data);
1762}
1763
1764/*!
1765 * \brief Acquire the iaxsl[callno] if call exists and not having ongoing hangup.
1766 * \param callno Call number to lock.
1767 * \retval 0 If call disappeared or has ongoing hangup procedure.
1768 * \retval 1 If call found and mutex is locked.
1769 */
1771{
1773
1774 /* We acquired the lock; but the call was already destroyed (we came after full hang up procedures)
1775 * or destroy initiated (in middle of hang up procedure. */
1776 if (!iaxs[callno] || iaxs[callno]->destroy_initiated) {
1777 ast_debug(3, "I wanted to lock callno %d, but it is dead or going to die.\n", callno);
1779 return 0;
1780 }
1781
1782 /* Lock acquired, and callno is alive and kicking. */
1783 return 1;
1784}
1785
1786static int send_ping(const void *data);
1787
1788static void __send_ping(const void *data)
1789{
1790 int callno = PTR_TO_CALLNO(data);
1791
1793 ast_debug(3, "Hangup initiated on call %d, aborting __send_ping\n", callno);
1794 return;
1795 }
1796
1797 /* Mark pingid as invalid scheduler id. */
1798 iaxs[callno]->pingid = -1;
1799
1800 /* callno is now locked. */
1801 if (iaxs[callno]->peercallno) {
1802 /* Send PING packet. */
1804
1805 /* Schedule sending next ping. */
1807 }
1808
1810}
1811
1812static int send_ping(const void *data)
1813{
1814#ifdef SCHED_MULTITHREADED
1815 if (schedule_action(__send_ping, data))
1816#endif
1817 __send_ping(data);
1818
1819 return 0;
1820}
1821
1822static void encmethods_to_str(int e, struct ast_str **buf)
1823{
1824 ast_str_set(buf, 0, "(");
1825 if (e & IAX_ENCRYPT_AES128) {
1826 ast_str_append(buf, 0, "aes128");
1827 }
1828 if (e & IAX_ENCRYPT_KEYROTATE) {
1829 ast_str_append(buf, 0, ",keyrotate");
1830 }
1831 if (ast_str_strlen(*buf) > 1) {
1832 ast_str_append(buf, 0, ")");
1833 } else {
1834 ast_str_set(buf, 0, "No");
1835 }
1836}
1837
1838static int get_encrypt_methods(const char *s)
1839{
1840 int e;
1841 if (!strcasecmp(s, "aes128"))
1843 else if (ast_true(s))
1845 else
1846 e = 0;
1847 return e;
1848}
1849
1850static int send_lagrq(const void *data);
1851
1852static void __send_lagrq(const void *data)
1853{
1854 int callno = PTR_TO_CALLNO(data);
1855
1857 ast_debug(3, "Hangup initiated on call %d, aborting __send_lagrq\n", callno);
1858 return;
1859 }
1860
1861 /* Mark lagid as invalid scheduler id. */
1862 iaxs[callno]->lagid = -1;
1863
1864 /* callno is now locked. */
1865 if (iaxs[callno]->peercallno) {
1866 /* Send LAGRQ packet. */
1868
1869 /* Schedule sending next lagrq. */
1871 }
1872
1874}
1875
1876static int send_lagrq(const void *data)
1877{
1878#ifdef SCHED_MULTITHREADED
1879 if (schedule_action(__send_lagrq, data))
1880#endif
1881 __send_lagrq(data);
1882 return 0;
1883}
1884
1885static unsigned char compress_subclass(iax2_format subclass)
1886{
1887 int x;
1888 int power=-1;
1889 /* If it's 64 or smaller, just return it */
1890 if (subclass < IAX_FLAG_SC_LOG)
1891 return subclass;
1892 /* Otherwise find its power */
1893 for (x = 0; x < IAX_MAX_SHIFT; x++) {
1894 if (subclass & (1LL << x)) {
1895 if (power > -1) {
1896 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass);
1897 return 0;
1898 } else
1899 power = x;
1900 }
1901 }
1902 return power | IAX_FLAG_SC_LOG;
1903}
1904
1905static iax2_format uncompress_subclass(unsigned char csub)
1906{
1907 /* If the SC_LOG flag is set, return 2^csub otherwise csub */
1908 if (csub & IAX_FLAG_SC_LOG) {
1909 /* special case for 'compressed' -1 */
1910 if (csub == 0xff)
1911 return -1;
1912 else
1913 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
1914 }
1915 else
1916 return csub;
1917}
1918
1919static struct ast_format *codec_choose_from_prefs(struct iax2_codec_pref *pref, struct ast_format_cap *cap)
1920{
1921 int x;
1922 struct ast_format *found_format = NULL;
1923
1924 for (x = 0; x < ARRAY_LEN(pref->order); ++x) {
1925 struct ast_format *pref_format;
1926 uint64_t pref_bitfield;
1927
1928 pref_bitfield = iax2_codec_pref_order_value_to_format_bitfield(pref->order[x]);
1929 if (!pref_bitfield) {
1930 break;
1931 }
1932
1933 pref_format = ast_format_compatibility_bitfield2format(pref_bitfield);
1934 if (!pref_format) {
1935 /* The bitfield is not associated with any format. */
1936 continue;
1937 }
1938 found_format = ast_format_cap_get_compatible_format(cap, pref_format);
1939 if (found_format) {
1940 break;
1941 }
1942 }
1943
1944 if (found_format && (ast_format_get_type(found_format) == AST_MEDIA_TYPE_AUDIO)) {
1945 return found_format;
1946 }
1947
1948 ast_debug(4, "Could not find preferred codec - Returning zero codec.\n");
1949 ao2_cleanup(found_format);
1950 return NULL;
1951}
1952
1954{
1955 struct ast_format_cap *cap;
1956 struct ast_format *tmpfmt;
1957 iax2_format format = 0;
1958
1961 tmpfmt = codec_choose_from_prefs(pref, cap);
1962 if (!tmpfmt) {
1963 ao2_ref(cap, -1);
1964 return 0;
1965 }
1966
1968 ao2_ref(tmpfmt, -1);
1969 ao2_ref(cap, -1);
1970 }
1971
1972 return format;
1973}
1974
1975const char *iax2_getformatname(iax2_format format)
1976{
1977 struct ast_format *tmpfmt;
1978
1980 if (!tmpfmt) {
1981 return "Unknown";
1982 }
1983
1984 return ast_format_get_name(tmpfmt);
1985}
1986
1987static const char *iax2_getformatname_multiple(iax2_format format, struct ast_str **codec_buf)
1988{
1990
1991 if (!cap) {
1992 return "(Nothing)";
1993 }
1995 ast_format_cap_get_names(cap, codec_buf);
1996 ao2_ref(cap, -1);
1997
1998 return ast_str_buffer(*codec_buf);
1999}
2000
2001static int iax2_parse_allow_disallow(struct iax2_codec_pref *pref, iax2_format *formats, const char *list, int allowing)
2002{
2003 int res, i;
2004 struct ast_format_cap *cap;
2005
2006 /* We want to add the formats to the cap in the preferred order */
2008 if (!cap || iax2_codec_pref_to_cap(pref, cap)) {
2009 ao2_cleanup(cap);
2010 return 1;
2011 }
2012
2013 res = ast_format_cap_update_by_allow_disallow(cap, list, allowing);
2014
2015 /* Adjust formats bitfield and pref list to match. */
2018
2019 for (i = 0; i < ast_format_cap_count(cap); i++) {
2020 struct ast_format *fmt = ast_format_cap_get_format(cap, i);
2021
2023 ao2_ref(fmt, -1);
2024 }
2025
2026 ao2_ref(cap, -1);
2027
2028 return res;
2029}
2030
2031/*!
2032 * \note The only member of the peer passed here guaranteed to be set is the name field
2033 */
2034static int peer_hash_cb(const void *obj, const int flags)
2035{
2036 const struct iax2_peer *peer = obj;
2037 const char *name = obj;
2038
2039 return ast_str_hash(flags & OBJ_KEY ? name : peer->name);
2040}
2041
2042/*!
2043 * \note The only member of the peer passed here guaranteed to be set is the name field
2044 */
2045static int peer_cmp_cb(void *obj, void *arg, int flags)
2046{
2047 struct iax2_peer *peer = obj, *peer2 = arg;
2048 const char *name = arg;
2049
2050 return !strcmp(peer->name, flags & OBJ_KEY ? name : peer2->name) ?
2051 CMP_MATCH | CMP_STOP : 0;
2052}
2053
2054/*!
2055 * \note The only member of the user passed here guaranteed to be set is the name field
2056 */
2057static int user_hash_cb(const void *obj, const int flags)
2058{
2059 const struct iax2_user *user = obj;
2060 const char *name = obj;
2061
2062 return ast_str_hash(flags & OBJ_KEY ? name : user->name);
2063}
2064
2065/*!
2066 * \note The only member of the user passed here guaranteed to be set is the name field
2067 */
2068static int user_cmp_cb(void *obj, void *arg, int flags)
2069{
2070 struct iax2_user *user = obj, *user2 = arg;
2071 const char *name = arg;
2072
2073 return !strcmp(user->name, flags & OBJ_KEY ? name : user2->name) ?
2074 CMP_MATCH | CMP_STOP : 0;
2075}
2076
2077/*!
2078 * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
2079 * so do not call it with a pvt lock held.
2080 */
2081static struct iax2_peer *find_peer(const char *name, int realtime)
2082{
2083 struct iax2_peer *peer = NULL;
2084
2085 peer = ao2_find(peers, name, OBJ_KEY);
2086
2087 /* Now go for realtime if applicable */
2088 if (!peer && realtime) {
2089 peer = realtime_peer(name, NULL);
2090 }
2091 return peer;
2092}
2093
2094static struct iax2_peer *peer_ref(struct iax2_peer *peer)
2095{
2096 ao2_ref(peer, +1);
2097 return peer;
2098}
2099
2100static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
2101{
2102 ao2_ref(peer, -1);
2103 return NULL;
2104}
2105
2106static struct iax2_user *find_user(const char *name)
2107{
2108 return ao2_find(users, name, OBJ_KEY);
2109}
2110
2111static inline struct iax2_user *user_unref(struct iax2_user *user)
2112{
2113 ao2_ref(user, -1);
2114 return NULL;
2115}
2116
2117static int iax2_getpeername(struct ast_sockaddr addr, char *host, int len)
2118{
2119 struct iax2_peer *peer = NULL;
2120 int res = 0;
2121 struct ao2_iterator i;
2122
2123 i = ao2_iterator_init(peers, 0);
2124 while ((peer = ao2_iterator_next(&i))) {
2125
2126 if (!ast_sockaddr_cmp(&peer->addr, &addr)) {
2127 ast_copy_string(host, peer->name, len);
2128 peer_unref(peer);
2129 res = 1;
2130 break;
2131 }
2132 peer_unref(peer);
2133 }
2135
2136 if (!peer) {
2137 peer = realtime_peer(NULL, &addr);
2138 if (peer) {
2139 ast_copy_string(host, peer->name, len);
2140 peer_unref(peer);
2141 res = 1;
2142 }
2143 }
2144
2145 return res;
2146}
2147
2148/* Call AST_SCHED_DEL on a scheduled task if it is found in scheduler. */
2149static int iax2_delete_from_sched(const void* data)
2150{
2151 int sched_id = (int)(long)data;
2152
2154
2155 return 0;
2156}
2157
2158/*!\note Assumes the lock on the pvt is already held, when
2159 * iax2_destroy_helper() is called. */
2160static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
2161{
2162 /* Decrement AUTHREQ count if needed */
2163 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) {
2164 struct iax2_user *user;
2165
2167 if (user) {
2168 ast_atomic_fetchadd_int(&user->curauthreq, -1);
2170 }
2171
2173 }
2174
2175
2176 /* Mark call destroy initiated flag. */
2177 pvt->destroy_initiated = 1;
2178
2179 /*
2180 * Schedule deleting the scheduled (but didn't run yet) PINGs or LAGRQs.
2181 * Already running tasks will be terminated because of destroy_initiated.
2182 *
2183 * Don't call AST_SCHED_DEL from this thread for pingid and lagid because
2184 * it leads to a deadlock between the scheduler thread callback locking
2185 * the callno mutex and this thread which holds the callno mutex one or
2186 * more times. It is better to have another thread delete the scheduled
2187 * callbacks which doesn't lock the callno mutex.
2188 */
2189 iax2_sched_add(sched, 0, iax2_delete_from_sched, (void*)(long)pvt->pingid);
2190 iax2_sched_add(sched, 0, iax2_delete_from_sched, (void*)(long)pvt->lagid);
2191
2192 pvt->pingid = -1;
2193 pvt->lagid = -1;
2194
2195 AST_SCHED_DEL(sched, pvt->autoid);
2196 AST_SCHED_DEL(sched, pvt->authid);
2197 AST_SCHED_DEL(sched, pvt->initid);
2198 AST_SCHED_DEL(sched, pvt->jbid);
2200}
2201
2202static void iax2_frame_free(struct iax_frame *fr)
2203{
2205 iax_frame_free(fr);
2206}
2207
2208static int scheduled_destroy(const void *vid)
2209{
2210 unsigned short callno = PTR_TO_CALLNO(vid);
2211 ast_mutex_lock(&iaxsl[callno]);
2212 if (iaxs[callno]) {
2213 ast_debug(1, "Really destroying %d now...\n", callno);
2214 iax2_destroy(callno);
2215 }
2216 ast_mutex_unlock(&iaxsl[callno]);
2217 return 0;
2218}
2219
2221{
2222 if (s->f.datalen) {
2223 ast_free(s->f.data.ptr);
2224 }
2225 ast_free(s);
2226}
2227
2228/*! \brief This function must be called once we are sure the other side has
2229 * given us a call number. All signaling is held here until that point. */
2230static void send_signaling(struct chan_iax2_pvt *pvt)
2231{
2232 struct signaling_queue_entry *s = NULL;
2233
2234 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
2235 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
2237 }
2238 pvt->hold_signaling = 0;
2239}
2240
2241/*! \brief All frames other than that of type AST_FRAME_IAX must be held until
2242 * we have received a destination call number. */
2243static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
2244{
2245 struct signaling_queue_entry *qe;
2246
2247 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
2248 return 1; /* do not queue this frame */
2249 } else if (!(qe = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
2250 return -1; /* out of memory */
2251 }
2252
2253 /* copy ast_frame into our queue entry */
2254 qe->f = *f;
2255 if (qe->f.datalen) {
2256 /* if there is data in this frame copy it over as well */
2257 if (!(qe->f.data.ptr = ast_malloc(qe->f.datalen))) {
2259 return -1;
2260 }
2261 memcpy(qe->f.data.ptr, f->data.ptr, qe->f.datalen);
2262 }
2264
2265 return 0;
2266}
2267
2268static void pvt_destructor(void *obj)
2269{
2270 struct chan_iax2_pvt *pvt = obj;
2271 struct iax_frame *cur = NULL;
2272 struct signaling_queue_entry *s = NULL;
2273
2274 ast_mutex_lock(&iaxsl[pvt->callno]);
2275
2277
2279 pvt->callno_entry = 0;
2280
2281 /* Already gone */
2283
2284 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) {
2285 /* Cancel any pending transmissions */
2286 cur->retries = -1;
2287 }
2288
2290
2291 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
2293 }
2294
2295 if (pvt->reg) {
2296 pvt->reg->callno = 0;
2297 }
2298
2299 if (!pvt->owner) {
2300 jb_frame frame;
2301 if (pvt->vars) {
2303 pvt->vars = NULL;
2304 }
2305
2306 while (jb_getall(pvt->jb, &frame) == JB_OK) {
2307 iax2_frame_free(frame.data);
2308 }
2309
2310 jb_destroy(pvt->jb);
2312 }
2313}
2314
2315static struct chan_iax2_pvt *new_iax(struct ast_sockaddr *addr, const char *host)
2316{
2317 struct chan_iax2_pvt *tmp;
2318 jb_conf jbconf;
2319
2320 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
2321 return NULL;
2322 }
2323
2324 tmp->pingid = -1;
2325 tmp->lagid = -1;
2326 tmp->autoid = -1;
2327 tmp->authid = -1;
2328 tmp->initid = -1;
2329 tmp->keyrotateid = -1;
2330 tmp->jbid = -1;
2331
2332 if (ast_string_field_init(tmp, 32)) {
2333 ao2_ref(tmp, -1);
2334 tmp = NULL;
2335 return NULL;
2336 }
2337
2338 tmp->prefs = prefs_global;
2339
2340 ast_string_field_set(tmp,exten, "s");
2342
2343 tmp->jb = jb_new();
2348 jb_setconf(tmp->jb,&jbconf);
2349
2351
2352 tmp->hold_signaling = 1;
2354
2355 return tmp;
2356}
2357
2358static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
2359{
2361 if (new) {
2362 size_t afdatalen = new->afdatalen;
2363 memcpy(new, fr, sizeof(*new));
2364 iax_frame_wrap(new, &fr->af);
2365 new->afdatalen = afdatalen;
2366 new->data = NULL;
2367 new->datalen = 0;
2368 new->direction = DIRECTION_INGRESS;
2369 new->retrans = -1;
2370 }
2371 return new;
2372}
2373/* keep these defined in this order. They are used in find_callno to
2374 * determine whether or not a new call number should be allowed. */
2375enum {
2376 /* do not allow a new call number, only search ones in use for match */
2377 NEW_PREVENT = 0,
2378 /* search for match first, then allow a new one to be allocated */
2379 NEW_ALLOW = 1,
2380 /* do not search for match, force a new call number */
2381 NEW_FORCE = 2,
2382 /* do not search for match, force a new call number. Signifies call number
2383 * has been calltoken validated */
2385};
2386
2387static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
2388{
2389 if (!ast_sockaddr_cmp(&cur->addr, addr)) {
2390 /* This is the main host */
2391 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
2392 (check_dcallno ? dcallno == cur->callno : 1) ) {
2393 /* That's us. Be sure we keep track of the peer call number */
2394 return 1;
2395 }
2396 }
2397 if (!ast_sockaddr_cmp(&cur->transfer, addr) && cur->transferring) {
2398 /* We're transferring */
2399 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
2400 return 1;
2401 }
2402 return 0;
2403}
2404
2405static int make_trunk(unsigned short callno, int locked)
2406{
2407 int x;
2408 int res= 0;
2409 callno_entry entry;
2410 if (iaxs[callno]->oseqno) {
2411 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
2412 return -1;
2413 }
2414 if (callno >= TRUNK_CALL_START) {
2415 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
2416 return -1;
2417 }
2418
2422 &entry)) {
2423 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
2424 return -1;
2425 }
2426
2427 x = CALLNO_ENTRY_GET_CALLNO(entry);
2428 ast_mutex_lock(&iaxsl[x]);
2429
2430 /*!
2431 * \note We delete these before switching the slot, because if
2432 * they fire in the meantime, they will generate a warning.
2433 */
2434 AST_SCHED_DEL(sched, iaxs[callno]->pingid);
2435 AST_SCHED_DEL(sched, iaxs[callno]->lagid);
2436 iaxs[callno]->lagid = iaxs[callno]->pingid = -1;
2437 iaxs[x] = iaxs[callno];
2438 iaxs[x]->callno = x;
2439
2440 /* since we copied over the pvt from a different callno, make sure the old entry is replaced
2441 * before assigning the new one */
2442 if (iaxs[x]->callno_entry) {
2444 sched,
2445 MIN_REUSE_TIME * 1000,
2448
2449 }
2450 iaxs[x]->callno_entry = entry;
2451
2452 iaxs[callno] = NULL;
2453 /* Update the two timers that should have been started */
2455 ping_time * 1000, send_ping, (void *)(long)x);
2457 lagrq_time * 1000, send_lagrq, (void *)(long)x);
2458
2459 if (locked)
2461 res = x;
2462 if (!locked)
2464
2465 /* We moved this call from a non-trunked to a trunked call */
2466 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
2467
2468 return res;
2469}
2470
2471static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
2472{
2473 if (!pvt->transfercallno) {
2474 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
2475 return;
2476 }
2477
2479}
2480
2481static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
2482{
2483 if (!pvt->transfercallno) {
2484 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
2485 return;
2486 }
2487
2489}
2490static void store_by_peercallno(struct chan_iax2_pvt *pvt)
2491{
2492 if (!pvt->peercallno) {
2493 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
2494 return;
2495 }
2496
2498}
2499
2500static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
2501{
2502 if (!pvt->peercallno) {
2503 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
2504 return;
2505 }
2506
2508}
2509
2510static int addr_range_delme_cb(void *obj, void *arg, int flags)
2511{
2512 struct addr_range *lim = obj;
2513 lim->delme = 1;
2514 return 0;
2515}
2516
2517static int addr_range_hash_cb(const void *obj, const int flags)
2518{
2519 const struct addr_range *lim = obj;
2520 return abs(ast_sockaddr_hash(&lim->ha.addr));
2521}
2522
2523static int addr_range_cmp_cb(void *obj, void *arg, int flags)
2524{
2525 struct addr_range *lim1 = obj, *lim2 = arg;
2526 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
2527 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
2528 CMP_MATCH | CMP_STOP : 0;
2529}
2530
2531static int peercnt_hash_cb(const void *obj, const int flags)
2532{
2533 const struct peercnt *peercnt = obj;
2534
2536 return 0;
2537 }
2538 return ast_sockaddr_hash(&peercnt->addr);
2539}
2540
2541static int peercnt_cmp_cb(void *obj, void *arg, int flags)
2542{
2543 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
2544 return !ast_sockaddr_cmp_addr(&peercnt1->addr, &peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
2545}
2546
2547static int addr_range_match_address_cb(void *obj, void *arg, int flags)
2548{
2549 struct addr_range *addr_range = obj;
2550 struct ast_sockaddr *addr = arg;
2551 struct ast_sockaddr tmp_addr;
2552
2553 ast_sockaddr_apply_netmask(addr, &addr_range->ha.netmask, &tmp_addr);
2554
2555 if (!ast_sockaddr_cmp_addr(&tmp_addr, &addr_range->ha.addr)) {
2556 return CMP_MATCH | CMP_STOP;
2557 }
2558 return 0;
2559}
2560
2561/*!
2562 * \internal
2563 *
2564 * \brief compares addr to calltoken_ignores table to determine if validation is required.
2565 */
2566static int calltoken_required(struct ast_sockaddr *addr, const char *name, int subclass)
2567{
2568 struct addr_range *addr_range;
2569 struct iax2_peer *peer = NULL;
2570 struct iax2_user *user = NULL;
2571 /* if no username is given, check for guest accounts */
2572 const char *find = S_OR(name, "guest");
2573 int res = 1; /* required by default */
2574 int optional = 0;
2576 /* There are only two cases in which calltoken validation is not required.
2577 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
2578 * the peer definition has not set the requirecalltoken option.
2579 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
2580 */
2581
2582 /* ----- Case 1 ----- */
2584 ao2_ref(addr_range, -1);
2585 optional = 1;
2586 }
2587
2588 /* ----- Case 2 ----- */
2589 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
2590 calltoken_required = user->calltoken_required;
2591 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, addr))) {
2592 calltoken_required = user->calltoken_required;
2593 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
2595 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, addr))) {
2597 }
2598
2599 if (peer) {
2600 peer_unref(peer);
2601 }
2602 if (user) {
2604 }
2605
2606 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);
2608 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
2609 res = 0;
2610 }
2611
2612 return res;
2613}
2614
2615/*!
2616 * \internal
2617 *
2618 * \brief set peercnt callno limit.
2619 *
2620 * \details
2621 * First looks in custom definitions. If not found, global limit
2622 * is used. Entries marked as reg already have
2623 * a custom limit set by a registration and are not modified.
2624 */
2625static void set_peercnt_limit(struct peercnt *peercnt)
2626{
2627 uint16_t limit = global_maxcallno;
2628 struct addr_range *addr_range;
2629 struct ast_sockaddr addr;
2630
2631 ast_sockaddr_copy(&addr, &peercnt->addr);
2632
2633 if (peercnt->reg && peercnt->limit) {
2634 return; /* this peercnt has a custom limit set by a registration */
2635 }
2636
2638 limit = addr_range->limit;
2639 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_sockaddr_stringify(&addr));
2640 ao2_ref(addr_range, -1);
2641 }
2642
2643 peercnt->limit = limit;
2644}
2645
2646/*!
2647 * \internal
2648 * \brief sets limits for all peercnts in table. done on reload to reflect changes in conf.
2649 */
2650static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
2651{
2652 struct peercnt *peercnt = obj;
2653
2655 ast_debug(1, "Reset limits for peercnts table\n");
2656
2657 return 0;
2658}
2659
2660/*!
2661 * \internal
2662 * \brief returns match if delme is set.
2663 */
2664static int prune_addr_range_cb(void *obj, void *arg, int flags)
2665{
2666 struct addr_range *addr_range = obj;
2667
2668 return addr_range->delme ? CMP_MATCH : 0;
2669}
2670
2671/*!
2672 * \internal
2673 * \brief modifies peercnt entry in peercnts table. Used to set custom limit or mark a registered ip
2674 */
2675static void peercnt_modify(unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
2676{
2677 /* this function turns off and on custom callno limits set by peer registration */
2678 struct peercnt *peercnt;
2679 struct peercnt tmp;
2680
2681 ast_sockaddr_copy(&tmp.addr, sockaddr);
2682
2683 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
2684 peercnt->reg = reg;
2685 if (limit) {
2686 peercnt->limit = limit;
2687 } else {
2689 }
2690 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_sockaddr_stringify_addr(sockaddr), peercnt->limit, peercnt->reg);
2691 ao2_ref(peercnt, -1); /* decrement ref from find */
2692 }
2693}
2694
2695/*!
2696 * \internal
2697 * \brief adds an ip to the peercnts table, increments connection count if it already exists
2698 *
2699 * \details First searches for the address in the peercnts table. If found
2700 * the current count is incremented. If not found a new peercnt is allocated
2701 * and linked into the peercnts table with a call number count of 1.
2702 */
2703static int peercnt_add(struct ast_sockaddr *addr)
2704{
2705 struct peercnt *peercnt;
2706 int res = 0;
2707 struct peercnt tmp;
2708
2710
2711 /* Reasoning for peercnts container lock: Two identical ip addresses
2712 * could be added by different threads at the "same time". Without the container
2713 * lock, both threads could alloc space for the same object and attempt
2714 * to link to table. With the lock, one would create the object and link
2715 * to table while the other would find the already created peercnt object
2716 * rather than creating a new one. */
2718 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
2720 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
2722 /* create and set defaults */
2725 /* guarantees it does not go away after unlocking table
2726 * ao2_find automatically adds this */
2728 } else {
2730 return -1;
2731 }
2732
2733 /* check to see if the address has hit its callno limit. If not increment cur. */
2734 if (peercnt->limit > peercnt->cur) {
2735 peercnt->cur++;
2736 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_sockaddr_stringify_addr(addr));
2737 } else { /* max num call numbers for this peer has been reached! */
2738 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_sockaddr_stringify_addr(addr));
2739 res = -1;
2740 }
2741
2742 /* clean up locks and ref count */
2745 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */
2746
2747 return res;
2748}
2749
2750/*!
2751 * \internal
2752 * \brief decrements a peercnts table entry
2753 */
2754static void peercnt_remove(struct peercnt *peercnt)
2755{
2756 struct ast_sockaddr addr;
2757
2758 ast_sockaddr_copy(&addr, &peercnt->addr);
2759
2760 /*
2761 * Container locked here since peercnt may be unlinked from
2762 * list. If left unlocked, peercnt_add could try and grab this
2763 * entry from the table and modify it at the "same time" this
2764 * thread attempts to unlink it.
2765 */
2767 peercnt->cur--;
2768 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_sockaddr_stringify_addr(&addr));
2769 /* if this was the last connection from the peer remove it from table */
2770 if (peercnt->cur == 0) {
2771 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */
2772 }
2774}
2775
2776/*!
2777 * \internal
2778 * \brief called by scheduler to decrement object
2779 */
2780static int peercnt_remove_cb(const void *obj)
2781{
2782 struct peercnt *peercnt = (struct peercnt *) obj;
2783
2785 ao2_ref(peercnt, -1); /* decrement ref from scheduler */
2786
2787 return 0;
2788}
2789
2790/*!
2791 * \internal
2792 * \brief decrements peercnts connection count, finds by addr
2793 */
2794static int peercnt_remove_by_addr(struct ast_sockaddr *addr)
2795{
2796 struct peercnt *peercnt;
2797 struct peercnt tmp;
2798
2800
2801 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
2803 ao2_ref(peercnt, -1); /* decrement ref from find */
2804 }
2805 return 0;
2806}
2807
2808/*!
2809 * \internal
2810 * \brief Create callno_limit entry based on configuration
2811 */
2812static void build_callno_limits(struct ast_variable *v)
2813{
2814 struct addr_range *addr_range = NULL;
2815 struct addr_range tmp;
2816 struct ast_ha *ha;
2817 int limit;
2818 int error;
2819 int found;
2820
2821 for (; v; v = v->next) {
2822 limit = -1;
2823 error = 0;
2824 found = 0;
2825 ha = ast_append_ha("permit", v->name, NULL, &error);
2826
2827 /* check for valid config information */
2828 if (error) {
2829 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
2830 continue;
2831 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
2832 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
2833 ast_free_ha(ha);
2834 continue;
2835 }
2836
2837 ast_copy_ha(ha, &tmp.ha);
2838 /* find or create the addr_range */
2839 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
2841 found = 1;
2842 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
2843 ast_free_ha(ha);
2844 return; /* out of memory */
2845 }
2846
2847 /* copy over config data into addr_range object */
2848 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
2849 ast_free_ha(ha); /* cleanup the tmp ha */
2850 addr_range->limit = limit;
2851 addr_range->delme = 0;
2852
2853 /* cleanup */
2854 if (found) {
2856 } else {
2858 }
2859 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
2860 }
2861}
2862
2863/*!
2864 * \internal
2865 * \brief Create calltoken_ignores entry based on configuration
2866 */
2867static int add_calltoken_ignore(const char *addr)
2868{
2869 struct addr_range tmp;
2870 struct addr_range *addr_range = NULL;
2871 struct ast_ha *ha = NULL;
2872 int error = 0;
2873
2874 if (ast_strlen_zero(addr)) {
2875 ast_log(LOG_WARNING, "invalid calltokenoptional (null)\n");
2876 return -1;
2877 }
2878
2879 ha = ast_append_ha("permit", addr, NULL, &error);
2880
2881 /* check for valid config information */
2882 if (error) {
2883 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
2884 return -1;
2885 }
2886
2887 ast_copy_ha(ha, &tmp.ha);
2888 /* find or create the addr_range */
2891 addr_range->delme = 0;
2893 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
2894 /* copy over config data into addr_range object */
2895 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
2897 } else {
2898 ast_free_ha(ha);
2899 return -1;
2900 }
2901
2902 ast_free_ha(ha);
2903 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
2904
2905 return 0;
2906}
2907
2908static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2909{
2910 struct ao2_iterator i;
2911 struct peercnt *peercnt;
2912 struct ast_sockaddr addr;
2913 int found = 0;
2914
2915 switch (cmd) {
2916 case CLI_INIT:
2917 e->command = "iax2 show callnumber usage";
2918 e->usage =
2919 "Usage: iax2 show callnumber usage [IP address]\n"
2920 " Shows current IP addresses which are consuming iax2 call numbers\n";
2921 return NULL;
2922 case CLI_GENERATE:
2923 return NULL;
2924 case CLI_HANDLER:
2925 if (a->argc < 4 || a->argc > 5)
2926 return CLI_SHOWUSAGE;
2927
2928 if (a->argc == 4) {
2929 ast_cli(a->fd, "%-45s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
2930 }
2931
2933 while ((peercnt = ao2_iterator_next(&i))) {
2934 ast_sockaddr_copy(&addr, &peercnt->addr);
2935
2936 if (a->argc == 5) {
2937 if (!strcasecmp(a->argv[4], ast_sockaddr_stringify(&addr))) {
2938 ast_cli(a->fd, "%-45s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
2939 ast_cli(a->fd, "%-45s %-12d %-12d\n", ast_sockaddr_stringify(&addr), peercnt->cur, peercnt->limit);
2940 ao2_ref(peercnt, -1);
2941 found = 1;
2942 break;
2943 }
2944 } else {
2945 ast_cli(a->fd, "%-45s %-12d %-12d\n", ast_sockaddr_stringify(&addr), peercnt->cur, peercnt->limit);
2946 }
2947 ao2_ref(peercnt, -1);
2948 }
2950
2951 if (a->argc == 4) {
2952 size_t pool_avail = callno_pool.available;
2953 size_t trunk_pool_avail = callno_pool_trunk.available;
2954
2955 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
2956 "Non-CallToken Validated Callno Used: %d\n",
2959
2960 ast_cli(a->fd, "Total Available Callno: %zu\n"
2961 "Regular Callno Available: %zu\n"
2962 "Trunk Callno Available: %zu\n",
2963 pool_avail + trunk_pool_avail,
2964 pool_avail,
2965 trunk_pool_avail);
2966 } else if (a->argc == 5 && !found) {
2967 ast_cli(a->fd, "No call number table entries for %s found\n", a->argv[4] );
2968 }
2969
2970
2971 return CLI_SUCCESS;
2972 default:
2973 return NULL;
2974 }
2975}
2976
2977static int get_unused_callno(enum callno_type type, int validated, callno_entry *entry)
2978{
2979 struct call_number_pool *pool = NULL;
2980 callno_entry swap;
2981 size_t choice;
2982
2983 switch (type) {
2984 case CALLNO_TYPE_NORMAL:
2985 pool = &callno_pool;
2986 break;
2987 case CALLNO_TYPE_TRUNK:
2988 pool = &callno_pool_trunk;
2989 break;
2990 default:
2991 ast_assert(0);
2992 break;
2993 }
2994
2995 /* If we fail, make sure this has a defined value */
2996 *entry = 0;
2997
2998 /* We lock here primarily to ensure thread safety of the
2999 * total_nonval_callno_used check and increment */
3001
3002 /* Bail out if we don't have any available call numbers */
3003 if (!pool->available) {
3004 ast_log(LOG_WARNING, "Out of call numbers\n");
3006 return 1;
3007 }
3008
3009 /* Only a certain number of non-validated call numbers should be allocated.
3010 * If there ever is an attack, this separates the calltoken validating users
3011 * from the non-calltoken validating users. */
3014 "NON-CallToken callnumber limit is reached. Current: %d Max: %d\n",
3018 return 1;
3019 }
3020
3021 /* We use a modified Fisher-Yates-Durstenfeld Shuffle to maintain a list of
3022 * available call numbers. The array of call numbers begins as an ordered
3023 * list from 1 -> n, and we keep a running tally of how many remain unclaimed
3024 * - let's call that x. When a call number is needed we pick a random index
3025 * into the array between 0 and x and use that as our call number. In a
3026 * typical FYD shuffle, we would swap the value that we are extracting with
3027 * the number at x, but in our case we swap and don't touch the value at x
3028 * because it is effectively invisible. We rely on the rest of the IAX2 core
3029 * to return the number to us at some point. Finally, we decrement x by 1
3030 * which establishes our new unused range.
3031 *
3032 * When numbers are returned to the pool, we put them just past x and bump x
3033 * by 1 so that this number is now available for re-use. */
3034
3035 choice = ast_random() % pool->available;
3036
3037 *entry = pool->numbers[choice];
3038 swap = pool->numbers[pool->available - 1];
3039
3040 pool->numbers[choice] = swap;
3041 pool->available--;
3042
3043 if (validated) {
3045 } else {
3047 }
3048
3050
3051 return 0;
3052}
3053
3054static int replace_callno(const void *obj)
3055{
3056 callno_entry entry = PTR_TO_CALLNO_ENTRY(obj);
3057 struct call_number_pool *pool;
3058
3059 /* We lock here primarily to ensure thread safety of the
3060 * total_nonval_callno_used check and decrement */
3062
3063 if (!CALLNO_ENTRY_IS_VALIDATED(entry)) {
3066 } else {
3068 "Attempted to decrement total non calltoken validated "
3069 "callnumbers below zero. Callno is: %d\n",
3071 }
3072 }
3073
3075 pool = &callno_pool;
3076 } else {
3077 pool = &callno_pool_trunk;
3078 }
3079
3080 ast_assert(pool->capacity > pool->available);
3081
3082 /* This clears the validated flag */
3083 entry = CALLNO_ENTRY_GET_CALLNO(entry);
3084
3085 pool->numbers[pool->available] = entry;
3086 pool->available++;
3087
3089
3090 return 0;
3091}
3092
3093static int create_callno_pools(void)
3094{
3095 uint16_t i;
3096
3098
3099 /* We start at 2. 0 and 1 are reserved. */
3100 for (i = 2; i < TRUNK_CALL_START; i++) {
3103 }
3104
3105 for (i = TRUNK_CALL_START; i < IAX_MAX_CALLS; i++) {
3108 }
3109
3112
3114
3115 return 0;
3116}
3117
3118/*!
3119 * \internal
3120 * \brief Schedules delayed removal of iax2_pvt call number data
3121 *
3122 * \note After MIN_REUSE_TIME has passed for a destroyed iax2_pvt, the callno is
3123 * available again, and the address from the previous connection must be decremented
3124 * from the peercnts table. This function schedules these operations to take place.
3125 */
3126static void sched_delay_remove(struct ast_sockaddr *addr, callno_entry entry)
3127{
3128 int i;
3129 struct peercnt *peercnt;
3130 struct peercnt tmp;
3131
3133
3134 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
3135 /* refcount is incremented with ao2_find. keep that ref for the scheduler */
3136 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_sockaddr_stringify_addr(addr), MIN_REUSE_TIME);
3138 if (i == -1) {
3139 ao2_ref(peercnt, -1);
3140 }
3141 }
3142
3144 sched,
3145 MIN_REUSE_TIME * 1000,
3147 CALLNO_ENTRY_TO_PTR(entry));
3148}
3149
3150/*!
3151 * \internal
3152 * \brief returns whether or not a frame is capable of starting a new IAX2 dialog.
3153 *
3154 * \note For this implementation, inbound pokes should _NOT_ be capable of allocating
3155 * a new callno.
3156 */
3157static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
3158{
3159 if (frametype != AST_FRAME_IAX) {
3160 return 0;
3161 }
3162 switch (subclass) {
3163 case IAX_COMMAND_NEW:
3164 case IAX_COMMAND_REGREQ:
3166 case IAX_COMMAND_REGREL:
3167 return 1;
3168 case IAX_COMMAND_POKE:
3169 if (!inbound) {
3170 return 1;
3171 }
3172 break;
3173 }
3174 return 0;
3175}
3176
3177/*!
3178 * \note Calling this function while holding another pvt lock can cause a deadlock.
3179 */
3180static int __find_callno(unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, int new, int sockfd, int return_locked, int check_dcallno)
3181{
3182 int res = 0;
3183 int x;
3184 /* this call is calltoken validated as long as it is either NEW_FORCE
3185 * or NEW_ALLOW_CALLTOKEN_VALIDATED */
3186 int validated = (new > NEW_ALLOW) ? 1 : 0;
3187 char host[80];
3188
3189 if (new <= NEW_ALLOW) {
3190 if (callno) {
3191 struct chan_iax2_pvt *pvt;
3192 struct chan_iax2_pvt tmp_pvt = {
3193 .callno = dcallno,
3194 .peercallno = callno,
3195 .transfercallno = callno,
3196 /* hack!! */
3197 .frames_received = check_dcallno,
3198 };
3199
3200 ast_sockaddr_copy(&tmp_pvt.addr, addr);
3201 /* this works for finding normal call numbers not involving transferring */
3202 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
3203 if (return_locked) {
3204 ast_mutex_lock(&iaxsl[pvt->callno]);
3205 }
3206 res = pvt->callno;
3207 ao2_ref(pvt, -1);
3208 pvt = NULL;
3209 return res;
3210 }
3211 /* this searches for transfer call numbers that might not get caught otherwise */
3212 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
3213 ast_sockaddr_copy(&tmp_pvt.transfer, addr);
3214 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
3215 if (return_locked) {
3216 ast_mutex_lock(&iaxsl[pvt->callno]);
3217 }
3218 res = pvt->callno;
3219 ao2_ref(pvt, -1);
3220 pvt = NULL;
3221 return res;
3222 }
3223 }
3224 /* This will occur on the first response to a message that we initiated,
3225 * such as a PING. */
3226 if (dcallno) {
3227 ast_mutex_lock(&iaxsl[dcallno]);
3228 }
3229 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(addr, callno, dcallno, iaxs[dcallno], check_dcallno)) {
3230 iaxs[dcallno]->peercallno = callno;
3231 res = dcallno;
3232 store_by_peercallno(iaxs[dcallno]);
3233 if (!res || !return_locked) {
3234 ast_mutex_unlock(&iaxsl[dcallno]);
3235 }
3236 return res;
3237 }
3238 if (dcallno) {
3239 ast_mutex_unlock(&iaxsl[dcallno]);
3240 }
3241 }
3242 if (!res && (new >= NEW_ALLOW)) {
3243 callno_entry entry;
3244
3245 /* It may seem odd that we look through the peer list for a name for
3246 * this *incoming* call. Well, it is weird. However, users don't
3247 * have an IP address/port number that we can match against. So,
3248 * this is just checking for a peer that has that IP/port and
3249 * assuming that we have a user of the same name. This isn't always
3250 * correct, but it will be changed if needed after authentication. */
3251 if (!iax2_getpeername(*addr, host, sizeof(host)))
3252 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(addr));
3253
3254 if (peercnt_add(addr)) {
3255 /* This address has hit its callnumber limit. When the limit
3256 * is reached, the connection is not added to the peercnts table.*/
3257 return 0;
3258 }
3259
3260 if (get_unused_callno(CALLNO_TYPE_NORMAL, validated, &entry)) {
3261 /* since we ran out of space, remove the peercnt
3262 * entry we added earlier */
3264 ast_log(LOG_WARNING, "No more space\n");
3265 return 0;
3266 }
3267 x = CALLNO_ENTRY_GET_CALLNO(entry);
3268 ast_mutex_lock(&iaxsl[x]);
3269
3270 iaxs[x] = new_iax(addr, host);
3271 if (iaxs[x]) {
3272 if (iaxdebug)
3273 ast_debug(1, "Creating new call structure %d\n", x);
3274 iaxs[x]->callno_entry = entry;
3275 iaxs[x]->sockfd = sockfd;
3277 iaxs[x]->peercallno = callno;
3278 iaxs[x]->callno = x;
3281 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
3282 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
3283 iaxs[x]->amaflags = amaflags;
3289
3290 if (iaxs[x]->peercallno) {
3292 }
3293 } else {
3294 ast_log(LOG_WARNING, "Out of resources\n");
3297 return 0;
3298 }
3299 if (!return_locked)
3301 res = x;
3302 }
3303 return res;
3304}
3305
3306static int find_callno(unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, int new, int sockfd, int full_frame) {
3307 return __find_callno(callno, dcallno, addr, new, sockfd, 0, full_frame);
3308}
3309
3310static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, int new, int sockfd, int full_frame) {
3311
3312 return __find_callno(callno, dcallno, addr, new, sockfd, 1, full_frame);
3313}
3314
3315/*!
3316 * \brief Queue a frame to a call's owning asterisk channel
3317 *
3318 * \pre This function assumes that iaxsl[callno] is locked when called.
3319 *
3320 * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
3321 * was valid before calling it, it may no longer be valid after calling it.
3322 * This function may unlock and lock the mutex associated with this callno,
3323 * meaning that another thread may grab it and destroy the call.
3324 */
3325static int iax2_queue_frame(int callno, struct ast_frame *f)
3326{
3328 if (iaxs[callno] && iaxs[callno]->owner) {
3331 }
3332 return 0;
3333}
3334
3335/*!
3336 * \brief Queue a hold frame on the ast_channel owner
3337 *
3338 * This function queues a hold frame on the owner of the IAX2 pvt struct that
3339 * is active for the given call number.
3340 *
3341 * \pre Assumes lock for callno is already held.
3342 *
3343 * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
3344 * was valid before calling it, it may no longer be valid after calling it.
3345 * This function may unlock and lock the mutex associated with this callno,
3346 * meaning that another thread may grab it and destroy the call.
3347 */
3348static int iax2_queue_hold(int callno, const char *musicclass)
3349{
3351 if (iaxs[callno] && iaxs[callno]->owner) {
3352 ast_queue_hold(iaxs[callno]->owner, musicclass);
3354 }
3355 return 0;
3356}
3357
3358/*!
3359 * \brief Queue an unhold frame on the ast_channel owner
3360 *
3361 * This function queues an unhold frame on the owner of the IAX2 pvt struct that
3362 * is active for the given call number.
3363 *
3364 * \pre Assumes lock for callno is already held.
3365 *
3366 * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
3367 * was valid before calling it, it may no longer be valid after calling it.
3368 * This function may unlock and lock the mutex associated with this callno,
3369 * meaning that another thread may grab it and destroy the call.
3370 */
3371static int iax2_queue_unhold(int callno)
3372{
3374 if (iaxs[callno] && iaxs[callno]->owner) {
3377 }
3378 return 0;
3379}
3380
3381/*!
3382 * \brief Queue a hangup frame on the ast_channel owner
3383 *
3384 * This function queues a hangup frame on the owner of the IAX2 pvt struct that
3385 * is active for the given call number.
3386 *
3387 * \pre Assumes lock for callno is already held.
3388 *
3389 * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
3390 * was valid before calling it, it may no longer be valid after calling it.
3391 * This function may unlock and lock the mutex associated with this callno,
3392 * meaning that another thread may grab it and destroy the call.
3393 */
3394static int iax2_queue_hangup(int callno)
3395{
3397 if (iaxs[callno] && iaxs[callno]->owner) {
3400 }
3401 return 0;
3402}
3403
3404/*!
3405 * \note This function assumes that iaxsl[callno] is locked when called.
3406 *
3407 * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
3408 * was valid before calling it, it may no longer be valid after calling it.
3409 * This function calls iax2_queue_frame(), which may unlock and lock the mutex
3410 * associated with this callno, meaning that another thread may grab it and destroy the call.
3411 */
3412static int __do_deliver(void *data)
3413{
3414 /* Just deliver the packet by using queueing. This is called by
3415 the IAX thread with the iaxsl lock held. */
3416 struct iax_frame *fr = data;
3417 fr->retrans = -1;
3420 iax2_queue_frame(fr->callno, &fr->af);
3421 /* Free our iax frame */
3422 iax2_frame_free(fr);
3423 /* And don't run again */
3424 return 0;
3425}
3426
3427static int handle_error(void)
3428{
3429 /* XXX Ideally we should figure out why an error occurred and then abort those
3430 rather than continuing to try. Unfortunately, the published interface does
3431 not seem to work XXX */
3432#if 0
3433 struct sockaddr_in *sin;
3434 int res;
3435 struct msghdr m;
3436 struct sock_extended_err e;
3437 m.msg_name = NULL;
3438 m.msg_namelen = 0;
3439 m.msg_iov = NULL;
3440 m.msg_control = &e;
3441 m.msg_controllen = sizeof(e);
3442 m.msg_flags = 0;
3443 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
3444 if (res < 0)
3445 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
3446 else {
3447 if (m.msg_controllen) {
3448 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
3449 if (sin)
3450 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
3451 else
3452 ast_log(LOG_WARNING, "No address detected??\n");
3453 } else {
3454 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
3455 }
3456 }
3457#endif
3458 return 0;
3459}
3460
3461static int transmit_trunk(struct iax_frame *f, struct ast_sockaddr *addr, int sockfd)
3462{
3463 int res;
3464 res = ast_sendto(sockfd, f->data, f->datalen, 0, addr);
3465
3466 if (res < 0) {
3467 ast_debug(1, "Received error: %s\n", strerror(errno));
3468 handle_error();
3469 } else
3470 res = 0;
3471 return res;
3472}
3473
3474static int send_packet(struct iax_frame *f)
3475{
3476 int res;
3477 int callno = f->callno;
3478
3479 /* Don't send if there was an error, but return error instead */
3480 if (!callno || !iaxs[callno] || iaxs[callno]->error)
3481 return -1;
3482
3483 /* Called with iaxsl held */
3484 if (iaxdebug) {
3485 ast_debug(8, "Sending %u on %d/%d to %s\n", f->ts, callno, iaxs[callno]->peercallno, ast_sockaddr_stringify(&iaxs[callno]->addr));
3486 }
3487 if (f->transfer) {
3488 iax_outputframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
3489 res = ast_sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0, &iaxs[callno]->transfer);
3490 } else {
3491 iax_outputframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
3492 res = ast_sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0, &iaxs[callno]->addr);
3493 }
3494 if (res < 0) {
3495 if (iaxdebug)
3496 ast_debug(1, "Received error: %s\n", strerror(errno));
3497 handle_error();
3498 } else
3499 res = 0;
3500
3501 return res;
3502}
3503
3504/*!
3505 * \note Since this function calls iax2_queue_hangup(), the pvt struct
3506 * for the given call number may disappear during its execution.
3507 */
3508static int iax2_predestroy(int callno)
3509{
3510 struct ast_channel *c = NULL;
3511 struct chan_iax2_pvt *pvt = iaxs[callno];
3512
3513 if (!pvt)
3514 return -1;
3515
3516 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
3519 }
3520
3521 if ((c = pvt->owner)) {
3524 pvt->owner = NULL;
3526 }
3527
3528 return 0;
3529}
3530
3531static void iax2_destroy(int callno)
3532{
3533 struct chan_iax2_pvt *pvt = NULL;
3534 struct ast_channel *owner = NULL;
3535
3536retry:
3537 if ((pvt = iaxs[callno])) {
3538#if 0
3539 /* iax2_destroy_helper gets called from this function later on. When
3540 * called twice, we get the (previously) familiar FRACK! errors in
3541 * devmode, from the scheduler. An alternative to this approach is to
3542 * reset the scheduler entries to -1 when they're deleted in
3543 * iax2_destroy_helper(). That approach was previously decided to be
3544 * "wrong" because "the memory is going to be deallocated anyway. Why
3545 * should we be resetting those values?" */
3547#endif
3548 }
3549
3550 owner = pvt ? pvt->owner : NULL;
3551
3552 if (owner) {
3553 if (ast_channel_trylock(owner)) {
3554 ast_debug(3, "Avoiding IAX destroy deadlock\n");
3555 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
3556 goto retry;
3557 }
3558 }
3559
3560 if (!owner) {
3561 iaxs[callno] = NULL;
3562 }
3563
3564 if (pvt) {
3565 if (!owner) {
3566 pvt->owner = NULL;
3567 } else {
3568 /* If there's an owner, prod it to give up */
3569 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
3570 * because we already hold the owner channel lock. */
3571 ast_queue_hangup(owner);
3572 }
3573
3574 if (pvt->peercallno) {
3576 }
3577
3578 if (pvt->transfercallno) {
3580 }
3581
3582 if (!owner) {
3583 ao2_ref(pvt, -1);
3584 pvt = NULL;
3585 }
3586 }
3587
3588 if (owner) {
3589 ast_channel_unlock(owner);
3590 }
3591}
3592
3593static int update_packet(struct iax_frame *f)
3594{
3595 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
3596 struct ast_iax2_full_hdr *fh = f->data;
3597 struct ast_frame af;
3598
3599 /* if frame is encrypted. decrypt before updating it. */
3600 if (f->encmethods) {
3601 decode_frame(&f->mydcx, fh, &af, &f->datalen);
3602 }
3603 /* Mark this as a retransmission */
3604 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
3605 /* Update iseqno */
3606 f->iseqno = iaxs[f->callno]->iseqno;
3607 fh->iseqno = f->iseqno;
3608
3609 /* Now re-encrypt the frame */
3610 if (f->encmethods) {
3611 /* since this is a retransmit frame, create a new random padding
3612 * before re-encrypting. */
3613 build_rand_pad(f->semirand, sizeof(f->semirand));
3614 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
3615 }
3616 return 0;
3617}
3618
3619static int attempt_transmit(const void *data);
3620static void __attempt_transmit(const void *data)
3621{
3622 /* Attempt to transmit the frame to the remote peer...
3623 Called without iaxsl held. */
3624 struct iax_frame *f = (struct iax_frame *)data;
3625 int freeme = 0;
3626 int callno = f->callno;
3627
3628 /* Make sure this call is still active */
3629 if (callno)
3631 if (callno && iaxs[callno]) {
3632 if (f->retries < 0) {
3633 /* Already ACK'd */
3634 freeme = 1;
3635 } else if (f->retries >= max_retries) {
3636 /* Too many attempts. Record an error. */
3637 if (f->transfer) {
3638 /* Transfer timeout */
3640 } else if (f->final) {
3642 } else {
3643 if (iaxs[callno]->owner) {
3644 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %u, subclass = %d, ts=%u, seqno=%d)\n",
3647 f->af.frametype,
3648 f->af.subclass.integer,
3649 f->ts,
3650 f->oseqno);
3651 }
3652 iaxs[callno]->error = ETIMEDOUT;
3653 if (iaxs[callno]->owner) {
3655 /* Hangup the fd */
3656 iax2_queue_frame(callno, &fr); /* XXX */
3657 /* Remember, owner could disappear */
3658 if (iaxs[callno] && iaxs[callno]->owner)
3660 } else {
3661 if (iaxs[callno]->reg) {
3662 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
3663 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
3665 }
3666 iax2_destroy(callno);
3667 }
3668 }
3669 freeme = 1;
3670 } else {
3671 /* Update it if it needs it */
3672 update_packet(f);
3673 /* Attempt transmission */
3674 send_packet(f);
3675 f->retries++;
3676 /* Try again later after 10 times as long */
3677 f->retrytime *= 10;
3678 if (f->retrytime > MAX_RETRY_TIME)
3680 /* Transfer messages max out at one second */
3681 if (f->transfer && (f->retrytime > 1000))
3682 f->retrytime = 1000;
3684 }
3685 } else {
3686 /* Make sure it gets freed */
3687 f->retries = -1;
3688 freeme = 1;
3689 }
3690
3691 if (freeme) {
3692 /* Don't attempt delivery, just remove it from the queue */
3693 AST_LIST_REMOVE(&frame_queue[callno], f, list);
3694 ast_mutex_unlock(&iaxsl[callno]);
3695 f->retrans = -1; /* this is safe because this is the scheduled function */
3696 /* Free the IAX frame */
3697 iax2_frame_free(f);
3698 } else if (callno) {
3699 ast_mutex_unlock(&iaxsl[callno]);
3700 }
3701}
3702
3703static int attempt_transmit(const void *data)
3704{
3705#ifdef SCHED_MULTITHREADED
3707#endif
3709 return 0;
3710}
3711
3712static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3713{
3714 struct iax2_peer *peer = NULL;
3715 struct iax2_user *user = NULL;
3716 static const char * const choices[] = { "all", NULL };
3717 char *cmplt;
3718
3719 switch (cmd) {
3720 case CLI_INIT:
3721 e->command = "iax2 prune realtime";
3722 e->usage =
3723 "Usage: iax2 prune realtime [<peername>|all]\n"
3724 " Prunes object(s) from the cache\n";
3725 return NULL;
3726 case CLI_GENERATE:
3727 if (a->pos == 3) {
3728 cmplt = ast_cli_complete(a->word, choices, a->n);
3729 if (!cmplt)
3730 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
3731 return cmplt;
3732 }
3733 return NULL;
3734 }
3735 if (a->argc != 4)
3736 return CLI_SHOWUSAGE;
3737 if (!strcmp(a->argv[3], "all")) {
3738 prune_users();
3739 prune_peers();
3740 ast_cli(a->fd, "Cache flushed successfully.\n");
3741 return CLI_SUCCESS;
3742 }
3743 peer = find_peer(a->argv[3], 0);
3744 user = find_user(a->argv[3]);
3745 if (peer || user) {
3746 if (peer) {
3750 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
3751 } else {
3752 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
3753 }
3754 peer_unref(peer);
3755 }
3756 if (user) {
3759 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
3760 } else {
3761 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
3762 }
3765 }
3766 } else {
3767 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
3768 }
3769
3770 return CLI_SUCCESS;
3771}
3772
3773static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3774{
3775 switch (cmd) {
3776 case CLI_INIT:
3777 e->command = "iax2 test losspct";
3778 e->usage =
3779 "Usage: iax2 test losspct <percentage>\n"
3780 " For testing, throws away <percentage> percent of incoming packets\n";
3781 return NULL;
3782 case CLI_GENERATE:
3783 return NULL;
3784 }
3785 if (a->argc != 4)
3786 return CLI_SHOWUSAGE;
3787
3788 test_losspct = atoi(a->argv[3]);
3789
3790 return CLI_SUCCESS;
3791}
3792
3793#ifdef IAXTESTS
3794static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3795{
3796 switch (cmd) {
3797 case CLI_INIT:
3798 e->command = "iax2 test late";
3799 e->usage =
3800 "Usage: iax2 test late <ms>\n"
3801 " For testing, count the next frame as <ms> ms late\n";
3802 return NULL;
3803 case CLI_GENERATE:
3804 return NULL;
3805 }
3806
3807 if (a->argc != 4)
3808 return CLI_SHOWUSAGE;
3809
3810 test_late = atoi(a->argv[3]);
3811
3812 return CLI_SUCCESS;
3813}
3814
3815static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3816{
3817 switch (cmd) {
3818 case CLI_INIT:
3819 e->command = "iax2 test resync";
3820 e->usage =
3821 "Usage: iax2 test resync <ms>\n"
3822 " For testing, adjust all future frames by <ms> ms\n";
3823 return NULL;
3824 case CLI_GENERATE:
3825 return NULL;
3826 }
3827
3828 if (a->argc != 4)
3829 return CLI_SHOWUSAGE;
3830
3831 test_resync = atoi(a->argv[3]);
3832
3833 return CLI_SUCCESS;
3834}
3835
3836static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3837{
3838 switch (cmd) {
3839 case CLI_INIT:
3840 e->command = "iax2 test jitter";
3841 e->usage =
3842 "Usage: iax2 test jitter <ms> <pct>\n"
3843 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
3844 " percentage of packets. If <pct> is not specified, adds\n"
3845 " jitter to all packets.\n";
3846 return NULL;
3847 case CLI_GENERATE:
3848 return NULL;
3849 }
3850
3851 if (a->argc < 4 || a->argc > 5)
3852 return CLI_SHOWUSAGE;
3853
3854 test_jit = atoi(a->argv[3]);
3855 if (a->argc == 5)
3856 test_jitpct = atoi(a->argv[4]);
3857
3858 return CLI_SUCCESS;
3859}
3860#endif /* IAXTESTS */
3861
3862/*! \brief peer_status: Report Peer status in character string */
3863/* returns 1 if peer is online, -1 if unmonitored */
3864static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
3865{
3866 int res = 0;
3867 if (peer->maxms) {
3868 if (peer->lastms < 0) {
3869 ast_copy_string(status, "UNREACHABLE", statuslen);
3870 } else if (peer->lastms > peer->maxms) {
3871 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
3872 res = 1;
3873 } else if (peer->lastms) {
3874 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
3875 res = 1;
3876 } else {
3877 ast_copy_string(status, "UNKNOWN", statuslen);
3878 }
3879 } else {
3880 ast_copy_string(status, "Unmonitored", statuslen);
3881 res = -1;
3882 }
3883 return res;
3884}
3885
3886/*! \brief Show one peer in detail */
3887static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3888{
3889 char status[64];
3890 char cbuf[256];
3891 struct iax2_peer *peer;
3892 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
3893 struct ast_str *encmethods = ast_str_alloca(256);
3894 int load_realtime = 0;
3895
3896 switch (cmd) {
3897 case CLI_INIT:
3898 e->command = "iax2 show peer";
3899 e->usage =
3900 "Usage: iax2 show peer <name>\n"
3901 " Display details on specific IAX peer\n";
3902 return NULL;
3903 case CLI_GENERATE:
3904 if (a->pos == 3)
3905 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
3906 return NULL;
3907 }
3908
3909 if (a->argc < 4)
3910 return CLI_SHOWUSAGE;
3911
3912 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
3913
3914 peer = find_peer(a->argv[3], load_realtime);
3915 if (peer) {
3916 char *str_addr, *str_defaddr;
3917 char *str_port, *str_defport;
3918
3919 str_addr = ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr));
3920 str_port = ast_strdupa(ast_sockaddr_stringify_port(&peer->addr));
3921 str_defaddr = ast_strdupa(ast_sockaddr_stringify_addr(&peer->defaddr));
3922 str_defport = ast_strdupa(ast_sockaddr_stringify_port(&peer->defaddr));
3923
3924 encmethods_to_str(peer->encmethods, &encmethods);
3925 ast_cli(a->fd, "\n\n");
3926 ast_cli(a->fd, " * Name : %s\n", peer->name);
3927 ast_cli(a->fd, " Description : %s\n", peer->description);
3928 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
3929 ast_cli(a->fd, " Context : %s\n", peer->context);
3930 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
3931 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
3932 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
3933 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
3934 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
3935 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
3936 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
3937 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
3938 ast_cli(a->fd, " Expire : %d\n", peer->expire);
3939 ast_cli(a->fd, " ACL : %s\n", (ast_acl_list_is_empty(peer->acl) ? "No" : "Yes"));
3940 ast_cli(a->fd, " Addr->IP : %s Port %s\n", str_addr ? str_addr : "(Unspecified)", str_port);
3941 ast_cli(a->fd, " Defaddr->IP : %s Port %s\n", str_defaddr, str_defport);
3942 ast_cli(a->fd, " Username : %s\n", peer->username);
3943 ast_cli(a->fd, " Codecs : %s\n", iax2_getformatname_multiple(peer->capability, &codec_buf));
3944
3945 if (iax2_codec_pref_string(&peer->prefs, cbuf, sizeof(cbuf)) < 0) {
3946 strcpy(cbuf, "Error"); /* Safe */
3947 }
3948 ast_cli(a->fd, " Codec Order : %s\n", cbuf);
3949
3950 peer_status(peer, status, sizeof(status));
3951 ast_cli(a->fd, " Status : %s\n", status);
3952 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");
3953 ast_cli(a->fd, "\n");
3954 peer_unref(peer);
3955 } else {
3956 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
3957 ast_cli(a->fd, "\n");
3958 }
3959
3960 return CLI_SUCCESS;
3961}
3962
3963static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags)
3964{
3965 int which = 0;
3966 struct iax2_peer *peer;
3967 char *res = NULL;
3968 int wordlen = strlen(word);
3969 struct ao2_iterator i;
3970
3971 i = ao2_iterator_init(peers, 0);
3972 while ((peer = ao2_iterator_next(&i))) {
3973 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
3974 && (!flags || ast_test_flag64(peer, flags))) {
3975 res = ast_strdup(peer->name);
3976 peer_unref(peer);
3977 break;
3978 }
3979 peer_unref(peer);
3980 }
3982
3983 return res;
3984}
3985
3986static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3987{
3988 struct iax_frame *cur;
3989 int cnt = 0, dead = 0, final = 0, i = 0;
3990
3991 switch (cmd) {
3992 case CLI_INIT:
3993 e->command = "iax2 show stats";
3994 e->usage =
3995 "Usage: iax2 show stats\n"
3996 " Display statistics on IAX channel driver.\n";
3997 return NULL;
3998 case CLI_GENERATE:
3999 return NULL;
4000 }
4001
4002 if (a->argc != 3)
4003 return CLI_SHOWUSAGE;
4004
4005 for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
4006 ast_mutex_lock(&iaxsl[i]);
4008 if (cur->retries < 0)
4009 dead++;
4010 if (cur->final)
4011 final++;
4012 cnt++;
4013 }
4015 }
4016
4017 ast_cli(a->fd, " IAX Statistics\n");
4018 ast_cli(a->fd, "---------------------\n");
4019 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
4020 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
4022 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
4023
4027
4028 return CLI_SUCCESS;
4029}
4030
4031/*! \brief Set trunk MTU from CLI */
4032static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
4033{
4034 int mtuv;
4035
4036 switch (cmd) {
4037 case CLI_INIT:
4038 e->command = "iax2 set mtu";
4039 e->usage =
4040 "Usage: iax2 set mtu <value>\n"
4041 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
4042 " zero to disable. Disabling means that the operating system\n"
4043 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
4044 " packet exceeds the UDP payload size. This is substantially\n"
4045 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
4046 " greater for G.711 samples.\n";
4047 return NULL;
4048 case CLI_GENERATE:
4049 return NULL;
4050 }
4051
4052 if (a->argc != 4)
4053 return CLI_SHOWUSAGE;
4054 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
4055 mtuv = MAX_TRUNK_MTU;
4056 else
4057 mtuv = atoi(a->argv[3]);
4058
4059 if (mtuv == 0) {
4060 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
4062 return CLI_SUCCESS;
4063 }
4064 if (mtuv < 172 || mtuv > 4000) {
4065 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
4066 return CLI_SHOWUSAGE;
4067 }
4068 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
4069 global_max_trunk_mtu = mtuv;
4070 return CLI_SUCCESS;
4071}
4072
4073static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
4074{
4075 struct iax2_dpcache *dp = NULL;
4076 char tmp[1024], *pc = NULL;
4077 int s, x, y;
4078 struct timeval now = ast_tvnow();
4079
4080 switch (cmd) {
4081 case CLI_INIT:
4082 e->command = "iax2 show cache";
4083 e->usage =
4084 "Usage: iax2 show cache\n"
4085 " Display currently cached IAX Dialplan results.\n";
4086 return NULL;
4087 case CLI_GENERATE:
4088 return NULL;
4089 }
4090
4092
4093 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
4094
4095 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
4096 s = dp->expiry.tv_sec - now.tv_sec;
4097 tmp[0] = '\0';
4098 if (dp->flags & CACHE_FLAG_EXISTS)
4099 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
4100 if (dp->flags & CACHE_FLAG_NONEXISTENT)
4101 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
4102 if (dp->flags & CACHE_FLAG_CANEXIST)
4103 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
4104 if (dp->flags & CACHE_FLAG_PENDING)
4105 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
4106 if (dp->flags & CACHE_FLAG_TIMEOUT)
4107 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
4108 if (dp->flags & CACHE_FLAG_TRANSMITTED)
4109 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
4110 if (dp->flags & CACHE_FLAG_MATCHMORE)
4111 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
4112 if (dp->flags & CACHE_FLAG_UNKNOWN)
4113 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
4114 /* Trim trailing pipe */
4115 if (!ast_strlen_zero(tmp)) {
4116 tmp[strlen(tmp) - 1] = '\0';
4117 } else {
4118 ast_copy_string(tmp, "(none)", sizeof(tmp));
4119 }
4120 y = 0;
4121 pc = strchr(dp->peercontext, '@');
4122 if (!pc) {
4123 pc = dp->peercontext;
4124 } else {
4125 pc++;
4126 }
4127 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
4128 if (dp->waiters[x] > -1)
4129 y++;
4130 }
4131 if (s > 0) {
4132 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
4133 } else {
4134 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
4135 }
4136 }
4137
4139
4140 return CLI_SUCCESS;
4141}
4142
4143static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
4144
4145static void unwrap_timestamp(struct iax_frame *fr)
4146{
4147 /* Video mini frames only encode the lower 15 bits of the session
4148 * timestamp, but other frame types (e.g. audio) encode 16 bits. */
4149 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
4150 const int lower_mask = (1 << ts_shift) - 1;
4151 const int upper_mask = ~lower_mask;
4152 const int last_upper = iaxs[fr->callno]->last & upper_mask;
4153
4154 if ( (fr->ts & upper_mask) == last_upper ) {
4155 const int x = fr->ts - iaxs[fr->callno]->last;
4156 const int threshold = (ts_shift == 15) ? 25000 : 50000;
4157
4158 if (x < -threshold) {
4159 /* Sudden big jump backwards in timestamp:
4160 What likely happened here is that miniframe timestamp has circled but we haven't
4161 gotten the update from the main packet. We'll just pretend that we did, and
4162 update the timestamp appropriately. */
4163 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
4164 if (iaxdebug)
4165 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
4166 } else if (x > threshold) {
4167 /* Sudden apparent big jump forwards in timestamp:
4168 What's likely happened is this is an old miniframe belonging to the previous
4169 top 15 or 16-bit timestamp that has turned up out of order.
4170 Adjust the timestamp appropriately. */
4171 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
4172 if (iaxdebug)
4173 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
4174 }
4175 }
4176}
4177
4178static int get_from_jb(const void *p);
4179
4180static void update_jbsched(struct chan_iax2_pvt *pvt)
4181{
4182 int when;
4183
4184 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
4185
4186 when = jb_next(pvt->jb) - when;
4187
4188 if (when <= 0) {
4189 /* XXX should really just empty until when > 0.. */
4190 when = 1;
4191 }
4192
4193 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
4194 CALLNO_TO_PTR(pvt->callno));
4195}
4196
4197static void __get_from_jb(const void *p)
4198{
4199 int callno = PTR_TO_CALLNO(p);
4200 struct chan_iax2_pvt *pvt = NULL;
4201 struct iax_frame *fr;
4202 jb_frame frame;
4203 int ret;
4204 long ms;
4205 long next;
4206 struct timeval now = ast_tvnow();
4207 struct ast_format *voicefmt;
4208
4209 /* Make sure we have a valid private structure before going on */
4210 ast_mutex_lock(&iaxsl[callno]);
4211 pvt = iaxs[callno];
4212 if (!pvt) {
4213 /* No go! */
4214 ast_mutex_unlock(&iaxsl[callno]);
4215 return;
4216 }
4217
4218 pvt->jbid = -1;
4219
4220 /* round up a millisecond since ast_sched_runq does; */
4221 /* prevents us from spinning while waiting for our now */
4222 /* to catch up with runq's now */
4223 now.tv_usec += 1000;
4224
4225 ms = ast_tvdiff_ms(now, pvt->rxcore);
4226 if (ms >= (next = jb_next(pvt->jb))) {
4228 if (!voicefmt) {
4229 /* pvt->voiceformat won't be set if we haven't received any voice frames yet.
4230 * In this case, fall back to using the format negotiated during call setup,
4231 * so we don't stall the jitterbuffer completely. */
4233 if (!voicefmt) {
4234 /* As a last resort, we can use pvt->chosenformat.
4235 * This is set when we receive a call (either authenticated or unauthenticated),
4236 * so even if we haven't received any voice frames yet, we can still use the
4237 * right format.
4238 *
4239 * If we have to do this, in most cases, we aren't even processing voice frames
4240 * anyways, it's likely a non-voice frame. In that case, the format doesn't
4241 * really matter so much, because we could just pass 20 to jb_get instead
4242 * of calling ast_format_get_default_ms. However, until jb_get returns,
4243 * we don't actually know what kind of frame it is for sure, so use
4244 * the right format just to be safe. */
4246 }
4247 }
4248 if (!voicefmt) {
4249 /* This should never happen, since we should always be able to have an acceptable format to use. */
4250 ast_log(LOG_ERROR, "No voice, peer, or chosen format available on %s, backlogging frame\n", ast_channel_name(pvt->owner));
4251 goto cleanup; /* Don't crash if there's no voice format */
4252 }
4253 ret = jb_get(pvt->jb, &frame, ms, ast_format_get_default_ms(voicefmt));
4254 switch(ret) {
4255 case JB_OK:
4256 fr = frame.data;
4257 __do_deliver(fr);
4258 /* __do_deliver() can cause the call to disappear */
4259 pvt = iaxs[callno];
4260 break;
4261 case JB_INTERP:
4262 {
4263 struct ast_frame af = { 0, };
4264
4265 /* create an interpolation frame */
4267 af.subclass.format = voicefmt;
4268 af.samples = frame.ms * (ast_format_get_sample_rate(voicefmt) / 1000);
4269 af.src = "IAX2 JB interpolation";
4270 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
4272
4273 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
4274 * which we'd need to malloc, and then it would free it. That seems like a drag */
4275 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
4276 iax2_queue_frame(callno, &af);
4277 /* iax2_queue_frame() could cause the call to disappear */
4278 pvt = iaxs[callno];
4279 }
4280 }
4281 break;
4282 case JB_DROP:
4283 iax2_frame_free(frame.data);
4284 break;
4285 case JB_NOFRAME:
4286 case JB_EMPTY:
4287 /* do nothing */
4288 break;
4289 default:
4290 /* shouldn't happen */
4291 break;
4292 }
4293 }
4294cleanup:
4295 if (pvt)
4296 update_jbsched(pvt);
4297 ast_mutex_unlock(&iaxsl[callno]);
4298}
4299
4300static int get_from_jb(const void *data)
4301{
4302#ifdef SCHED_MULTITHREADED
4304#endif
4306 return 0;
4307}
4308
4309/*!
4310 * \note This function assumes fr->callno is locked
4311 *
4312 * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
4313 * was valid before calling it, it may no longer be valid after calling it.
4314 */
4315static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
4316{
4317 int type, len;
4318 int ret;
4319 int needfree = 0;
4320
4321 /*
4322 * Clear fr->af.data if there is no data in the buffer. Things
4323 * like AST_CONTROL_HOLD without a suggested music class must
4324 * have a NULL pointer.
4325 */
4326 if (!fr->af.datalen) {
4327 memset(&fr->af.data, 0, sizeof(fr->af.data));
4328 }
4329
4330 /* Attempt to recover wrapped timestamps */
4331 unwrap_timestamp(fr);
4332
4333 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
4334 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
4335 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
4336 else {
4337#if 0
4338 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
4339#endif
4340 fr->af.delivery = ast_tv(0,0);
4341 }
4342
4344 len = 0;
4345
4346 if(fr->af.frametype == AST_FRAME_VOICE) {
4349 } else if(fr->af.frametype == AST_FRAME_CNG) {
4351 }
4352
4353 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
4354 if (tsout)
4355 *tsout = fr->ts;
4356 __do_deliver(fr);
4357 return -1;
4358 }
4359
4360 /* insert into jitterbuffer */
4361 /* TODO: Perhaps we could act immediately if it's not droppable and late */
4362 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
4363 calc_rxstamp(iaxs[fr->callno],fr->ts));
4364 if (ret == JB_DROP) {
4365 needfree++;
4366 } else if (ret == JB_SCHED) {
4368 }
4369 if (tsout)
4370 *tsout = fr->ts;
4371 if (needfree) {
4372 /* Free our iax frame */
4373 iax2_frame_free(fr);
4374 return -1;
4375 }
4376 return 0;
4377}
4378
4379static int transmit_frame(void *data)
4380{
4381 struct iax_frame *fr = data;
4382
4384
4385 fr->sentyet = 1;
4386
4387 if (iaxs[fr->callno]) {
4388 send_packet(fr);
4389 }
4390
4391 if (fr->retries < 0) {
4393 /* No retransmit requested */
4394 iax_frame_free(fr);
4395 } else {
4396 /* We need reliable delivery. Schedule a retransmission */
4398 fr->retries++;
4401 }
4402
4403 return 0;
4404}
4405
4406static int iax2_transmit(struct iax_frame *fr)
4407{
4408 fr->sentyet = 0;
4409
4411}
4412
4413static int iax2_digit_begin(struct ast_channel *c, char digit)
4414{
4416}
4417
4418static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
4419{
4421}
4422
4423static int iax2_sendtext(struct ast_channel *c, const char *text)
4424{
4425
4427 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
4428}
4429
4430static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
4431{
4433}
4434
4435static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
4436{
4437 return send_command_locked(PTR_TO_CALLNO(ast_channel_tech_pvt(c)), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
4438}
4439
4440static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
4441{
4442 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(newchan));
4444 if (iaxs[callno])
4445 iaxs[callno]->owner = newchan;
4446 else
4447 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
4449 return 0;
4450}
4451
4452/*!
4453 * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
4454 * so do not call this with a pvt lock held.
4455 */
4456static struct iax2_peer *realtime_peer(const char *peername, struct ast_sockaddr *addr)
4457{
4458 struct ast_variable *var = NULL;
4459 struct ast_variable *tmp;
4460 struct iax2_peer *peer=NULL;
4461 time_t regseconds = 0, nowtime;
4462 int dynamic=0;
4463 char *str_addr, *str_port;
4464
4467
4468 if (peername) {
4469 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
4470 if (!var && !ast_sockaddr_isnull(addr)) {
4471 var = ast_load_realtime("iaxpeers", "name", peername, "host", str_addr, SENTINEL);
4472 }
4473 } else if (!ast_sockaddr_isnull(addr)) {
4474 var = ast_load_realtime("iaxpeers", "ipaddr", str_addr, "port", str_port, SENTINEL);
4475 if (var) {
4476 /* We'll need the peer name in order to build the structure! */
4477 for (tmp = var; tmp; tmp = tmp->next) {
4478 if (!strcasecmp(tmp->name, "name"))
4479 peername = tmp->value;
4480 }
4481 }
4482 }
4483 if (!var && peername) { /* Last ditch effort */
4484 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
4485 /*!\note
4486 * If this one loaded something, then we need to ensure that the host
4487 * field matched. The only reason why we can't have this as a criteria
4488 * is because we only have the IP address and the host field might be
4489 * set as a name (and the reverse PTR might not match).
4490 */
4491 if (var && !ast_sockaddr_isnull(addr)) {
4492 for (tmp = var; tmp; tmp = tmp->next) {
4493 if (!strcasecmp(tmp->name, "host")) {
4494 struct ast_sockaddr *hostaddr = NULL;
4495
4497 || ast_sockaddr_cmp_addr(hostaddr, addr)) {
4498 /* No match */
4500 var = NULL;
4501 }
4502 ast_free(hostaddr);
4503 break;
4504 }
4505 }
4506 }
4507 }
4508 if (!var)
4509 return NULL;
4510
4511 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
4512
4513 if (!peer) {
4515 return NULL;
4516 }
4517
4518 for (tmp = var; tmp; tmp = tmp->next) {
4519 /* Make sure it's not a user only... */
4520 if (!strcasecmp(tmp->name, "type")) {
4521 if (strcasecmp(tmp->value, "friend") &&
4522 strcasecmp(tmp->value, "peer")) {
4523 /* Whoops, we weren't supposed to exist! */
4524 peer = peer_unref(peer);
4525 break;
4526 }
4527 } else if (!strcasecmp(tmp->name, "regseconds")) {
4528 ast_get_time_t(tmp->value, &regseconds, 0, NULL);
4529 } else if (!strcasecmp(tmp->name, "ipaddr")) {
4530 int setport = ast_sockaddr_port(&peer->addr);
4532 ast_log(LOG_WARNING, "Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->value, tmp->name);
4533 } else {
4534 ast_sockaddr_parse(&peer->addr, tmp->value, 0);
4535 }
4536 ast_sockaddr_set_port(&peer->addr, setport);
4537 } else if (!strcasecmp(tmp->name, "port")) {
4538 int bindport;
4539 if (ast_parse_arg(tmp->value, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535)) {
4540 bindport = IAX_DEFAULT_PORTNO;
4541 }
4542 ast_sockaddr_set_port(&peer->addr, bindport);
4543 } else if (!strcasecmp(tmp->name, "host")) {
4544 if (!strcasecmp(tmp->value, "dynamic"))
4545 dynamic = 1;
4546 }
4547 }
4548
4550
4553 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
4554 if (peer->expire > -1) {
4555 if (!AST_SCHED_DEL(sched, peer->expire)) {
4556 peer->expire = -1;
4557 peer_unref(peer);
4558 }
4559 }
4561 if (peer->expire == -1)
4562 peer_unref(peer);
4563 }
4564 ao2_link(peers, peer);
4565 if (ast_test_flag64(peer, IAX_DYNAMIC))
4566 reg_source_db(peer);
4567 } else {
4569 }
4570
4572 time(&nowtime);
4573 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
4574 memset(&peer->addr, 0, sizeof(peer->addr));
4575 realtime_update_peer(peer->name, &peer->addr, 0);
4576 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
4577 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
4578 }
4579 else {
4580 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
4581 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
4582 }
4583 }
4584
4585 return peer;
4586}
4587
4588static struct iax2_user *realtime_user(const char *username, struct ast_sockaddr *addr)
4589{
4590 struct ast_variable *var;
4591 struct ast_variable *tmp;
4592 struct iax2_user *user=NULL;
4593 char *str_addr, *str_port;
4594
4595 str_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
4596 str_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
4597
4598 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
4599 if (!var)
4600 var = ast_load_realtime("iaxusers", "name", username, "host", str_addr, SENTINEL);
4601 if (!var && !ast_sockaddr_isnull(addr)) {
4602 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", str_addr, "port", str_port, SENTINEL);
4603 if (!var)
4604 var = ast_load_realtime("iaxusers", "ipaddr", str_addr, "port", str_port, SENTINEL);
4605 }
4606 if (!var) { /* Last ditch effort */
4607 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
4608 /*!\note
4609 * If this one loaded something, then we need to ensure that the host
4610 * field matched. The only reason why we can't have this as a criteria
4611 * is because we only have the IP address and the host field might be
4612 * set as a name (and the reverse PTR might not match).
4613 */
4614 if (var) {
4615 for (tmp = var; tmp; tmp = tmp->next) {
4616 if (!strcasecmp(tmp->name, "host")) {
4617 struct ast_sockaddr *hostaddr = NULL;
4618
4620 || ast_sockaddr_cmp_addr(hostaddr, addr)) {
4621 /* No match */
4623 var = NULL;
4624 }
4625 ast_free(hostaddr);
4626 break;
4627 }
4628 }
4629 }
4630 }
4631 if (!var)
4632 return NULL;
4633
4634 tmp = var;
4635 while(tmp) {
4636 /* Make sure it's not a peer only... */
4637 if (!strcasecmp(tmp->name, "type")) {
4638 if (strcasecmp(tmp->value, "friend") &&
4639 strcasecmp(tmp->value, "user")) {
4640 return NULL;
4641 }
4642 }
4643 tmp = tmp->next;
4644 }
4645
4647
4649
4650 if (!user)
4651 return NULL;
4652
4656 } else {
4658 }
4659
4660 return user;
4661}
4662
4663static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
4664{
4665 char regseconds[20];
4666 const char *sysname = ast_config_AST_SYSTEM_NAME;
4667 char *syslabel = NULL;
4668 char *port;
4669
4670 if (ast_strlen_zero(sysname)) /* No system name, disable this */
4671 sysname = NULL;
4673 syslabel = "regserver";
4674
4675 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
4676 port = ast_strdupa(ast_sockaddr_stringify_port(sockaddr));
4677 ast_update_realtime("iaxpeers", "name", peername,
4678 "ipaddr", ast_sockaddr_isnull(sockaddr) ? "" : ast_sockaddr_stringify_addr(sockaddr),
4679 "port", ast_sockaddr_isnull(sockaddr) ? "" : port,
4680 "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslabel can be NULL */
4681}
4682
4683struct create_addr_info {
4685 uint64_t flags;
4686 struct iax2_codec_pref prefs;
4687 int maxtime;
4688 int encmethods;
4689 int authmethods;
4690 int found;
4691 int sockfd;
4692 int adsi;
4693 char username[80];
4694 char secret[80];
4695 char outkey[80];
4696 char timezone[80];
4697 char cid_num[80];
4698 char cid_name[80];
4703};
4704
4705static int create_addr(const char *peername, struct ast_channel *c, struct ast_sockaddr *addr, struct create_addr_info *cai)
4706{
4707 struct iax2_peer *peer;
4708 int res = -1;
4709
4711 cai->sockfd = defaultsockfd;
4712 cai->maxtime = 0;
4713
4714 if (!(peer = find_peer(peername, 1))) {
4715 struct ast_sockaddr peer_addr;
4716
4717 peer_addr.ss.ss_family = AST_AF_UNSPEC;
4718 cai->found = 0;
4719 if (ast_get_ip_or_srv(&peer_addr, peername, srvlookup ? "_iax._udp" : NULL)) {
4720 ast_log(LOG_WARNING, "No such host: %s\n", peername);
4721 return -1;
4722 }
4723
4724 if (!ast_sockaddr_port(&peer_addr)) {
4726 }
4727
4728 ast_sockaddr_copy(addr, &peer_addr);
4729 /*
4730 * Use The global iax prefs for unknown peer/user.
4731 * However, move the calling channel's native codec to
4732 * the top of the preference list.
4733 */
4734 cai->prefs = prefs_global;
4735 if (c) {
4736 int i;
4737
4738 for (i = 0; i < ast_format_cap_count(ast_channel_nativeformats(c)); i++) {
4739 struct ast_format *format = ast_format_cap_get_format(
4741 iax2_codec_pref_prepend(&cai->prefs, format,
4743 1);
4744 ao2_ref(format, -1);
4745 }
4746 }
4747 return 0;
4748 }
4749
4750 cai->found = 1;
4751
4752 /* if the peer has no address (current or default), return failure */
4753 if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) {
4754 goto return_unref;
4755 }
4756
4757 /* if the peer is being monitored and is currently unreachable, return failure */
4758 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
4759 goto return_unref;
4760
4762 cai->maxtime = peer->maxms;
4763 cai->capability = peer->capability;
4764 cai->encmethods = peer->encmethods;
4765 cai->authmethods = peer->authmethods;
4766 cai->sockfd = peer->sockfd;
4767 cai->adsi = peer->adsi;
4768 cai->prefs = peer->prefs;
4769 /* Move the calling channel's native codec to the top of the preference list */
4770 if (c) {
4771 int i;
4772
4773 for (i = 0; i < ast_format_cap_count(ast_channel_nativeformats(c)); i++) {
4774 struct ast_format *tmpfmt = ast_format_cap_get_format(
4776 iax2_codec_pref_prepend(&cai->prefs, tmpfmt,
4778 1);
4779 ao2_ref(tmpfmt, -1);
4780 }
4781 }
4782 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
4783 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
4784 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
4785 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
4786 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
4787 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
4788 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
4789 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
4790 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
4791 if (ast_strlen_zero(peer->dbsecret)) {
4792 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
4793 } else {
4794 char *family;
4795 char *key = NULL;
4796
4797 family = ast_strdupa(peer->dbsecret);
4798 key = strchr(family, '/');
4799 if (key)
4800 *key++ = '\0';
4801 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
4802 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
4803 goto return_unref;
4804 }
4805 }
4806
4807 if (!ast_sockaddr_isnull(&peer->addr)) {
4808 ast_sockaddr_copy(addr, &peer->addr);
4809 } else {
4810 ast_sockaddr_copy(addr, &peer->defaddr);
4811 }
4812
4813 res = 0;
4814
4815return_unref:
4816 peer_unref(peer);
4817
4818 return res;
4819}
4820
4821static void __auto_congest(const void *nothing)
4822{
4823 int callno = PTR_TO_CALLNO(nothing);
4825 ast_mutex_lock(&iaxsl[callno]);
4826 if (iaxs[callno]) {
4827 iaxs[callno]->initid = -1;
4828 iax2_queue_frame(callno, &f);
4829 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
4830 }
4831 ast_mutex_unlock(&iaxsl[callno]);
4832}
4833
4834static int auto_congest(const void *data)
4835{
4836#ifdef SCHED_MULTITHREADED
4838#endif
4840 return 0;
4841}
4842
4843static unsigned int iax2_datetime(const char *tz)
4844{
4845 struct timeval t = ast_tvnow();
4846 struct ast_tm tm;
4847 unsigned int tmp;
4848 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
4849 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */
4850 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */
4851 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */
4852 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */
4853 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */
4854 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
4855 return tmp;
4856}
4857
4858struct parsed_dial_string {
4859 char *username;
4860 char *password;
4861 char *key;
4862 char *peer;
4863 char *port;
4864 char *exten;
4865 char *context;
4866 char *options;
4867};
4868
4869static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
4870 struct ast_sockaddr *addr, int command, int ts, unsigned char seqno,
4871 int sockfd, struct iax_ie_data *ied)
4872{
4873 struct {
4874 struct ast_iax2_full_hdr f;
4875 struct iax_ie_data ied;
4876 } data;
4877 size_t size = sizeof(struct ast_iax2_full_hdr);
4878
4879 if (ied) {
4880 size += ied->pos;
4881 memcpy(&data.ied, ied->buf, ied->pos);
4882 }
4883
4884 data.f.scallno = htons(0x8000 | callno);
4885 data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS);
4886 data.f.ts = htonl(ts);
4887 data.f.iseqno = seqno;
4888 data.f.oseqno = 0;
4889 data.f.type = AST_FRAME_IAX;
4890 data.f.csub = compress_subclass(command);
4891
4892 iax_outputframe(NULL, &data.f, 0, addr, size - sizeof(struct ast_iax2_full_hdr));
4893
4894 return ast_sendto(sockfd, &data, size, 0, addr);
4895}
4896
4897static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
4898{
4899 /* first make sure their are two empty bytes left in ied->buf */
4900 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
4901 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */
4902 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */
4903 pvt->calltoken_ie_len = 2;
4904 }
4905}
4906
4907static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
4908{
4909 struct chan_iax2_pvt *pvt = iaxs[callno];
4910 int frametype = f->af.frametype;
4911 int subclass = f->af.subclass.integer;
4912 struct {
4913 struct ast_iax2_full_hdr fh;
4914 struct iax_ie_data ied;
4915 } data = {
4916 .ied.buf = { 0 },
4917 .ied.pos = 0,
4918 };
4919 /* total len - header len gives us the frame's IE len */
4920 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
4921
4922 if (!pvt) {
4923 return; /* this should not be possible if called from socket_process() */
4924 }
4925
4926 /*
4927 * Check to make sure last frame sent is valid for call token resend
4928 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog
4929 * 2. Frame should _NOT_ already have a destination callno
4930 * 3. Frame must be a valid iax_frame subclass capable of starting dialog
4931 * 4. Pvt must have a calltoken_ie_len which represents the number of
4932 * bytes at the end of the frame used for the previous calltoken ie.
4933 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length
4934 * 6. Total length of f->data must be _LESS_ than size of our data struct
4935 * because f->data must be able to fit within data.
4936 */
4937 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
4938 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
4939 (f->datalen > sizeof(data))) {
4940
4941 return; /* ignore resend, token was not valid for the dialog */
4942 }
4943
4944 /* token is valid
4945 * 1. Copy frame data over
4946 * 2. Redo calltoken IE, it will always be the last ie in the frame.
4947 * NOTE: Having the ie always be last is not protocol specified,
4948 * it is only an implementation choice. Since we only expect the ie to
4949 * be last for frames we have sent, this can no way be affected by
4950 * another end point.
4951 * 3. Remove frame from queue
4952 * 4. Free old frame
4953 * 5. Clear previous seqnos
4954 * 6. Resend with CALLTOKEN ie.
4955 */
4956
4957 /* ---1.--- */
4958 memcpy(&data, f->data, f->datalen);
4959 data.ied.pos = ie_data_pos;
4960
4961 /* ---2.--- */
4962 /* move to the beginning of the calltoken ie so we can write over it */
4963 data.ied.pos -= pvt->calltoken_ie_len;
4964 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
4965
4966 /* make sure to update token length incase it ever has to be stripped off again */
4967 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */
4968
4969 /* ---3.--- */
4970 AST_LIST_REMOVE(&frame_queue[callno], f, list);
4971
4972 /* ---4.--- */
4973 iax2_frame_free(f);
4974
4975 /* ---5.--- */
4976 pvt->oseqno = 0;
4977 pvt->rseqno = 0;
4978 pvt->iseqno = 0;
4979 pvt->aseqno = 0;
4980 if (pvt->peercallno) {
4982 pvt->peercallno = 0;
4983 }
4984
4985 /* ---6.--- */
4986 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
4987}
4988
4989static void requirecalltoken_mark_auto(const char *name, int subclass)
4990{
4991 struct iax2_user *user = NULL;
4992 struct iax2_peer *peer = NULL;
4993
4994 if (ast_strlen_zero(name)) {
4995 return; /* no username given */
4996 }
4997
4998 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
4999 user->calltoken_required = CALLTOKEN_YES;
5000 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
5002 }
5003
5004 if (peer) {
5005 peer_unref(peer);
5006 }
5007 if (user) {
5009 }
5010}
5011
5012/*!
5013 * \internal
5014 *
5015 * \brief handles calltoken logic for a received iax_frame.
5016 *
5017 * \note frametype must be AST_FRAME_IAX.
5018 *
5019 * \note
5020 * Three different cases are possible here.
5021 * Case 1. An empty calltoken is provided. This means the client supports
5022 * calltokens but has not yet received one from us. In this case
5023 * a full calltoken IE is created and sent in a calltoken fullframe.
5024 * Case 2. A full calltoken is received and must be checked for validity.
5025 * Case 3. No calltoken is received indicating that the client does not
5026 * support calltokens. In this case it is up to the configuration
5027 * to decide how this should be handled (reject or permit without calltoken)
5028 */
5029static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
5030 struct ast_sockaddr *addr, int fd)
5031{
5032#define CALLTOKEN_HASH_FORMAT "%s%u%d" /* address + port + ts + randomcalldata */
5033#define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */
5034 struct ast_str *buf = ast_str_alloca(256);
5035 time_t t = time(NULL);
5036 char hash[41]; /* 40 char sha1 hash */
5037 int subclass = uncompress_subclass(fh->csub);
5038
5039 /* ----- Case 1 ----- */
5040 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */
5041 struct iax_ie_data ied = {
5042 .buf = { 0 },
5043 .pos = 0,
5044 };
5045
5046 /* create the hash with their address data and our timestamp */
5049
5050 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
5052 send_apathetic_reply(1, ntohs(fh->scallno), addr, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
5053
5054 return 1;
5055
5056 /* ----- Case 2 ----- */
5057 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */
5058 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */
5059 char *rec_ts = NULL; /* received timestamp */
5060 unsigned int rec_time; /* received time_t */
5061
5062 /* split the timestamp from the hash data */
5063 rec_hash = strchr((char *) ies->calltokendata, '?');
5064 if (rec_hash) {
5065 *rec_hash++ = '\0';
5066 rec_ts = (char *) ies->calltokendata;
5067 }
5068
5069 /* check that we have valid data before we do any comparisons */
5070 if (!rec_hash || !rec_ts) {
5071 goto reject;
5072 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
5073 goto reject;
5074 }
5075
5076 /* create a hash with their address and the _TOKEN'S_ timestamp */
5079
5080 /* compare hashes and then check timestamp delay */
5081 if (strcmp(hash, rec_hash)) {
5082 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_sockaddr_stringify(addr));
5083 goto reject; /* received hash does not match ours, reject */
5084 } else if ((t < rec_time) || ((t - rec_time) >= max_calltoken_delay)) {
5085 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_sockaddr_stringify(addr));
5086 goto reject; /* too much delay, reject */
5087 }
5088
5089 /* at this point the call token is valid, returning 0
5090 * will allow socket_process to continue as usual */
5091 requirecalltoken_mark_auto(ies->username, subclass);
5092 return 0;
5093
5094 /* ----- Case 3 ----- */
5095 } else { /* calltokens are not supported for this client, how do we respond? */
5096 if (calltoken_required(addr, ies->username, subclass)) {
5097 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"));
5098 goto reject;
5099 }
5100 return 0; /* calltoken is not required for this addr, so permit it. */
5101 }
5102
5103reject:
5104 /* received frame has failed calltoken inspection, send apathetic reject messages */
5105 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
5106 send_apathetic_reply(1, ntohs(fh->scallno), addr, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
5107 } else {
5108 send_apathetic_reply(1, ntohs(fh->scallno), addr, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
5109 }
5110
5111 return 1;
5112}
5113
5114/*!
5115 * \brief Parses an IAX dial string into its component parts.
5116 * \param data the string to be parsed
5117 * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
5118 *
5119 * This function parses the string and fills the structure
5120 * with pointers to its component parts. The input string
5121 * will be modified.
5122 *
5123 * \note This function supports both plaintext passwords and RSA
5124 * key names; if the password string is formatted as '[keyname]',
5125 * then the keyname will be placed into the key field, and the
5126 * password field will be set to NULL.
5127 *
5128 * \note The dial string format is:
5129 * \verbatim [username[:password]@]peer[:port][/exten[@context]][/options] \endverbatim
5130 */
5131static void parse_dial_string(char *data, struct parsed_dial_string *pds)
5132{
5133 char *outkey = NULL;
5134
5135 if (ast_strlen_zero(data))
5136 return;
5137
5138 pds->peer = strsep(&data, "/");
5139 pds->exten = strsep(&data, "/");
5140 pds->options = data;
5141
5142 if (pds->exten) {
5143 data = pds->exten;
5144 pds->exten = strsep(&data, "@");
5145 pds->context = data;
5146 }
5147
5148 if (strchr(pds->peer, '@')) {
5149 data = pds->peer;
5150 pds->username = strsep(&data, "@");
5151 pds->peer = data;
5152 }
5153
5154 if (pds->username) {
5155 data = pds->username;
5156 pds->username = strsep(&data, ":");
5157 pds->password = strsep(&data, ":");
5158 outkey = data;
5159 }
5160
5161 data = pds->peer;
5162 pds->peer = strsep(&data, ":");
5163 pds->port = data;
5164
5165 /*
5166 * Check for a key name wrapped in [] in the password position.
5167 * If found, move it to the key field instead.
5168 * Also allow for both key and secret to be specified, now that
5169 * encryption is possible with RSA authentication.
5170 */
5171
5172 if (pds->password && (pds->password[0] == '[')) { /* key (then maybe secret) */
5173 pds->key = ast_strip_quoted(pds->password, "[", "]");
5174 if (ast_strlen_zero(outkey)) {
5175 pds->password = NULL;
5176 ast_debug(1, "Outkey (%s), no secret\n", pds->key);
5177 } else {
5178 pds->password = outkey;
5179 ast_debug(1, "Outkey (%s) and secret (%s)\n", pds->key, pds->password);
5180 }
5181 } else if (outkey && (outkey[0] == '[')) { /* secret, then key */
5182 pds->key = ast_strip_quoted(outkey, "[", "]");
5183 if (ast_strlen_zero(pds->password)) {
5184 ast_debug(1, "Outkey (%s), no secret\n", pds->key);
5185 } else {
5186 ast_debug(1, "Outkey (%s) and secret (%s)\n", pds->key, pds->password);
5187 }
5188 }
5189}
5190
5191static int iax2_call(struct ast_channel *c, const char *dest, int timeout)
5192{
5193 struct ast_sockaddr addr;
5194 char *l=NULL, *n=NULL, *tmpstr;
5195 struct iax_ie_data ied;
5196 char *defaultrdest = "s";
5197 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5198 struct parsed_dial_string pds;
5199 struct create_addr_info cai;
5200 struct ast_var_t *var;
5202 const char* osp_token_ptr;
5203 unsigned int osp_token_length;
5204 unsigned char osp_block_index;
5205 unsigned int osp_block_length;
5206 unsigned char osp_buffer[256];
5207 char encoded_prefs[32];
5208 iax2_format iax2_tmpfmt;
5209
5211 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", ast_channel_name(c));
5212 return -1;
5213 }
5214
5215 memset(&cai, 0, sizeof(cai));
5218
5219 memset(&pds, 0, sizeof(pds));
5220 tmpstr = ast_strdupa(dest);
5221 parse_dial_string(tmpstr, &pds);
5222
5223 if (ast_strlen_zero(pds.peer)) {
5224 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
5225 return -1;
5226 }
5227 if (!pds.exten) {
5228 pds.exten = defaultrdest;
5229 }
5230 if (create_addr(pds.peer, c, &addr, &cai)) {
5231 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
5232 return -1;
5233 }
5234
5237 if (!cai.encmethods) {
5238 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
5240 return -1;
5241 }
5242 if (((cai.authmethods & IAX_AUTH_RSA) || (cai.authmethods & IAX_AUTH_MD5) || (cai.authmethods & IAX_AUTH_PLAINTEXT)) &&
5244 ast_log(LOG_WARNING, "Call terminated. Encryption forced but no secret provided\n");
5245 return -1;
5246 }
5247 }
5248
5249 if (!pds.username && !ast_strlen_zero(cai.username))
5250 pds.username = cai.username;
5251 if (!pds.password && !ast_strlen_zero(cai.secret))
5252 pds.password = cai.secret;
5253 if (!pds.key && !ast_strlen_zero(cai.outkey))
5254 pds.key = cai.outkey;
5255 if (!pds.context && !ast_strlen_zero(cai.peercontext))
5256 pds.context = cai.peercontext;
5257
5258 /* Keep track of the context for outgoing calls too */
5260
5261 if (pds.port) {
5262 int bindport;
5263 if (ast_parse_arg(pds.port, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535)) {
5264 ast_sockaddr_set_port(&addr, bindport);
5265 }
5266 }
5267
5270
5271 /* Now build request */
5272 memset(&ied, 0, sizeof(ied));
5273
5274 /* On new call, first IE MUST be IAX version of caller */
5277 if (pds.options && strchr(pds.options, 'a')) {
5278 /* Request auto answer */
5280 }
5281
5282 /* WARNING: this breaks down at 190 bits! */
5283 iax2_codec_pref_convert(&cai.prefs, encoded_prefs, sizeof(encoded_prefs), 1);
5284 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, encoded_prefs);
5285
5286 if (l) {
5290 } else if (n) {
5293 } else {
5295 }
5296
5298 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, ast_channel_dialed(c)->transit_network_select);
5300
5301 if (n)
5303 if (ast_test_flag64(iaxs[callno], IAX_SENDANI)
5304 && ast_channel_connected(c)->ani.number.valid
5305 && ast_channel_connected(c)->ani.number.str) {
5307 }
5308
5313 }
5314 if (ast_channel_redirecting(c)->from.number.valid
5315 && !ast_strlen_zero(ast_channel_redirecting(c)->from.number.str)) {
5316 iax_ie_append_str(&ied, IAX_IE_RDNIS, ast_channel_redirecting(c)->from.number.str);
5317 }
5318
5319 if (pds.context)
5321
5322 if (pds.username)
5324
5325 if (cai.encmethods)
5327
5328 ast_mutex_lock(&iaxsl[callno]);
5329
5331 ast_string_field_set(iaxs[callno], context, ast_channel_context(c));
5332
5333 if (pds.username)
5334 ast_string_field_set(iaxs[callno], username, pds.username);
5335
5336 iaxs[callno]->encmethods = cai.encmethods;
5337
5338 iaxs[callno]->adsi = cai.adsi;
5339
5342
5343 if (pds.key)
5344 ast_string_field_set(iaxs[callno], outkey, pds.key);
5345 if (pds.password)
5346 ast_string_field_set(iaxs[callno], secret, pds.password);
5347
5349 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) iax2_tmpfmt);
5350 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, iax2_tmpfmt);
5351
5352 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
5353 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
5356
5357 if (iaxs[callno]->maxtime) {
5358 /* Initialize pingtime and auto-congest time */
5359 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
5360 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
5361 } else if (autokill) {
5362 iaxs[callno]->pingtime = autokill / 2;
5364 }
5365
5366 /* Check if there is an OSP token */
5367 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
5368 if (!ast_strlen_zero(osp_token_ptr)) {
5369 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
5370 osp_block_index = 0;
5371 while (osp_token_length > 0) {
5372 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
5373 osp_buffer[0] = osp_block_index;
5374 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
5375 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
5376 osp_block_index++;
5377 osp_token_ptr += osp_block_length;
5378 osp_token_length -= osp_block_length;
5379 }
5380 } else
5381 ast_log(LOG_WARNING, "OSP token is too long\n");
5382 } else if (iaxdebug)
5383 ast_debug(1, "OSP token is undefined\n");
5384
5385 /* send the command using the appropriate socket for this peer */
5386 iaxs[callno]->sockfd = cai.sockfd;
5387
5388 /* Add remote vars */
5389 if (variablestore) {
5390 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
5391 ast_debug(1, "Found an IAX variable store on this channel\n");
5392 AST_LIST_LOCK(variablelist);
5393 AST_LIST_TRAVERSE(variablelist, var, entries) {
5394 char tmp[256];
5395 int i;
5396 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
5397 /* Automatically divide the value up into sized chunks */
5398 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
5399 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
5401 }
5402 }
5403 AST_LIST_UNLOCK(variablelist);
5404 }
5405
5406 /* Transmit the string in a "NEW" request */
5407 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
5408 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
5409
5410 ast_mutex_unlock(&iaxsl[callno]);
5412
5413 return 0;
5414}
5415
5416static int iax2_hangup(struct ast_channel *c)
5417{
5418 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5419 struct iax_ie_data ied;
5420 int alreadygone;
5421 memset(&ied, 0, sizeof(ied));
5422 ast_mutex_lock(&iaxsl[callno]);
5423 if (callno && iaxs[callno]) {
5424 ast_debug(1, "We're hanging up %s now...\n", ast_channel_name(c));
5425 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
5426 /* Send the hangup unless we have had a transmission error or are already gone */
5428 if (!iaxs[callno]->error && !alreadygone) {
5429 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
5430 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
5431 }
5432 if (!iaxs[callno]) {
5433 ast_mutex_unlock(&iaxsl[callno]);
5434 return 0;
5435 }
5436 }
5437 /* Explicitly predestroy it */
5438 iax2_predestroy(callno);
5439 /* If we were already gone to begin with, destroy us now */
5440 if (iaxs[callno] && alreadygone) {
5441 ast_debug(1, "Really destroying %s now...\n", ast_channel_name(c));
5442 iax2_destroy(callno);
5443 } else if (iaxs[callno]) {
5444 if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
5445 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
5446 iax2_destroy(callno);
5447 }
5448 }
5449 } else if (ast_channel_tech_pvt(c)) {
5450 /* If this call no longer exists, but the channel still
5451 * references it we need to set the channel's tech_pvt to null
5452 * to avoid ast_channel_free() trying to free it.
5453 */
5455 }
5456 ast_mutex_unlock(&iaxsl[callno]);
5457 ast_verb(3, "Hungup '%s'\n", ast_channel_name(c));
5458 return 0;
5459}
5460
5461/*!
5462 * \note expects the pvt to be locked
5463 */
5464static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
5465{
5466 unsigned short callno = pvt->callno;
5467
5468 if (!pvt->peercallno) {
5469 /* We don't know the remote side's call number, yet. :( */
5470 int count = 10;
5471 while (count-- && pvt && !pvt->peercallno) {
5472 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
5473 pvt = iaxs[callno];
5474 }
5475 if (!pvt || !pvt->peercallno) {
5476 return -1;
5477 }
5478 }
5479
5480 return 0;
5481}
5482
5483static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
5484{
5485 struct ast_option_header *h;
5486 int res;
5487
5488 switch (option) {
5489 case AST_OPTION_TXGAIN:
5490 case AST_OPTION_RXGAIN:
5491 /* these two cannot be sent, because they require a result */
5492 errno = ENOSYS;
5493 return -1;
5494 case AST_OPTION_OPRMODE:
5495 errno = EINVAL;
5496 return -1;
5499 {
5500 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5501 ast_mutex_lock(&iaxsl[callno]);
5502 if ((*(int *) data)) {
5504 } else {
5506 }
5507 ast_mutex_unlock(&iaxsl[callno]);
5508 return 0;
5509 }
5510 /* These options are sent to the other side across the network where
5511 * they will be passed to whatever channel is bridged there. Don't
5512 * do anything silly like pass an option that transmits pointers to
5513 * memory on this machine to a remote machine to use */
5515 case AST_OPTION_TDD:
5520 {
5521 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5522 struct chan_iax2_pvt *pvt;
5523
5525 pvt = iaxs[callno];
5526
5527 if (wait_for_peercallno(pvt)) {
5529 return -1;
5530 }
5531
5533
5534 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
5535 return -1;
5536 }
5537
5539 h->option = htons(option);
5540 memcpy(h->data, data, datalen);
5542 AST_CONTROL_OPTION, 0, (unsigned char *) h,
5543 datalen + sizeof(*h), -1);
5544 ast_free(h);
5545 return res;
5546 }
5547 default:
5548 return -1;
5549 }
5550
5551 /* Just in case someone does a break instead of a return */
5552 return -1;
5553}
5554
5555static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen)
5556{
5557 switch (option) {
5560 {
5561 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5563 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
5565 return 0;
5566 }
5567 default:
5568 return -1;
5569 }
5570}
5571
5572static struct ast_frame *iax2_read(struct ast_channel *c)
5573{
5574 ast_debug(1, "I should never be called!\n");
5575 return &ast_null_frame;
5576}
5577
5578static int iax2_key_rotate(const void *vpvt)
5579{
5580 int res = 0;
5581 struct chan_iax2_pvt *pvt = (void *) vpvt;
5582 struct MD5Context md5;
5583 char key[17] = "";
5584 struct iax_ie_data ied = {
5585 .pos = 0,
5586 };
5587
5588 ast_mutex_lock(&iaxsl[pvt->callno]);
5589 pvt->keyrotateid = ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
5590
5591 snprintf(key, sizeof(key), "%lX", (unsigned long)ast_random());
5592
5593 MD5Init(&md5);
5594 MD5Update(&md5, (unsigned char *) key, strlen(key));
5595 MD5Final((unsigned char *) key, &md5);
5596
5597 IAX_DEBUGDIGEST("Sending", key);
5598
5599 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
5600
5601 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
5602
5603 build_ecx_key((unsigned char *) key, pvt);
5604
5606
5607 return res;
5608}
5609
5610#if defined(IAX2_NATIVE_BRIDGING)
5611static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
5612{
5613 int res;
5614 struct iax_ie_data ied0;
5615 struct iax_ie_data ied1;
5616 unsigned int transferid = (unsigned int)ast_random();
5617
5618 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
5619 ast_debug(1, "transfers are not supported for encrypted calls at this time\n");
5622 return 0;
5623 }
5624
5625 memset(&ied0, 0, sizeof(ied0));
5626 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
5627 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
5628 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
5629
5630 memset(&ied1, 0, sizeof(ied1));
5631 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
5632 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
5633 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
5634
5635 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
5636 if (res)
5637 return -1;
5638 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
5639 if (res)
5640 return -1;
5641 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
5642 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
5643 return 0;
5644}
5645#endif /* defined(IAX2_NATIVE_BRIDGING) */
5646
5647#if defined(IAX2_NATIVE_BRIDGING)
5648static void lock_both(unsigned short callno0, unsigned short callno1)
5649{
5650 ast_mutex_lock(&iaxsl[callno0]);
5651 while (ast_mutex_trylock(&iaxsl[callno1])) {
5652 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
5653 }
5654}
5655#endif /* defined(IAX2_NATIVE_BRIDGING) */
5656
5657#if defined(IAX2_NATIVE_BRIDGING)
5658static void unlock_both(unsigned short callno0, unsigned short callno1)
5659{
5660 ast_mutex_unlock(&iaxsl[callno1]);
5661 ast_mutex_unlock(&iaxsl[callno0]);
5662}
5663#endif /* defined(IAX2_NATIVE_BRIDGING) */
5664
5665#if defined(IAX2_NATIVE_BRIDGING)
5666static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
5667{
5668 struct ast_channel *cs[3];
5669 struct ast_channel *who, *other;
5670 int to = -1;
5671 int res = -1;
5672 int transferstarted=0;
5673 struct ast_frame *f;
5674 unsigned short callno0 = PTR_TO_CALLNO(ast_channel_tech_pvt(c0));
5675 unsigned short callno1 = PTR_TO_CALLNO(ast_channel_tech_pvt(c1));
5676 struct timeval waittimer = {0, 0};
5677
5678 /* We currently do not support native bridging if a timeoutms value has been provided */
5679 if (timeoutms > 0) {
5680 return AST_BRIDGE_FAILED;
5681 }
5682
5683 timeoutms = -1;
5684
5685 lock_both(callno0, callno1);
5686 if (!iaxs[callno0] || !iaxs[callno1]) {
5687 unlock_both(callno0, callno1);
5688 return AST_BRIDGE_FAILED;
5689 }
5690 /* Put them in native bridge mode */
5692 iaxs[callno0]->bridgecallno = callno1;
5693 iaxs[callno1]->bridgecallno = callno0;
5694 }
5695 unlock_both(callno0, callno1);
5696
5697 /* If not, try to bridge until we can execute a transfer, if we can */
5698 cs[0] = c0;
5699 cs[1] = c1;
5700 for (/* ever */;;) {
5701 /* Check in case we got masqueraded into */
5702 if ((ast_channel_tech(c0) != &iax2_tech) || (ast_channel_tech(c1) != &iax2_tech)) {
5703 ast_verb(3, "Can't masquerade, we're different...\n");
5704 /* Remove from native mode */
5705 if (ast_channel_tech(c0) == &iax2_tech) {
5706 ast_mutex_lock(&iaxsl[callno0]);
5707 iaxs[callno0]->bridgecallno = 0;
5708 ast_mutex_unlock(&iaxsl[callno0]);
5709 }
5710 if (ast_channel_tech(c1) == &iax2_tech) {
5711 ast_mutex_lock(&iaxsl[callno1]);
5712 iaxs[callno1]->bridgecallno = 0;
5713 ast_mutex_unlock(&iaxsl[callno1]);
5714 }
5716 }
5720
5721 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n",
5724
5725 /* Remove from native mode */
5726 lock_both(callno0, callno1);
5727 if (iaxs[callno0])
5728 iaxs[callno0]->bridgecallno = 0;
5729 if (iaxs[callno1])
5730 iaxs[callno1]->bridgecallno = 0;
5731 unlock_both(callno0, callno1);
5733 }
5734 /* check if transferred and if we really want native bridging */
5735 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
5736 /* Try the transfer */
5737 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
5739 ast_log(LOG_WARNING, "Unable to start the transfer\n");
5740 transferstarted = 1;
5741 }
5742 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
5743 /* Call has been transferred. We're no longer involved */
5744 struct timeval now = ast_tvnow();
5745 if (ast_tvzero(waittimer)) {
5746 waittimer = now;
5747 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
5750 *fo = NULL;
5751 *rc = c0;
5752 res = AST_BRIDGE_COMPLETE;
5753 break;
5754 }
5755 }
5756 to = 1000;
5757 who = ast_waitfor_n(cs, 2, &to);
5758 /* XXX This will need to be updated to calculate
5759 * timeout correctly once timeoutms is allowed to be
5760 * > 0. Right now, this can go badly if the waitfor
5761 * times out in less than a millisecond
5762 */
5763 if (timeoutms > -1) {
5764 timeoutms -= (1000 - to);
5765 if (timeoutms < 0)
5766 timeoutms = 0;
5767 }
5768 if (!who) {
5769 if (!timeoutms) {
5770 res = AST_BRIDGE_RETRY;
5771 break;
5772 }
5773 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
5774 res = AST_BRIDGE_FAILED;
5775 break;
5776 }
5777 continue;
5778 }
5779 f = ast_read(who);
5780 if (!f) {
5781 *fo = NULL;
5782 *rc = who;
5783 res = AST_BRIDGE_COMPLETE;
5784 break;
5785 }
5786 other = (who == c0) ? c1 : c0; /* the 'other' channel */
5787 if (f->frametype == AST_FRAME_CONTROL) {
5788 switch (f->subclass.integer) {
5793 ast_write(other, f);
5794 break;
5797 break;
5798 default:
5799 *fo = f;
5800 *rc = who;
5801 res = AST_BRIDGE_COMPLETE;
5802 break;
5803 }
5804 if (res == AST_BRIDGE_COMPLETE) {
5805 break;
5806 }
5807 } else if (f->frametype == AST_FRAME_VOICE
5808 || f->frametype == AST_FRAME_TEXT
5809 || f->frametype == AST_FRAME_VIDEO
5810 || f->frametype == AST_FRAME_IMAGE) {
5811 ast_write(other, f);
5812 } else if (f->frametype == AST_FRAME_DTMF) {
5813 /* monitored dtmf take out of the bridge.
5814 * check if we monitor the specific source.
5815 */
5816 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
5817
5818 if (flags & monitored_source) {
5819 *rc = who;
5820 *fo = f;
5821 res = AST_BRIDGE_COMPLETE;
5822 /* Remove from native mode */
5823 break;
5824 }
5825 ast_write(other, f);
5826 }
5827 ast_frfree(f);
5828 /* Swap who gets priority */
5829 cs[2] = cs[0];
5830 cs[0] = cs[1];
5831 cs[1] = cs[2];
5832 }
5833 lock_both(callno0, callno1);
5834 if(iaxs[callno0])
5835 iaxs[callno0]->bridgecallno = 0;
5836 if(iaxs[callno1])
5837 iaxs[callno1]->bridgecallno = 0;
5838 unlock_both(callno0, callno1);
5839 return res;
5840}
5841#endif /* defined(IAX2_NATIVE_BRIDGING) */
5842
5843static int iax2_answer(struct ast_channel *c)
5844{
5845 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5846 ast_debug(1, "Answering IAX2 call\n");
5848}
5849
5850static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
5851{
5852 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5853 struct chan_iax2_pvt *pvt;
5854 int res = 0;
5855
5856 if (iaxdebug)
5857 ast_debug(1, "Indicating condition %d\n", condition);
5858
5860 pvt = iaxs[callno];
5861
5862 if (wait_for_peercallno(pvt)) {
5863 res = -1;
5864 goto done;
5865 }
5866
5867 switch (condition) {
5868 case AST_CONTROL_HOLD:
5869 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
5870 ast_moh_start(c, data, pvt->mohinterpret);
5871 goto done;
5872 }
5873 break;
5874 case AST_CONTROL_UNHOLD:
5875 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
5876 ast_moh_stop(c);
5877 goto done;
5878 }
5879 break;
5883 /* We are not configured to allow sending these updates. */
5884 ast_debug(2, "Callno %d: Config blocked sending control frame %d.\n",
5885 callno, condition);
5886 goto done;
5887 }
5888 break;
5891 res = -1;
5892 goto done;
5893 }
5894
5895 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
5896
5897done:
5899
5900 return res;
5901}
5902
5903static int iax2_transfer(struct ast_channel *c, const char *dest)
5904{
5905 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5906 struct iax_ie_data ied = { "", };
5907 char tmp[256], *context;
5909 ast_copy_string(tmp, dest, sizeof(tmp));
5910 context = strchr(tmp, '@');
5911 if (context) {
5912 *context = '\0';
5913 context++;
5914 }
5916 if (context)
5918 ast_debug(1, "Transferring '%s' to '%s'\n", ast_channel_name(c), dest);
5920 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
5921}
5922
5923static int iax2_getpeertrunk(struct ast_sockaddr addr)
5924{
5925 struct iax2_peer *peer;
5926 int res = 0;
5927 struct ao2_iterator i;
5928
5929 i = ao2_iterator_init(peers, 0);
5930 while ((peer = ao2_iterator_next(&i))) {
5931
5932 if (!ast_sockaddr_cmp(&peer->addr, &addr)) {
5933 res = ast_test_flag64(peer, IAX_TRUNK);
5934 peer_unref(peer);
5935 break;
5936 }
5937 peer_unref(peer);
5938 }
5940
5941 return res;
5942}
5943
5944/*! \brief Create new call, interface with the PBX core */
5945static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability,
5946 struct iax2_codec_pref *prefs, const struct ast_assigned_ids *assignedids,
5947 const struct ast_channel *requestor, unsigned int cachable)
5948{
5949 struct ast_channel *tmp = NULL;
5950 struct chan_iax2_pvt *i;
5951 struct iax2_peer *peer;
5952 struct ast_variable *v = NULL;
5953 struct ast_format_cap *native;
5954 struct ast_format *tmpfmt;
5955 ast_callid callid;
5956 char *peer_name = NULL;
5957
5958 if (!(i = iaxs[callno])) {
5959 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
5960 return NULL;
5961 }
5962
5963 if (!capability) {
5964 ast_log(LOG_WARNING, "No formats specified for call to: IAX2/%s-%d\n",
5965 i->host, i->callno);
5966 return NULL;
5967 }
5969 if (!native) {
5970 return NULL;
5971 }
5972 if (iax2_codec_pref_best_bitfield2cap(capability, prefs, native)
5973 || !ast_format_cap_count(native)) {
5974 ast_log(LOG_WARNING, "No requested formats available for call to: IAX2/%s-%d\n",
5975 i->host, i->callno);
5976 ao2_ref(native, -1);
5977 return NULL;
5978 }
5979
5980 if (!ast_strlen_zero(i->peer)) {
5981 peer_name = ast_strdupa(i->peer);
5982 } else if (!ast_strlen_zero(i->host)) {
5983 peer_name = ast_strdupa(i->host);
5984 }
5985
5986 /* Don't hold call lock while making a channel or looking up a peer */
5987 ast_mutex_unlock(&iaxsl[callno]);
5988
5989 if (!ast_strlen_zero(peer_name)) {
5990 peer = find_peer(peer_name, 1);
5991 if (peer && peer->endpoint) {
5993 i->accountcode, i->exten, i->context, assignedids, requestor,
5994 i->amaflags, peer->endpoint, "IAX2/%s-%d", i->host, i->callno);
5995 }
5996 ao2_cleanup(peer);
5997 }
5998
5999 if (!tmp) {
6000 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode,
6001 i->exten, i->context, assignedids, requestor, i->amaflags, "IAX2/%s-%d",
6002 i->host, i->callno);
6003 }
6004
6005 ast_mutex_lock(&iaxsl[callno]);
6006 if (i != iaxs[callno]) {
6007 if (tmp) {
6008 /* unlock and relock iaxsl[callno] to preserve locking order */
6009 ast_mutex_unlock(&iaxsl[callno]);
6010 ast_channel_unlock(tmp);
6011 tmp = ast_channel_release(tmp);
6012 ast_mutex_lock(&iaxsl[callno]);
6013 }
6014 ao2_ref(native, -1);
6015 return NULL;
6016 }
6017 if (!tmp) {
6018 ao2_ref(native, -1);
6019 return NULL;
6020 }
6021
6023
6024 if ((callid = iaxs[callno]->callid)) {
6025 ast_channel_callid_set(tmp, callid);
6026 }
6027
6029
6030 /* We can support any format by default, until we get restricted */
6031 ast_channel_nativeformats_set(tmp, native);
6032 tmpfmt = ast_format_cap_get_format(native, 0);
6033
6034 ast_channel_set_readformat(tmp, tmpfmt);
6035 ast_channel_set_rawreadformat(tmp, tmpfmt);
6036 ast_channel_set_writeformat(tmp, tmpfmt);
6037 ast_channel_set_rawwriteformat(tmp, tmpfmt);
6038
6039 ao2_ref(tmpfmt, -1);
6040 ao2_ref(native, -1);
6041
6043
6044 if (!ast_strlen_zero(i->parkinglot))
6045 ast_channel_parkinglot_set(tmp, i->parkinglot);
6046 /* Don't use ast_set_callerid() here because it will
6047 * generate a NewCallerID event before the NewChannel event */
6048 if (!ast_strlen_zero(i->ani)) {
6051 } else if (!ast_strlen_zero(i->cid_num)) {
6054 }
6056 if (!ast_strlen_zero(i->rdnis)) {
6059 }
6065 if (!ast_strlen_zero(i->language))
6066 ast_channel_language_set(tmp, i->language);
6068 ast_channel_accountcode_set(tmp, i->accountcode);
6069 if (i->amaflags)
6073 if (i->adsi)
6075 else
6077 i->owner = tmp;
6078 i->capability = capability;
6079
6080 if (!cachable) {
6082 }
6083
6084 /* Set inherited variables */
6085 if (i->vars) {
6086 for (v = i->vars ; v ; v = v->next)
6088 }
6089 if (i->iaxvars) {
6090 struct ast_datastore *variablestore;
6091 struct ast_variable *var, *prev = NULL;
6092 AST_LIST_HEAD(, ast_var_t) *varlist;
6093 ast_debug(1, "Loading up the channel with IAXVARs\n");
6094 varlist = ast_calloc(1, sizeof(*varlist));
6096 if (variablestore && varlist) {
6097 variablestore->data = varlist;
6098 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
6099 AST_LIST_HEAD_INIT(varlist);
6100 for (var = i->iaxvars; var; var = var->next) {
6101 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
6102 if (prev)
6103 ast_free(prev);
6104 prev = var;
6105 if (!newvar) {
6106 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
6107 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
6108 } else {
6109 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
6110 }
6111 }
6112 if (prev)
6113 ast_free(prev);
6114 i->iaxvars = NULL;
6115 ast_channel_datastore_add(i->owner, variablestore);
6116 } else {
6117 if (variablestore) {
6118 ast_datastore_free(variablestore);
6119 }
6120 if (varlist) {
6121 ast_free(varlist);
6122 }
6123 }
6124 }
6125
6127 ast_channel_unlock(tmp);
6128
6129 if (state != AST_STATE_DOWN) {
6130 if (ast_pbx_start(tmp)) {
6131 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
6132 /* unlock and relock iaxsl[callno] to preserve locking order */
6133 ast_mutex_unlock(&iaxsl[callno]);
6134 ast_hangup(tmp);
6135 ast_mutex_lock(&iaxsl[callno]);
6136 return NULL;
6137 }
6138 }
6139
6141 return tmp;
6142}
6143
6144static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
6145{
6146 unsigned long int mssincetx; /* unsigned to handle overflows */
6147 long int ms, pred;
6148
6149 tpeer->trunkact = *now;
6150 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
6151 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
6152 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
6153 tpeer->txtrunktime = *now;
6154 tpeer->lastsent = 999999;
6155 }
6156 /* Update last transmit time now */
6157 tpeer->lasttxtime = *now;
6158
6159 /* Calculate ms offset */
6160 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
6161 /* Predict from last value */
6162 pred = tpeer->lastsent + sampms;
6163 if (labs(ms - pred) < MAX_TIMESTAMP_SKEW)
6164 ms = pred;
6165
6166 /* We never send the same timestamp twice, so fudge a little if we must */
6167 if (ms == tpeer->lastsent)
6168 ms = tpeer->lastsent + 1;
6169 tpeer->lastsent = ms;
6170 return ms;
6171}
6172
6173static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
6174{
6175 long ms; /* NOT unsigned */
6176 if (ast_tvzero(iaxs[callno]->rxcore)) {
6177 /* Initialize rxcore time if appropriate */
6178 iaxs[callno]->rxcore = ast_tvnow();
6179 /* Round to nearest 20ms so traces look pretty */
6180 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
6181 }
6182 /* Calculate difference between trunk and channel */
6183 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
6184 /* Return as the sum of trunk time and the difference between trunk and real time */
6185 return ms + ts;
6186}
6187
6188static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
6189{
6190 int ms;
6191 int voice = 0;
6192 int genuine = 0;
6193 int adjust;
6194 int rate = 0;
6195 struct timeval *delivery = NULL;
6196
6197
6198 /* What sort of frame do we have?: voice is self-explanatory
6199 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
6200 non-genuine frames are CONTROL frames [ringing etc], DTMF
6201 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
6202 the others need a timestamp slaved to the voice frames so that they go in sequence
6203 */
6204 if (f->frametype == AST_FRAME_VOICE) {
6205 voice = 1;
6206 rate = ast_format_get_sample_rate(f->subclass.format) / 1000;
6207 delivery = &f->delivery;
6208 } else if (f->frametype == AST_FRAME_IAX) {
6209 genuine = 1;
6210 } else if (f->frametype == AST_FRAME_CNG) {
6211 p->notsilenttx = 0;
6212 }
6213
6214 if (ast_tvzero(p->offset)) {
6215 p->offset = ast_tvnow();
6216 /* Round to nearest 20ms for nice looking traces */
6217 p->offset.tv_usec -= p->offset.tv_usec % 20000;
6218 }
6219 /* If the timestamp is specified, just send it as is */
6220 if (ts)
6221 return ts;
6222 /* If we have a time that the frame arrived, always use it to make our timestamp */
6223 if (delivery && !ast_tvzero(*delivery)) {
6224 ms = ast_tvdiff_ms(*delivery, p->offset);
6225 if (ms < 0) {
6226 ms = 0;
6227 }
6228 if (iaxdebug)
6229 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
6230 } else {
6231 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
6232 if (ms < 0)
6233 ms = 0;
6234 if (voice) {
6235 /* On a voice frame, use predicted values if appropriate */
6236 adjust = (ms - p->nextpred);
6237 if (p->notsilenttx && abs(adjust) <= MAX_TIMESTAMP_SKEW) {
6238 /* Adjust our txcore, keeping voice and non-voice synchronized */
6239 /* AN EXPLANATION:
6240 When we send voice, we usually send "calculated" timestamps worked out
6241 on the basis of the number of samples sent. When we send other frames,
6242 we usually send timestamps worked out from the real clock.
6243 The problem is that they can tend to drift out of step because the
6244 source channel's clock and our clock may not be exactly at the same rate.
6245 We fix this by continuously "tweaking" p->offset. p->offset is "time zero"
6246 for this call. Moving it adjusts timestamps for non-voice frames.
6247 We make the adjustment in the style of a moving average. Each time we
6248 adjust p->offset by 10% of the difference between our clock-derived
6249 timestamp and the predicted timestamp. That's why you see "10000"
6250 below even though IAX2 timestamps are in milliseconds.
6251 The use of a moving average avoids offset moving too radically.
6252 Generally, "adjust" roams back and forth around 0, with offset hardly
6253 changing at all. But if a consistent different starts to develop it
6254 will be eliminated over the course of 10 frames (200-300msecs)
6255 */
6256 if (adjust < 0)
6257 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
6258 else if (adjust > 0)
6259 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
6260
6261 if (!p->nextpred) {
6262 p->nextpred = ms; /*f->samples / rate;*/
6263 if (p->nextpred <= p->lastsent)
6264 p->nextpred = p->lastsent + 3;
6265 }
6266 ms = p->nextpred;
6267 } else {
6268 /* in this case, just use the actual
6269 * time, since we're either way off
6270 * (shouldn't happen), or we're ending a
6271 * silent period -- and seed the next
6272 * predicted time. Also, round ms to the
6273 * next multiple of frame size (so our
6274 * silent periods are multiples of
6275 * frame size too) */
6276
6277 if (iaxdebug && abs(adjust) > MAX_TIMESTAMP_SKEW )
6278 ast_debug(1, "predicted timestamp skew (%d) > max (%d), using real ts instead.\n",
6279 abs(adjust), MAX_TIMESTAMP_SKEW);
6280
6281 if (f->samples >= rate) /* check to make sure we don't core dump */
6282 {
6283 int diff = ms % (f->samples / rate);
6284 if (diff)
6285 ms += f->samples/rate - diff;
6286 }
6287
6288 p->nextpred = ms;
6289 p->notsilenttx = 1;
6290 }
6291 } else if ( f->frametype == AST_FRAME_VIDEO ) {
6292 /*
6293 * IAX2 draft 03 says that timestamps MUST be in order.
6294 * It does not say anything about several frames having the same timestamp
6295 * When transporting video, we can have a frame that spans multiple iax packets
6296 * (so called slices), so it would make sense to use the same timestamp for all of
6297 * them
6298 * We do want to make sure that frames don't go backwards though
6299 */
6300 if ( (unsigned int)ms < p->lastsent )
6301 ms = p->lastsent;
6302 } else {
6303 /* On a dataframe, use last value + 3 (to accommodate jitter buffer shrinking) if appropriate unless
6304 it's a genuine frame */
6305 adjust = (ms - p->lastsent);
6306 if (genuine) {
6307 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
6308 if (ms <= p->lastsent)
6309 ms = p->lastsent + 3;
6310 } else if (abs(adjust) <= MAX_TIMESTAMP_SKEW) {
6311 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
6312 ms = p->lastsent + 3;
6313 }
6314 }
6315 }
6316 p->lastsent = ms;
6317 if (voice) {
6318 p->nextpred = p->nextpred + f->samples / rate;
6319 }
6320 return ms;
6321}
6322
6323static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
6324{
6325 /* Returns where in "receive time" we are. That is, how many ms
6326 since we received (or would have received) the frame with timestamp 0 */
6327 int ms;
6328#ifdef IAXTESTS
6329 int jit;
6330#endif /* IAXTESTS */
6331 /* Setup rxcore if necessary */
6332 if (ast_tvzero(p->rxcore)) {
6333 p->rxcore = ast_tvnow();
6334 if (iaxdebug)
6335 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %ums\n",
6336 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
6337 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
6338#if 1
6339 if (iaxdebug)
6340 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
6341 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
6342#endif
6343 }
6344
6345 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
6346#ifdef IAXTESTS
6347 if (test_jit) {
6348 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
6349 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
6350 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
6351 jit = -jit;
6352 ms += jit;
6353 }
6354 }
6355 if (test_late) {
6356 ms += test_late;
6357 test_late = 0;
6358 }
6359#endif /* IAXTESTS */
6360 return ms;
6361}
6362
6363static struct iax2_trunk_peer *find_tpeer(struct ast_sockaddr *addr, int fd)
6364{
6365 struct iax2_trunk_peer *tpeer = NULL;
6366
6367 /* Finds and locks trunk peer */
6369
6370 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
6371 if (!ast_sockaddr_cmp(&tpeer->addr, addr)) {
6372 ast_mutex_lock(&tpeer->lock);
6373 break;
6374 }
6375 }
6376
6377 if (!tpeer) {
6378 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
6379 ast_mutex_init(&tpeer->lock);
6380 tpeer->lastsent = 9999;
6381 ast_sockaddr_copy(&tpeer->addr, addr);
6382 tpeer->trunkact = ast_tvnow();
6383 ast_mutex_lock(&tpeer->lock);
6384 tpeer->sockfd = fd;
6385
6386#ifdef SO_NO_CHECK
6387 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
6388#endif
6389 ast_debug(1, "Created trunk peer for '%s'\n", ast_sockaddr_stringify(&tpeer->addr));
6391 }
6392 }
6393
6395
6396 return tpeer;
6397}
6398
6399static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
6400{
6401 struct ast_frame *f;
6402 struct iax2_trunk_peer *tpeer;
6403 void *tmp, *ptr;
6404 struct timeval now;
6405 struct ast_iax2_meta_trunk_entry *met;
6406 struct ast_iax2_meta_trunk_mini *mtm;
6407
6408 f = &fr->af;
6409 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
6410 if (tpeer) {
6411
6412 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
6413 /* Need to reallocate space */
6414 if (tpeer->trunkdataalloc < trunkmaxsize) {
6415 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
6416 ast_mutex_unlock(&tpeer->lock);
6417 return -1;
6418 }
6419
6421 tpeer->trunkdata = tmp;
6422 ast_debug(1, "Expanded trunk '%s' to %u bytes\n", ast_sockaddr_stringify(&tpeer->addr), tpeer->trunkdataalloc);
6423 } else {
6424 ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s\n", ast_sockaddr_stringify(&tpeer->addr));
6425 ast_mutex_unlock(&tpeer->lock);
6426 return -1;
6427 }
6428 }
6429
6430 /* Append to meta frame */
6431 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
6433 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
6434 mtm->len = htons(f->datalen);
6435 mtm->mini.callno = htons(pvt->callno);
6436 mtm->mini.ts = htons(0xffff & fr->ts);
6437 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
6438 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
6439 } else {
6440 met = (struct ast_iax2_meta_trunk_entry *)ptr;
6441 /* Store call number and length in meta header */
6442 met->callno = htons(pvt->callno);
6443 met->len = htons(f->datalen);
6444 /* Advance pointers/decrease length past trunk entry header */
6445 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
6446 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
6447 }
6448 /* Copy actual trunk data */
6449 memcpy(ptr, f->data.ptr, f->datalen);
6450 tpeer->trunkdatalen += f->datalen;
6451
6452 tpeer->calls++;
6453
6454 /* track the largest mtu we actually have sent */
6455 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
6456 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
6457
6458 /* if we have enough for a full MTU, ship it now without waiting */
6459 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
6460 now = ast_tvnow();
6461 send_trunk(tpeer, &now);
6462 trunk_untimed ++;
6463 }
6464
6465 ast_mutex_unlock(&tpeer->lock);
6466 }
6467 return 0;
6468}
6469
6470/* IAX2 encryption requires 16 to 32 bytes of random padding to be present
6471 * before the encryption data. This function randomizes that data. */
6472static void build_rand_pad(unsigned char *buf, ssize_t len)
6473{
6474 long tmp;
6475 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
6476 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
6477 buf += sizeof(tmp);
6478 len -= sizeof(tmp);
6479 }
6480}
6481
6482static int invalid_key(ast_aes_decrypt_key *ecx)
6483{
6484#ifdef HAVE_OPENSSL
6485 int i;
6486 for (i = 0; i < 60; i++) {
6487 if (ecx->raw[i]) {
6488 return 0; /* stop if we encounter anything non-zero */
6489 }
6490 }
6491 /* if ast_aes_encrypt or ast_aes_decrypt is called, then we'll crash when calling AES_encrypt or AES_decrypt */
6492 return -1;
6493#else
6494 return 0; /* Can't verify, but doesn't matter anyways */
6495#endif
6496}
6497
6498static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
6499{
6500 build_ecx_key(digest, pvt);
6501 ast_aes_set_decrypt_key(digest, &pvt->dcx);
6502}
6503
6504static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
6505{
6506 /* it is required to hold the corresponding decrypt key to our encrypt key
6507 * in the pvt struct because queued frames occasionally need to be decrypted and
6508 * re-encrypted when updated for a retransmission */
6509 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
6510 ast_aes_set_encrypt_key(digest, &pvt->ecx);
6511 ast_aes_set_decrypt_key(digest, &pvt->mydcx);
6512}
6513
6514static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
6515{
6516#if 0
6517 /* Debug with "fake encryption" */
6518 int x;
6519 if (len % 16)
6520 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
6521 for (x=0;x<len;x++)
6522 dst[x] = src[x] ^ 0xff;
6523#else
6524 unsigned char lastblock[16] = { 0 };
6525 int x;
6526 while(len > 0) {
6527 ast_aes_decrypt(src, dst, dcx);
6528 for (x=0;x<16;x++)
6529 dst[x] ^= lastblock[x];
6530 memcpy(lastblock, src, sizeof(lastblock));
6531 dst += 16;
6532 src += 16;
6533 len -= 16;
6534 }
6535#endif
6536}
6537
6538static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
6539{
6540#if 0
6541 /* Debug with "fake encryption" */
6542 int x;
6543 if (len % 16)
6544 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
6545 for (x=0;x<len;x++)
6546 dst[x] = src[x] ^ 0xff;
6547#else
6548 unsigned char curblock[16] = { 0 };
6549 int x;
6550 while(len > 0) {
6551 for (x=0;x<16;x++)
6552 curblock[x] ^= src[x];
6553 ast_aes_encrypt(curblock, dst, ecx);
6554 memcpy(curblock, dst, sizeof(curblock));
6555 dst += 16;
6556 src += 16;
6557 len -= 16;
6558 }
6559#endif
6560}
6561
6562static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
6563{
6564 int padding;
6565 unsigned char *workspace;
6566
6567 workspace = ast_alloca(*datalen);
6568 memset(f, 0, sizeof(*f));
6569 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
6570 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
6571 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
6572 return -1;
6573 /* Decrypt */
6574 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
6575
6576 padding = 16 + (workspace[15] & 0x0f);
6577 if (iaxdebug)
6578 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02hhx)\n", *datalen, padding, workspace[15]);
6579 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
6580 return -1;
6581
6582 *datalen -= padding;
6583 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
6584 f->frametype = fh->type;
6585 if (f->frametype == AST_FRAME_VIDEO) {
6587 if (!f->subclass.format) {
6589 }
6590 } else if (f->frametype == AST_FRAME_VOICE) {
6592 if (!f->subclass.format) {
6594 }
6595 } else {
6597 }
6598 } else {
6599 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
6600 if (iaxdebug)
6601 ast_debug(5, "Decoding mini with length %d\n", *datalen);
6602 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
6603 return -1;
6604 /* Decrypt */
6605 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
6606 padding = 16 + (workspace[15] & 0x0f);
6607 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
6608 return -1;
6609 *datalen -= padding;
6610 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
6611 }
6612 return 0;
6613}
6614
6615static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
6616{
6617 int padding;
6618 unsigned char *workspace;
6619 workspace = ast_alloca(*datalen + 32);
6620 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
6621 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
6622 if (iaxdebug)
6623 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
6624 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
6625 padding = 16 + (padding & 0xf);
6626 memcpy(workspace, poo, padding);
6627 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
6628 workspace[15] &= 0xf0;
6629 workspace[15] |= (padding & 0xf);
6630 if (iaxdebug)
6631 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02hhx)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
6632 *datalen += padding;
6633 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
6634 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
6635 memcpy(poo, workspace + *datalen - 32, 32);
6636 } else {
6637 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
6638 if (iaxdebug)
6639 ast_debug(5, "Encoding mini frame with length %d\n", *datalen);
6640 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
6641 padding = 16 + (padding & 0xf);
6642 memcpy(workspace, poo, padding);
6643 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
6644 workspace[15] &= 0xf0;
6645 workspace[15] |= (padding & 0x0f);
6646 *datalen += padding;
6647 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
6648 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
6649 memcpy(poo, workspace + *datalen - 32, 32);
6650 }
6651 return 0;
6652}
6653
6654static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
6655{
6656 int res=-1;
6658 /* Search for possible keys, given secrets */
6659 struct MD5Context md5;
6660 unsigned char digest[16];
6661 char *tmppw, *stringp;
6662
6663 tmppw = ast_strdupa(iaxs[callno]->secret);
6664 stringp = tmppw;
6665 while ((tmppw = strsep(&stringp, ";"))) {
6666 MD5Init(&md5);
6667 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
6668 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
6669 MD5Final(digest, &md5);
6670 build_encryption_keys(digest, iaxs[callno]);
6671 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
6672 if (!res) {
6674 break;
6675 }
6676 }
6677 } else
6678 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
6679 return res;
6680}
6681
6682static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
6683{
6684 /* Queue a packet for delivery on a given private structure. Use "ts" for
6685 timestamp, or calculate if ts is 0. Send immediately without retransmission
6686 or delayed, with retransmission */
6687 struct ast_iax2_full_hdr *fh;
6688 struct ast_iax2_mini_hdr *mh;
6689 struct ast_iax2_video_hdr *vh;
6690 struct {
6691 struct iax_frame fr2;
6692 unsigned char buffer[4096];
6693 } frb;
6694 struct iax_frame *fr;
6695 int res;
6696 int sendmini=0;
6697 unsigned int lastsent;
6698 unsigned int fts;
6699
6700 frb.fr2.afdatalen = sizeof(frb.buffer);
6701
6702 if (!pvt) {
6703 ast_log(LOG_WARNING, "No private structure for packet?\n");
6704 return -1;
6705 }
6706
6707 lastsent = pvt->lastsent;
6708
6709 /* Calculate actual timestamp */
6710 fts = calc_timestamp(pvt, ts, f);
6711
6712 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
6713 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we
6714 * increment the "predicted timestamps" for voice, if we're predicting */
6715 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
6716 return 0;
6717#if 0
6719 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
6720 *("=!" + (f->frametype == AST_FRAME_VOICE)),
6721 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
6722 pvt->keyrotateid != -1 ? "" : "no "
6723 );
6724#endif
6725 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
6726 iax2_key_rotate(pvt);
6727 }
6728
6729 if ((ast_test_flag64(pvt, IAX_TRUNK) ||
6730 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
6731 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
6732 /* High two bytes are the same on timestamp, or sending on a trunk */ &&
6734 /* is a voice frame */ &&
6737 /* is the same type */ ) {
6738 /* Force immediate rather than delayed transmission */
6739 now = 1;
6740 /* Mark that mini-style frame is appropriate */
6741 sendmini = 1;
6742 }
6743 if ( f->frametype == AST_FRAME_VIDEO ) {
6744 /*
6745 * If the lower 15 bits of the timestamp roll over, or if
6746 * the video format changed then send a full frame.
6747 * Otherwise send a mini video frame
6748 */
6749 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
6752 ) {
6753 now = 1;
6754 sendmini = 1;
6755 } else {
6756 now = 0;
6757 sendmini = 0;
6758 }
6759 pvt->lastvsent = fts;
6760 }
6761 if (f->frametype == AST_FRAME_IAX) {
6762 /* 0x8000 marks this message as TX:, this bit will be stripped later */
6764 if (!pvt->first_iax_message) {
6766 }
6767 }
6768 /* Allocate an iax_frame */
6769 if (now) {
6770 fr = &frb.fr2;
6771 } else
6772 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag64(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO));
6773 if (!fr) {
6774 ast_log(LOG_WARNING, "Out of memory\n");
6775 return -1;
6776 }
6777 /* Copy our prospective frame into our immediate or retransmitted wrapper */
6778 iax_frame_wrap(fr, f);
6779
6780 fr->ts = fts;
6781 fr->callno = pvt->callno;
6782 fr->transfer = transfer;
6783 fr->final = final;
6784 fr->encmethods = 0;
6785 if (!sendmini) {
6786 /* We need a full frame */
6787 if (seqno > -1)
6788 fr->oseqno = seqno;
6789 else
6790 fr->oseqno = pvt->oseqno++;
6791 fr->iseqno = pvt->iseqno;
6792 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
6793 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
6794 fh->ts = htonl(fr->ts);
6795 fh->oseqno = fr->oseqno;
6796 if (transfer) {
6797 fh->iseqno = 0;
6798 } else
6799 fh->iseqno = fr->iseqno;
6800 /* Keep track of the last thing we've acknowledged */
6801 if (!transfer)
6802 pvt->aseqno = fr->iseqno;
6803 fh->type = fr->af.frametype & 0xFF;
6804
6805 if (fr->af.frametype == AST_FRAME_VIDEO) {
6807 tmpfmt |= fr->af.subclass.frame_ending ? 0x1LL : 0;
6808 fh->csub = compress_subclass(tmpfmt | ((tmpfmt & 0x1LL) << 6));
6809 } else if (fr->af.frametype == AST_FRAME_VOICE) {
6811 } else {
6813 }
6814
6815 if (transfer) {
6816 fr->dcallno = pvt->transfercallno;
6817 } else
6818 fr->dcallno = pvt->peercallno;
6819 fh->dcallno = htons(fr->dcallno);
6820 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
6821 fr->data = fh;
6822 fr->retries = 0;
6823 /* Retry after 2x the ping time has passed */
6824 fr->retrytime = pvt->pingtime * 2;
6825 if (fr->retrytime < MIN_RETRY_TIME)
6827 if (fr->retrytime > MAX_RETRY_TIME)
6829 /* Acks' don't get retried */
6831 fr->retries = -1;
6832 else if (f->frametype == AST_FRAME_VOICE)
6834 else if (f->frametype == AST_FRAME_VIDEO)
6836 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
6838 if (fr->transfer)
6839 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
6840 else
6841 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
6842 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
6843 fr->encmethods = pvt->encmethods;
6844 fr->ecx = pvt->ecx;
6845 fr->mydcx = pvt->mydcx;
6846 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
6847 } else
6848 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
6849 }
6850
6851 if (now) {
6852 res = send_packet(fr);
6853 } else
6854 res = iax2_transmit(fr);
6855 } else {
6856 if (ast_test_flag64(pvt, IAX_TRUNK)) {
6857 iax2_trunk_queue(pvt, fr);
6858 res = 0;
6859 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
6860 /* Video frame have no sequence number */
6861 fr->oseqno = -1;
6862 fr->iseqno = -1;
6863 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
6864 vh->zeros = 0;
6865 vh->callno = htons(0x8000 | fr->callno);
6866 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.frame_ending ? 0x8000 : 0));
6867 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
6868 fr->data = vh;
6869 fr->retries = -1;
6870 res = send_packet(fr);
6871 } else {
6872 /* Mini-frames have no sequence number */
6873 fr->oseqno = -1;
6874 fr->iseqno = -1;
6875 /* Mini frame will do */
6876 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
6877 mh->callno = htons(fr->callno);
6878 mh->ts = htons(fr->ts & 0xFFFF);
6879 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
6880 fr->data = mh;
6881 fr->retries = -1;
6882 if (pvt->transferring == TRANSFER_MEDIAPASS)
6883 fr->transfer = 1;
6884 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
6886 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
6887 } else
6888 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
6889 }
6890 res = send_packet(fr);
6891 }
6892 }
6893 return res;
6894}
6895
6896static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
6897{
6898 regex_t regexbuf;
6899 int havepattern = 0;
6900
6901#define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
6902#define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
6903
6904 struct iax2_user *user = NULL;
6905 char auth[90];
6906 char *pstr = "";
6907 struct ao2_iterator i;
6908
6909 switch (cmd) {
6910 case CLI_INIT:
6911 e->command = "iax2 show users [like]";
6912 e->usage =
6913 "Usage: iax2 show users [like <pattern>]\n"
6914 " Lists all known IAX2 users.\n"
6915 " Optional regular expression pattern is used to filter the user list.\n";
6916 return NULL;
6917 case CLI_GENERATE:
6918 return NULL;
6919 }
6920
6921 switch (a->argc) {
6922 case 5:
6923 if (!strcasecmp(a->argv[3], "like")) {
6924 if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
6925 return CLI_SHOWUSAGE;
6926 havepattern = 1;
6927 } else
6928 return CLI_SHOWUSAGE;
6929 case 3:
6930 break;
6931 default:
6932 return CLI_SHOWUSAGE;
6933 }
6934
6935 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
6936 i = ao2_iterator_init(users, 0);
6937 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
6938 if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
6939 continue;
6940
6941 if (!ast_strlen_zero(user->secret)) {
6942 ast_copy_string(auth,user->secret, sizeof(auth));
6943 } else if (!ast_strlen_zero(user->inkeys)) {
6944 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
6945 } else
6946 ast_copy_string(auth, "-no secret-", sizeof(auth));
6947
6949 pstr = "REQ Only";
6951 pstr = "Disabled";
6952 else
6953 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
6954
6955 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
6956 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
6957 ast_acl_list_is_empty(user->acl) ? "No" : "Yes", pstr);
6958 }
6960
6961 if (havepattern)
6962 regfree(&regexbuf);
6963
6964 return CLI_SUCCESS;
6965#undef FORMAT
6966#undef FORMAT2
6967}
6968
6969struct show_peers_context {
6970 regex_t regexbuf;
6971 int havepattern;
6972 char idtext[256];
6973 int registeredonly;
6974 int peerlist;
6975 int total_peers;
6976 int online_peers;
6977 int offline_peers;
6979};
6980
6981#define PEERS_FORMAT2 "%-15.15s %-40.40s %s %-40.40s %-9s %s %-11s %-32.32s\n"
6982#define PEERS_FORMAT "%-15.15s %-40.40s %s %-40.40s %-6s%s %s %-11s %-32.32s\n"
6983
6984static void _iax2_show_peers_one(int fd, struct mansession *s, struct show_peers_context *cont, struct iax2_peer *peer)
6985{
6986 char name[256] = "";
6987 char status[64];
6988 int retstatus;
6989 struct ast_str *encmethods = ast_str_alloca(256);
6990
6991 char *tmp_host, *tmp_mask, *tmp_port;
6992
6993 tmp_host = ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr));
6994 tmp_mask = ast_strdupa(ast_sockaddr_stringify_addr(&peer->mask));
6995 tmp_port = ast_strdupa(ast_sockaddr_stringify_port(&peer->addr));
6996
6997 if (!ast_strlen_zero(peer->username)) {
6998 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
6999 } else {
7000 ast_copy_string(name, peer->name, sizeof(name));
7001 }
7002
7003 encmethods_to_str(peer->encmethods, &encmethods);
7004 retstatus = peer_status(peer, status, sizeof(status));
7005 if (retstatus > 0) {
7006 cont->online_peers++;
7007 } else if (!retstatus) {
7008 cont->offline_peers++;
7009 } else {
7010 cont->unmonitored_peers++;
7011 }
7012
7013 if (s) {
7014 if (cont->peerlist) { /* IAXpeerlist */
7015 astman_append(s,
7016 "Event: PeerEntry\r\n%s"
7017 "Channeltype: IAX\r\n",
7018 cont->idtext);
7019 if (!ast_strlen_zero(peer->username)) {
7020 astman_append(s,
7021 "ObjectName: %s\r\n"
7022 "ObjectUsername: %s\r\n",
7023 peer->name,
7024 peer->username);
7025 } else {
7026 astman_append(s,
7027 "ObjectName: %s\r\n",
7028 name);
7029 }
7030 } else { /* IAXpeers */
7031 astman_append(s,
7032 "Event: PeerEntry\r\n%s"
7033 "Channeltype: IAX2\r\n"
7034 "ObjectName: %s\r\n",
7035 cont->idtext,
7036 name);
7037 }
7038 astman_append(s,
7039 "ChanObjectType: peer\r\n"
7040 "IPaddress: %s\r\n",
7041 tmp_host);
7042 if (cont->peerlist) { /* IAXpeerlist */
7043 astman_append(s,
7044 "Mask: %s\r\n"
7045 "Port: %s\r\n",
7046 tmp_mask,
7047 tmp_port);
7048 } else { /* IAXpeers */
7049 astman_append(s,
7050 "IPport: %s\r\n",
7051 tmp_port);
7052 }
7053 astman_append(s,
7054 "Dynamic: %s\r\n"
7055 "Trunk: %s\r\n"
7056 "Encryption: %s\r\n"
7057 "Status: %s\r\n",
7058 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
7059 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
7060 peer->encmethods ? ast_str_buffer(encmethods) : "no",
7061 status);
7062 if (cont->peerlist) { /* IAXpeerlist */
7063 astman_append(s, "\r\n");
7064 } else { /* IAXpeers */
7065 astman_append(s,
7066 "Description: %s\r\n\r\n",
7067 peer->description);
7068 }
7069 } else {
7071 name,
7072 tmp_host,
7073 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
7074 tmp_mask,
7075 tmp_port,
7076 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ",
7077 peer->encmethods ? "(E)" : " ",
7078 status,
7079 peer->description);
7080 }
7081
7082 cont->total_peers++;
7083}
7084
7085static int __iax2_show_peers(int fd, int *total, struct mansession *s, const int argc, const char * const argv[])
7086{
7087 struct show_peers_context cont = {
7088 .havepattern = 0,
7089 .idtext = "",
7090 .registeredonly = 0,
7091
7092 .peerlist = 0,
7093
7094 .total_peers = 0,
7095 .online_peers = 0,
7096 .offline_peers = 0,
7097 .unmonitored_peers = 0,
7098 };
7099
7100 struct ao2_iterator i;
7101
7102 struct iax2_peer *peer = NULL;
7103
7104 switch (argc) {
7105 case 6:
7106 if (!strcasecmp(argv[3], "registered"))
7107 cont.registeredonly = 1;
7108 else
7109 return RESULT_SHOWUSAGE;
7110 if (!strcasecmp(argv[4], "like")) {
7111 if (regcomp(&cont.regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
7112 return RESULT_SHOWUSAGE;
7113 cont.havepattern = 1;
7114 } else
7115 return RESULT_SHOWUSAGE;
7116 break;
7117 case 5:
7118 if (!strcasecmp(argv[3], "like")) {
7119 if (regcomp(&cont.regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
7120 return RESULT_SHOWUSAGE;
7121 cont.havepattern = 1;
7122 } else
7123 return RESULT_SHOWUSAGE;
7124 break;
7125 case 4:
7126 if (!strcasecmp(argv[3], "registered")) {
7127 cont.registeredonly = 1;
7128 } else {
7129 return RESULT_SHOWUSAGE;
7130 }
7131 break;
7132 case 3:
7133 break;
7134 default:
7135 return RESULT_SHOWUSAGE;
7136 }
7137
7138
7139 if (!s) {
7140 ast_cli(fd, PEERS_FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", "Description");
7141 }
7142
7143 i = ao2_iterator_init(peers, 0);
7144 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
7145
7146 if (cont.registeredonly && ast_sockaddr_isnull(&peer->addr)) {
7147 continue;
7148 }
7149 if (cont.havepattern && regexec(&cont.regexbuf, peer->name, 0, NULL, 0)) {
7150 continue;
7151 }
7152
7153 _iax2_show_peers_one(fd, s, &cont, peer);
7154
7155 }
7157
7158 if (!s) {
7159 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
7161 }
7162
7163 if (cont.havepattern) {
7164 regfree(&cont.regexbuf);
7165 }
7166
7167 if (total) {
7168 *total = cont.total_peers;
7169 }
7170
7171 return RESULT_SUCCESS;
7172
7173}
7174#undef PEERS_FORMAT2
7175#undef PEERS_FORMAT
7176
7177static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
7178{
7179 struct iax2_thread *thread = NULL;
7180 time_t t;
7181 int threadcount = 0, dynamiccount = 0;
7182 char type;
7183
7184 switch (cmd) {
7185 case CLI_INIT:
7186 e->command = "iax2 show threads";
7187 e->usage =
7188 "Usage: iax2 show threads\n"
7189 " Lists status of IAX helper threads\n";
7190 return NULL;
7191 case CLI_GENERATE:
7192 return NULL;
7193 }
7194 if (a->argc != 3)
7195 return CLI_SHOWUSAGE;
7196
7197 ast_cli(a->fd, "IAX2 Thread Information\n");
7198 time(&t);
7199 ast_cli(a->fd, "Idle Threads:\n");
7202#ifdef DEBUG_SCHED_MULTITHREAD
7203 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d, func='%s'\n",
7204 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
7205#else
7206 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d\n",
7207 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
7208#endif
7209 threadcount++;
7210 }
7212 ast_cli(a->fd, "Active Threads:\n");
7215 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
7216 type = 'D';
7217 else
7218 type = 'P';
7219#ifdef DEBUG_SCHED_MULTITHREAD
7220 ast_cli(a->fd, "Thread %c%d: state=%u, update=%d, actions=%d, func='%s'\n",
7221 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
7222#else
7223 ast_cli(a->fd, "Thread %c%d: state=%u, update=%d, actions=%d\n",
7224 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
7225#endif
7226 threadcount++;
7227 }
7229 ast_cli(a->fd, "Dynamic Threads:\n");
7232#ifdef DEBUG_SCHED_MULTITHREAD
7233 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d, func='%s'\n",
7234 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
7235#else
7236 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d\n",
7237 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
7238#endif
7239 dynamiccount++;
7240 }
7242 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
7243 return CLI_SUCCESS;
7244}
7245
7246static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
7247{
7248 struct iax2_peer *p;
7249
7250 switch (cmd) {
7251 case CLI_INIT:
7252 e->command = "iax2 unregister";
7253 e->usage =
7254 "Usage: iax2 unregister <peername>\n"
7255 " Unregister (force expiration) an IAX2 peer from the registry.\n";
7256 return NULL;
7257 case CLI_GENERATE:
7258 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
7259 }
7260
7261 if (a->argc != 3)
7262 return CLI_SHOWUSAGE;
7263
7264 p = find_peer(a->argv[2], 1);
7265 if (p) {
7266 if (p->expire > -1) {
7267 struct iax2_peer *peer;
7268
7269 peer = ao2_find(peers, a->argv[2], OBJ_KEY);
7270 if (peer) {
7271 expire_registry(peer_ref(peer)); /* will release its own reference when done */
7272 peer_unref(peer); /* ref from ao2_find() */
7273 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
7274 } else {
7275 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
7276 }
7277 } else {
7278 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
7279 }
7280 peer_unref(p);
7281 } else {
7282 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
7283 }
7284 return CLI_SUCCESS;
7285}
7286
7287static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
7288{
7289 int which = 0;
7290 struct iax2_peer *p = NULL;
7291 char *res = NULL;
7292 int wordlen = strlen(word);
7293
7294 /* 0 - iax2; 1 - unregister; 2 - <peername> */
7295 if (pos == 2) {
7296 struct ao2_iterator i = ao2_iterator_init(peers, 0);
7297 while ((p = ao2_iterator_next(&i))) {
7298 if (!strncasecmp(p->name, word, wordlen) &&
7299 ++which > state && p->expire > -1) {
7300 res = ast_strdup(p->name);
7301 peer_unref(p);
7302 break;
7303 }
7304 peer_unref(p);
7305 }
7307 }
7308
7309 return res;
7310}
7311
7312static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
7313{
7314 switch (cmd) {
7315 case CLI_INIT:
7316 e->command = "iax2 show peers";
7317 e->usage =
7318 "Usage: iax2 show peers [registered] [like <pattern>]\n"
7319 " Lists all known IAX2 peers.\n"
7320 " Optional 'registered' argument lists only peers with known addresses.\n"
7321 " Optional regular expression pattern is used to filter the peer list.\n";
7322 return NULL;
7323 case CLI_GENERATE:
7324 return NULL;
7325 }
7326
7327 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
7328 case RESULT_SHOWUSAGE:
7329 return CLI_SHOWUSAGE;
7330 case RESULT_FAILURE:
7331 return CLI_FAILURE;
7332 default:
7333 return CLI_SUCCESS;
7334 }
7335}
7336
7337static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
7338{
7339 ast_cli_netstats(s, -1, 0);
7340 astman_append(s, "\r\n");
7341 return RESULT_SUCCESS;
7342}
7343
7345 void *user_data)
7346{
7347 int *fd = user_data;
7348
7349 ast_cli(*fd, "%-15.15s %-15d %-15d\n",
7350 header->devname,
7351 ntohs(header->version),
7352 (int) ntohl(header->datalen));
7353
7354 return 0;
7355}
7356
7357static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
7358{
7359 switch (cmd) {
7360 case CLI_INIT:
7361 e->command = "iax2 show firmware";
7362 e->usage =
7363 "Usage: iax2 show firmware\n"
7364 " Lists all known IAX firmware images.\n";
7365 return NULL;
7366 case CLI_GENERATE:
7367 return NULL;
7368 }
7369
7370 if (a->argc != 3 && a->argc != 4)
7371 return CLI_SHOWUSAGE;
7372
7373 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
7374
7376 a->argc == 3 ? NULL : a->argv[3],
7378 (void *) &a->fd);
7379
7380 return CLI_SUCCESS;
7381}
7382
7383/*! \brief callback to display iax peers in manager */
7384static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
7385{
7386 static const char * const a[] = { "iax2", "show", "peers" };
7387 const char *id = astman_get_header(m,"ActionID");
7388 char idtext[256] = "";
7389 int total = 0;
7390
7391 if (!ast_strlen_zero(id))
7392 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
7393
7394 astman_send_listack(s, m, "Peer status list will follow", "start");
7395
7396 /* List the peers in separate manager events */
7397 __iax2_show_peers(-1, &total, s, 3, a);
7398
7399 /* Send final confirmation */
7400 astman_send_list_complete_start(s, m, "PeerlistComplete", total);
7402 return 0;
7403}
7404
7405/*! \brief callback to display iax peers in manager format */
7406static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
7407{
7408 struct show_peers_context cont = {
7409 .havepattern = 0,
7410 .idtext = "",
7411 .registeredonly = 0,
7412
7413 .peerlist = 1,
7414
7415 .total_peers = 0,
7416 .online_peers = 0,
7417 .offline_peers = 0,
7418 .unmonitored_peers = 0,
7419 };
7420
7421 struct iax2_peer *peer = NULL;
7422 struct ao2_iterator i;
7423
7424 const char *id = astman_get_header(m,"ActionID");
7425
7426 if (!ast_strlen_zero(id)) {
7427 snprintf(cont.idtext, sizeof(cont.idtext), "ActionID: %s\r\n", id);
7428 }
7429
7430 astman_send_listack(s, m, "IAX Peer status list will follow", "start");
7431
7432 i = ao2_iterator_init(peers, 0);
7433 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
7434 _iax2_show_peers_one(-1, s, &cont, peer);
7435 }
7437
7438 astman_send_list_complete_start(s, m, "PeerlistComplete", cont.total_peers);
7440
7441 return RESULT_SUCCESS;
7442}
7443
7444
7445static char *regstate2str(int regstate)
7446{
7447 switch(regstate) {
7449 return "Unregistered";
7450 case REG_STATE_REGSENT:
7451 return "Request Sent";
7452 case REG_STATE_AUTHSENT:
7453 return "Auth. Sent";
7455 return "Registered";
7456 case REG_STATE_REJECTED:
7457 return "Rejected";
7458 case REG_STATE_TIMEOUT:
7459 return "Timeout";
7460 case REG_STATE_NOAUTH:
7461 return "No Authentication";
7462 default:
7463 return "Unknown";
7464 }
7465}
7466
7467static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
7468{
7469#define FORMAT2 "%-45.45s %-6.6s %-10.10s %-45.45s %8.8s %s\n"
7470#define FORMAT "%-45.45s %-6.6s %-10.10s %-45.45s %8d %s\n"
7471
7472 struct iax2_registry *reg = NULL;
7473 char host[80];
7474 char perceived[80];
7475 int counter = 0;
7476
7477 switch (cmd) {
7478 case CLI_INIT:
7479 e->command = "iax2 show registry";
7480 e->usage =
7481 "Usage: iax2 show registry\n"
7482 " Lists all registration requests and status.\n";
7483 return NULL;
7484 case CLI_GENERATE:
7485 return NULL;
7486 }
7487 if (a->argc != 3)
7488 return CLI_SHOWUSAGE;
7489 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
7492 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
7493
7494 snprintf(perceived, sizeof(perceived), "%s", ast_sockaddr_isnull(&reg->us) ? "<Unregistered>" : ast_sockaddr_stringify(&reg->us));
7495
7496 ast_cli(a->fd, FORMAT, host,
7497 (reg->dnsmgr) ? "Y" : "N",
7498 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
7499 counter++;
7500 }
7502 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
7503 return CLI_SUCCESS;
7504#undef FORMAT
7505#undef FORMAT2
7506}
7507
7508static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
7509{
7510 const char *id = astman_get_header(m, "ActionID");
7511 struct iax2_registry *reg = NULL;
7512 char idtext[256] = "";
7513 char host[80] = "";
7514 char perceived[80] = "";
7515 int total = 0;
7516
7517 if (!ast_strlen_zero(id))
7518 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
7519
7520 astman_send_listack(s, m, "Registrations will follow", "start");
7521
7524 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
7525
7526 snprintf(perceived, sizeof(perceived), "%s", ast_sockaddr_isnull(&reg->us) ? "<Unregistered>" : ast_sockaddr_stringify(&reg->us));
7527
7528 astman_append(s,
7529 "Event: RegistryEntry\r\n"
7530 "%s"
7531 "Host: %s\r\n"
7532 "DNSmanager: %s\r\n"
7533 "Username: %s\r\n"
7534 "Perceived: %s\r\n"
7535 "Refresh: %d\r\n"
7536 "State: %s\r\n"
7537 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
7538 reg->refresh, regstate2str(reg->regstate));
7539
7540 total++;
7541 }
7543
7544 astman_send_list_complete_start(s, m, "RegistrationsComplete", total);
7546
7547 return 0;
7548}
7549
7550static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
7551{
7552#define FORMAT2 "%-20.20s %-40.40s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
7553#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"
7554#define FORMATB "%-20.20s %-40.40s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
7555 int x;
7556 int numchans = 0;
7557 char first_message[10] = { 0, };
7558 char last_message[10] = { 0, };
7559
7560 switch (cmd) {
7561 case CLI_INIT:
7562 e->command = "iax2 show channels";
7563 e->usage =
7564 "Usage: iax2 show channels\n"
7565 " Lists all currently active IAX channels.\n";
7566 return NULL;
7567 case CLI_GENERATE:
7568 return NULL;
7569 }
7570
7571 if (a->argc != 3)
7572 return CLI_SHOWUSAGE;
7573 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
7574 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
7575 ast_mutex_lock(&iaxsl[x]);
7576 if (iaxs[x]) {
7577 int lag, jitter, localdelay;
7578 jb_info jbinfo;
7580 jb_getinfo(iaxs[x]->jb, &jbinfo);
7581 jitter = jbinfo.jitter;
7582 localdelay = jbinfo.current - jbinfo.min;
7583 } else {
7584 jitter = -1;
7585 localdelay = 0;
7586 }
7587
7588 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
7589 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
7590 lag = iaxs[x]->remote_rr.delay;
7591 ast_cli(a->fd, FORMAT,
7592 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
7594 S_OR(iaxs[x]->username, "(None)"),
7595 iaxs[x]->callno, iaxs[x]->peercallno,
7596 iaxs[x]->oseqno, iaxs[x]->iseqno,
7597 lag,
7598 jitter,
7599 localdelay,
7600 iax2_getformatname(iaxs[x]->voiceformat),
7601 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7602 first_message,
7603 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7604 last_message);
7605 numchans++;
7606 }
7608 }
7609 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
7610 return CLI_SUCCESS;
7611#undef FORMAT
7612#undef FORMAT2
7613#undef FORMATB
7614}
7615
7616static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
7617{
7618 int x;
7619 int numchans = 0;
7620 char first_message[10] = { 0, };
7621 char last_message[10] = { 0, };
7622#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"
7623#define ACN_FORMAT2 "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
7624 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
7625 ast_mutex_lock(&iaxsl[x]);
7626 if (iaxs[x]) {
7627 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
7628 jb_info jbinfo;
7629 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
7630 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
7631
7633 jb_getinfo(iaxs[x]->jb, &jbinfo);
7634 localjitter = jbinfo.jitter;
7635 localdelay = jbinfo.current - jbinfo.min;
7636 locallost = jbinfo.frames_lost;
7637 locallosspct = jbinfo.losspct/1000;
7638 localdropped = jbinfo.frames_dropped;
7639 localooo = jbinfo.frames_ooo;
7640 } else {
7641 localjitter = -1;
7642 localdelay = 0;
7643 locallost = -1;
7644 locallosspct = -1;
7645 localdropped = 0;
7646 localooo = -1;
7647 }
7648 if (s)
7649 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
7650 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
7651 iaxs[x]->pingtime,
7652 localjitter,
7653 localdelay,
7654 locallost,
7655 locallosspct,
7656 localdropped,
7657 localooo,
7658 iaxs[x]->frames_received/1000,
7659 iaxs[x]->remote_rr.jitter,
7660 iaxs[x]->remote_rr.delay,
7661 iaxs[x]->remote_rr.losscnt,
7662 iaxs[x]->remote_rr.losspct,
7663 iaxs[x]->remote_rr.dropped,
7664 iaxs[x]->remote_rr.ooo,
7665 iaxs[x]->remote_rr.packets/1000,
7666 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7667 first_message,
7668 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7669 last_message);
7670 else
7671 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
7672 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
7673 iaxs[x]->pingtime,
7674 localjitter,
7675 localdelay,
7676 locallost,
7677 locallosspct,
7678 localdropped,
7679 localooo,
7680 iaxs[x]->frames_received/1000,
7681 iaxs[x]->remote_rr.jitter,
7682 iaxs[x]->remote_rr.delay,
7683 iaxs[x]->remote_rr.losscnt,
7684 iaxs[x]->remote_rr.losspct,
7685 iaxs[x]->remote_rr.dropped,
7686 iaxs[x]->remote_rr.ooo,
7687 iaxs[x]->remote_rr.packets/1000,
7688 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7689 first_message,
7690 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
7691 last_message);
7692 numchans++;
7693 }
7695 }
7696
7697 return numchans;
7698}
7699
7700static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
7701{
7702 int numchans = 0;
7703
7704 switch (cmd) {
7705 case CLI_INIT:
7706 e->command = "iax2 show netstats";
7707 e->usage =
7708 "Usage: iax2 show netstats\n"
7709 " Lists network status for all currently active IAX channels.\n";
7710 return NULL;
7711 case CLI_GENERATE:
7712 return NULL;
7713 }
7714 if (a->argc != 3)
7715 return CLI_SHOWUSAGE;
7716 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
7717 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
7718 numchans = ast_cli_netstats(NULL, a->fd, 1);
7719 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
7720 return CLI_SUCCESS;
7721}
7722
7723static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
7724{
7725 switch (cmd) {
7726 case CLI_INIT:
7727 e->command = "iax2 set debug {on|off|peer}";
7728 e->usage =
7729 "Usage: iax2 set debug {on|off|peer peername}\n"
7730 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
7731 return NULL;
7732 case CLI_GENERATE:
7733 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
7734 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
7735 return NULL;
7736 }
7737
7738 if (a->argc < e->args || a->argc > e->args + 1)
7739 return CLI_SHOWUSAGE;
7740
7741 if (!strcasecmp(a->argv[3], "peer")) {
7742 struct iax2_peer *peer;
7743
7744 if (a->argc != e->args + 1)
7745 return CLI_SHOWUSAGE;
7746
7747 peer = find_peer(a->argv[4], 1);
7748
7749 if (!peer) {
7750 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
7751 return CLI_FAILURE;
7752 }
7753
7755
7756 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_port(&debugaddr));
7757
7758 ao2_ref(peer, -1);
7759 } else if (!strncasecmp(a->argv[3], "on", 2)) {
7760 iaxdebug = 1;
7761 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
7762 } else {
7763 iaxdebug = 0;
7764 memset(&debugaddr, 0, sizeof(debugaddr));
7765 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
7766 }
7767 return CLI_SUCCESS;
7768}
7769
7770static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
7771{
7772 switch (cmd) {
7773 case CLI_INIT:
7774 e->command = "iax2 set debug trunk {on|off}";
7775 e->usage =
7776 "Usage: iax2 set debug trunk {on|off}\n"
7777 " Enables/Disables debugging of IAX trunking\n";
7778 return NULL;
7779 case CLI_GENERATE:
7780 return NULL;
7781 }
7782
7783 if (a->argc != e->args)
7784 return CLI_SHOWUSAGE;
7785
7786 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
7787 iaxtrunkdebug = 1;
7788 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
7789 } else {
7790 iaxtrunkdebug = 0;
7791 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
7792 }
7793 return CLI_SUCCESS;
7794}
7795
7796static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
7797{
7798 switch (cmd) {
7799 case CLI_INIT:
7800 e->command = "iax2 set debug jb {on|off}";
7801 e->usage =
7802 "Usage: iax2 set debug jb {on|off}\n"
7803 " Enables/Disables jitterbuffer debugging information\n";
7804 return NULL;
7805 case CLI_GENERATE:
7806 return NULL;
7807 }
7808
7809 if (a->argc != e->args)
7810 return CLI_SHOWUSAGE;
7811
7812 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
7814 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
7815 } else {
7817 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
7818 }
7819 return CLI_SUCCESS;
7820}
7821
7822static int iax2_write(struct ast_channel *c, struct ast_frame *f)
7823{
7824 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
7825 int res = -1;
7827 if (iaxs[callno]) {
7828 /* If there's an outstanding error, return failure now */
7829 if (!iaxs[callno]->error) {
7831 res = 0;
7832 /* Don't waste bandwidth sending null frames */
7833 else if (f->frametype == AST_FRAME_NULL)
7834 res = 0;
7836 res = 0;
7838 res = 0;
7839 else
7840 /* Simple, just queue for transmission */
7841 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
7842 } else {
7843 ast_debug(1, "Write error: %s\n", strerror(errno));
7844 }
7845 }
7846 /* If it's already gone, just return */
7848 return res;
7849}
7850
7851static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
7852 int now, int transfer, int final)
7853{
7854 struct ast_frame f = { 0, };
7855 int res = 0;
7856
7857 f.frametype = type;
7858 f.subclass.integer = command;
7859 f.datalen = datalen;
7860 f.src = __FUNCTION__;
7861 f.data.ptr = (void *) data;
7862
7863 if ((res = queue_signalling(i, &f)) <= 0) {
7864 return res;
7865 }
7866
7867 return iax2_send(i, &f, ts, seqno, now, transfer, final);
7868}
7869
7870static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
7871{
7873 /* Control frame should not go out on the wire. */
7874 ast_debug(2, "Callno %d: Blocked sending control frame %d.\n",
7875 i->callno, command);
7876 return 0;
7877 }
7878 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
7879}
7880
7881static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
7882{
7883 int res;
7884 ast_mutex_lock(&iaxsl[callno]);
7885 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
7886 ast_mutex_unlock(&iaxsl[callno]);
7887 return res;
7888}
7889
7890/*!
7891 * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
7892 * the pvt struct for the given call number may disappear during its
7893 * execution.
7894 */
7895static int send_command_final(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
7896{
7897 int call_num = i->callno;
7898 /* It is assumed that the callno has already been locked */
7900 if (!iaxs[call_num])
7901 return -1;
7902 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
7903}
7904
7905static int send_command_immediate(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
7906{
7907 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
7908}
7909
7910static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
7911{
7912 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
7913}
7914
7915static int apply_context(struct iax2_context *con, const char *context)
7916{
7917 while(con) {
7918 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
7919 return -1;
7920 con = con->next;
7921 }
7922 return 0;
7923}
7924
7925
7926static int check_access(int callno, struct ast_sockaddr *addr, struct iax_ies *ies)
7927{
7928 /* Start pessimistic */
7929 int res = -1;
7930 int version = 2;
7931 struct iax2_user *user = NULL, *best = NULL;
7932 int bestscore = 0;
7933 int gotcapability = 0;
7934 struct ast_variable *v = NULL, *tmpvar = NULL;
7935 struct ao2_iterator i;
7936
7937 if (!iaxs[callno])
7938 return res;
7939 if (ies->called_number)
7940 ast_string_field_set(iaxs[callno], exten, ies->called_number);
7941 if (ies->calling_number) {
7944 }
7945 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
7946 }
7947 if (ies->calling_name)
7948 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
7949 if (ies->calling_ani)
7950 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
7951 if (ies->dnid)
7952 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
7953 if (ies->rdnis)
7954 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
7955 if (ies->called_context)
7956 ast_string_field_set(iaxs[callno], context, ies->called_context);
7957 if (ies->language)
7959 if (ies->username)
7960 ast_string_field_set(iaxs[callno], username, ies->username);
7961 if (ies->calling_ton > -1)
7962 iaxs[callno]->calling_ton = ies->calling_ton;
7963 if (ies->calling_tns > -1)
7964 iaxs[callno]->calling_tns = ies->calling_tns;
7965 if (ies->calling_pres > -1)
7966 iaxs[callno]->calling_pres = ies->calling_pres;
7967 if (ies->calling_ani2 > -1)
7968 iaxs[callno]->calling_ani2 = ies->calling_ani2;
7969 if (ies->format)
7970 iaxs[callno]->peerformat = ies->format;
7971 if (ies->adsicpe)
7972 iaxs[callno]->peeradsicpe = ies->adsicpe;
7973 if (ies->capability) {
7974 gotcapability = 1;
7975 iaxs[callno]->peercapability = ies->capability;
7976 }
7977 if (ies->version)
7978 version = ies->version;
7979
7980 /* Use provided preferences until told otherwise for actual preferences */
7981 if (ies->codec_prefs) {
7982 iax2_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
7983 } else {
7984 memset(&iaxs[callno]->rprefs, 0, sizeof(iaxs[callno]->rprefs));
7985 }
7986 iaxs[callno]->prefs = iaxs[callno]->rprefs;
7987
7988 if (!gotcapability) {
7989 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
7990 }
7991 if (version > IAX_PROTO_VERSION) {
7992 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
7994 return res;
7995 }
7996 /* Search the userlist for a compatible entry, and fill in the rest */
7997 i = ao2_iterator_init(users, 0);
7998 while ((user = ao2_iterator_next(&i))) {
7999 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */
8000 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
8001 && (ast_apply_acl(user->acl, addr, "IAX2 user ACL: ") == AST_SENSE_ALLOW) /* Access is permitted from this IP */
8002 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */
8003 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */
8004 if (!ast_strlen_zero(iaxs[callno]->username)) {
8005 /* Exact match, stop right now. */
8006 if (best)
8007 user_unref(best);
8008 best = user;
8009 break;
8010 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
8011 /* No required authentication */
8012 if (user->acl) {
8013 /* There was host authentication and we passed, bonus! */
8014 if (bestscore < 4) {
8015 bestscore = 4;
8016 if (best)
8017 user_unref(best);
8018 best = user;
8019 continue;
8020 }
8021 } else {
8022 /* No host access, but no secret, either, not bad */
8023 if (bestscore < 3) {
8024 bestscore = 3;
8025 if (best)
8026 user_unref(best);
8027 best = user;
8028 continue;
8029 }
8030 }
8031 } else {
8032 if (user->acl) {
8033 /* Authentication, but host access too, eh, it's something.. */
8034 if (bestscore < 2) {
8035 bestscore = 2;
8036 if (best)
8037 user_unref(best);
8038 best = user;
8039 continue;
8040 }
8041 } else {
8042 /* Authentication and no host access... This is our baseline */
8043 if (bestscore < 1) {
8044 bestscore = 1;
8045 if (best)
8046 user_unref(best);
8047 best = user;
8048 continue;
8049 }
8050 }
8051 }
8052 }
8054 }
8056 user = best;
8057 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
8058 user = realtime_user(iaxs[callno]->username, addr);
8059 if (user && (ast_apply_acl(user->acl, addr, "IAX2 user ACL: ") == AST_SENSE_DENY /* Access is denied from this IP */
8060 || (!ast_strlen_zero(iaxs[callno]->context) && /* No context specified */
8061 !apply_context(user->contexts, iaxs[callno]->context)))) { /* Context is permitted */
8062 user = user_unref(user);
8063 }
8064 }
8065 if (user) {
8066 /* We found our match (use the first) */
8067 /* copy vars */
8068 for (v = user->vars ; v ; v = v->next) {
8069 if ((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
8070 if (ast_variable_list_replace(&iaxs[callno]->vars, tmpvar)) {
8071 tmpvar->next = iaxs[callno]->vars;
8072 iaxs[callno]->vars = tmpvar;
8073 }
8074 }
8075 }
8076 /* If a max AUTHREQ restriction is in place, activate it */
8077 if (user->maxauthreq > 0)
8079 iaxs[callno]->prefs = user->prefs;
8081 iaxs[callno]->encmethods = user->encmethods;
8082 /* Store the requested username if not specified */
8083 if (ast_strlen_zero(iaxs[callno]->username))
8084 ast_string_field_set(iaxs[callno], username, user->name);
8085 /* Store whether this is a trunked call, too, of course, and move if appropriate */
8087 iaxs[callno]->capability = user->capability;
8088 /* And use the default context */
8089 if (ast_strlen_zero(iaxs[callno]->context)) {
8090 if (user->contexts)
8091 ast_string_field_set(iaxs[callno], context, user->contexts->context);
8092 else
8093 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
8094 }
8095 /* And any input keys */
8096 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
8097 /* And the permitted authentication methods */
8098 iaxs[callno]->authmethods = user->authmethods;
8099 iaxs[callno]->adsi = user->adsi;
8100 /* If the user has callerid, override the remote caller id. */
8102 iaxs[callno]->calling_tns = 0;
8103 iaxs[callno]->calling_ton = 0;
8104 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
8105 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
8106 ast_string_field_set(iaxs[callno], ani, user->cid_num);
8108 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
8110 } /* else user is allowed to set their own CID settings */
8111 if (!ast_strlen_zero(user->accountcode))
8112 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
8113 if (!ast_strlen_zero(user->mohinterpret))
8114 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
8115 if (!ast_strlen_zero(user->mohsuggest))
8116 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
8117 if (!ast_strlen_zero(user->parkinglot))
8118 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
8119 if (user->amaflags)
8120 iaxs[callno]->amaflags = user->amaflags;
8121 if (!ast_strlen_zero(user->language))
8122 ast_string_field_set(iaxs[callno], language, user->language);
8124 /* Keep this check last */
8125 if (!ast_strlen_zero(user->dbsecret)) {
8126 char *family, *key=NULL;
8127 char buf[80];
8128 family = ast_strdupa(user->dbsecret);
8129 key = strchr(family, '/');
8130 if (key) {
8131 *key = '\0';
8132 key++;
8133 }
8134 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
8135 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
8136 else
8137 ast_string_field_set(iaxs[callno], secret, buf);
8138 } else
8139 ast_string_field_set(iaxs[callno], secret, user->secret);
8140 res = 0;
8141 user = user_unref(user);
8142 } else {
8143 /* user was not found, but we should still fake an AUTHREQ.
8144 * Set authmethods to the last known authmethod used by the system
8145 * Set a fake secret, it's not looked at, just required to attempt authentication.
8146 * Set authrej so the AUTHREP is rejected without even looking at its contents */
8148 ast_string_field_set(iaxs[callno], secret, "badsecret");
8149 iaxs[callno]->authrej = 1;
8150 if (!ast_strlen_zero(iaxs[callno]->username)) {
8151 /* only send the AUTHREQ if a username was specified. */
8152 res = 0;
8153 }
8154 }
8156 return res;
8157}
8158
8159static int raw_hangup(struct ast_sockaddr *addr, unsigned short src, unsigned short dst, int sockfd)
8160{
8161 struct ast_iax2_full_hdr fh;
8162 fh.scallno = htons(src | IAX_FLAG_FULL);
8163 fh.dcallno = htons(dst);
8164 fh.ts = 0;
8165 fh.oseqno = 0;
8166 fh.iseqno = 0;
8167 fh.type = AST_FRAME_IAX;
8169 iax_outputframe(NULL, &fh, 0, addr, 0);
8170
8171 ast_debug(1, "Raw Hangup %s, src=%d, dst=%d\n", ast_sockaddr_stringify(addr), src, dst);
8172 return ast_sendto(sockfd, &fh, sizeof(fh), 0, addr);
8173}
8174
8175static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
8176{
8177 /* Select exactly one common encryption if there are any */
8178 p->encmethods &= enc;
8179 if (p->encmethods) {
8180 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */
8181 p->keyrotateid = -2;
8182 }
8185 else
8186 p->encmethods = 0;
8187 }
8188}
8189
8190/*!
8191 * \pre iaxsl[call_num] is locked
8192 *
8193 * \note Since this function calls send_command_final(), the pvt struct for the given
8194 * call number may disappear while executing this function.
8195 */
8196static int authenticate_request(int call_num)
8197{
8198 struct iax_ie_data ied;
8199 int res = -1, authreq_restrict = 0;
8200 char challenge[10];
8201 struct chan_iax2_pvt *p = iaxs[call_num];
8202
8203 memset(&ied, 0, sizeof(ied));
8204
8205 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
8207 struct iax2_user *user;
8208
8210 if (user) {
8211 if (user->curauthreq == user->maxauthreq)
8212 authreq_restrict = 1;
8213 else
8214 user->curauthreq++;
8215 user = user_unref(user);
8216 }
8217 }
8218
8219 /* If the AUTHREQ limit test failed, send back an error */
8220 if (authreq_restrict) {
8221 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
8224 return 0;
8225 }
8226
8228 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
8229 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
8231 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
8233 }
8234 if (p->encmethods)
8236
8238
8239 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
8240
8241 if (p->encmethods)
8243
8244 return res;
8245}
8246
8247static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
8248{
8249 char requeststr[256];
8250 char md5secret[256] = "";
8251 char secret[256] = "";
8252 char rsasecret[256] = "";
8253 int res = -1;
8254 int x;
8255 struct iax2_user *user;
8256
8257 if (p->authrej) {
8258 return res;
8259 }
8260
8262 if (user) {
8264 ast_atomic_fetchadd_int(&user->curauthreq, -1);
8266 }
8267 ast_string_field_set(p, host, user->name);
8268 user = user_unref(user);
8269 }
8271 ast_log(LOG_WARNING, "Call Terminated, incoming call is unencrypted while force encrypt is enabled.\n");
8272 return res;
8273 }
8275 return res;
8276 if (ies->password)
8277 ast_copy_string(secret, ies->password, sizeof(secret));
8278 if (ies->md5_result)
8279 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
8280 if (ies->rsa_result)
8281 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
8282 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
8283 struct ast_key *key;
8284 char *keyn;
8285 char *tmpkey;
8286 char *stringp=NULL;
8287 if (!(tmpkey = ast_strdup(p->inkeys))) {
8288 ast_log(LOG_ERROR, "Unable to create a temporary string for parsing stored 'inkeys'\n");
8289 return res;
8290 }
8291 stringp = tmpkey;
8292 keyn = strsep(&stringp, ":");
8293 while(keyn) {
8294 key = ast_key_get(keyn, AST_KEY_PUBLIC);
8295 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
8296 res = 0;
8298 break;
8299 } else if (!key) {
8300 ast_log(LOG_WARNING, "Requested inkey '%s' for RSA authentication does not exist\n", keyn);
8301 }
8302 keyn = strsep(&stringp, ":");
8303 }
8304 ast_free(tmpkey);
8305 if (res && authdebug) {
8306 ast_log(LOG_WARNING, "No RSA public keys on file matched incoming call\n");
8307 }
8308 } else if (p->authmethods & IAX_AUTH_MD5) {
8309 struct MD5Context md5;
8310 unsigned char digest[16];
8311 char *tmppw, *stringp;
8312 tmppw = ast_strdupa(p->secret);
8313 stringp = tmppw;
8314 while((tmppw = strsep(&stringp, ";"))) {
8315 MD5Init(&md5);
8316 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
8317 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
8318 MD5Final(digest, &md5);
8319 /* If they support md5, authenticate with it. */
8320 for (x=0;x<16;x++)
8321 sprintf(requeststr + (x << 1), "%02hhx", digest[x]); /* safe */
8322 if (!strcasecmp(requeststr, md5secret)) {
8323 res = 0;
8325 break;
8326 } else if (authdebug) {
8327 ast_log(LOG_WARNING, "MD5 secret mismatch\n");
8328 }
8329 }
8330 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
8331 if (!strcmp(secret, p->secret)) {
8332 res = 0;
8334 } else if (authdebug) {
8335 ast_log(LOG_WARNING, "Plaintext secret mismatch\n");
8336 }
8337 }
8338 return res;
8339}
8340
8341/*! \brief Verify inbound registration */
8342static int register_verify(int callno, struct ast_sockaddr *addr, struct iax_ies *ies)
8343{
8344 char requeststr[256] = "";
8345 char peer[256] = "";
8346 char md5secret[256] = "";
8347 char rsasecret[256] = "";
8348 char secret[256] = "";
8349 struct iax2_peer *p = NULL;
8350 struct ast_key *key;
8351 char *keyn;
8352 int x;
8353 int expire = 0;
8354 int res = -1;
8355
8357 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
8358 if (ies->username)
8359 ast_copy_string(peer, ies->username, sizeof(peer));
8360 if (ies->password)
8361 ast_copy_string(secret, ies->password, sizeof(secret));
8362 if (ies->md5_result)
8363 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
8364 if (ies->rsa_result)
8365 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
8366 if (ies->refresh)
8367 expire = ies->refresh;
8368
8369 if (ast_strlen_zero(peer)) {
8370 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_sockaddr_stringify_addr(addr));
8371 return -1;
8372 }
8373
8374 /* SLD: first call to lookup peer during registration */
8375 ast_mutex_unlock(&iaxsl[callno]);
8376 p = find_peer(peer, 1);
8377 ast_mutex_lock(&iaxsl[callno]);
8378 if (!p || !iaxs[callno]) {
8379 if (iaxs[callno]) {
8380 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
8381 /* Anything, as long as it's non-blank */
8382 ast_string_field_set(iaxs[callno], secret, "badsecret");
8383 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
8384 * 1. A challenge already exists indicating a AUTHREQ was already sent out.
8385 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
8386 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
8387 * to be plaintext, indicating it is an authmethod used by other peers on the system.
8388 *
8389 * If none of these cases exist, res will be returned as 0 without authentication indicating
8390 * an AUTHREQ needs to be sent out. */
8391
8392 if (ast_strlen_zero(iaxs[callno]->challenge) &&
8393 !(!ast_strlen_zero(secret) && plaintext)) {
8394 /* by setting res to 0, an REGAUTH will be sent */
8395 res = 0;
8396 }
8397 }
8398 if (authdebug && !p)
8399 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_sockaddr_stringify_addr(addr));
8400 goto return_unref;
8401 }
8402
8403 if (!ast_test_flag64(p, IAX_DYNAMIC)) {
8404 if (authdebug)
8405 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_sockaddr_stringify_addr(addr));
8406 goto return_unref;
8407 }
8408
8409 if (!ast_apply_acl(p->acl, addr, "IAX2 Peer ACL: ")) {
8410 if (authdebug)
8411 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_sockaddr_stringify_addr(addr), p->name);
8412 goto return_unref;
8413 }
8414 ast_string_field_set(iaxs[callno], secret, p->secret);
8415 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
8416 /* Check secret against what we have on file */
8417 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
8418 if (!ast_strlen_zero(p->inkeys)) {
8419 char *tmpkey;
8420 char *stringp=NULL;
8421 if (!(tmpkey = ast_strdup(p->inkeys))) {
8422 ast_log(LOG_ERROR, "Unable to create a temporary string for parsing stored 'inkeys'\n");
8423 goto return_unref;
8424 }
8425 stringp = tmpkey;
8426 keyn = strsep(&stringp, ":");
8427 while(keyn) {
8428 key = ast_key_get(keyn, AST_KEY_PUBLIC);
8429 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
8431 break;
8432 } else if (!key)
8433 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
8434 keyn = strsep(&stringp, ":");
8435 }
8436 ast_free(tmpkey);
8437 if (!keyn) {
8438 if (authdebug)
8439 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
8440 goto return_unref;
8441 }
8442 } else {
8443 if (authdebug)
8444 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
8445 goto return_unref;
8446 }
8447 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
8448 struct MD5Context md5;
8449 unsigned char digest[16];
8450 char *tmppw, *stringp;
8451
8452 tmppw = ast_strdupa(p->secret);
8453 stringp = tmppw;
8454 while((tmppw = strsep(&stringp, ";"))) {
8455 MD5Init(&md5);
8456 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
8457 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
8458 MD5Final(digest, &md5);
8459 for (x=0;x<16;x++)
8460 sprintf(requeststr + (x << 1), "%02hhx", digest[x]); /* safe */
8461 if (!strcasecmp(requeststr, md5secret))
8462 break;
8463 }
8464 if (tmppw) {
8466 } else {
8467 if (authdebug)
8468 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_sockaddr_stringify_addr(addr), p->name, requeststr, md5secret);
8469 goto return_unref;
8470 }
8471 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
8472 /* They've provided a plain text password and we support that */
8473 if (strcmp(secret, p->secret)) {
8474 if (authdebug)
8475 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_sockaddr_stringify_addr(addr), p->name);
8476 goto return_unref;
8477 } else
8479 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
8480 /* if challenge has been sent, but no challenge response if given, reject. */
8481 goto return_unref;
8482 }
8483 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
8484
8485 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
8486 res = 0;
8487
8488return_unref:
8489 if (iaxs[callno]) {
8490 ast_string_field_set(iaxs[callno], peer, peer);
8491
8492 /* Choose lowest expiry number */
8493 if (expire && (expire < iaxs[callno]->expiry)) {
8494 iaxs[callno]->expiry = expire;
8495 }
8496 }
8497
8498 if (p) {
8499 peer_unref(p);
8500 }
8501 return res;
8502}
8503
8504static 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)
8505{
8506 int res = -1;
8507 int x;
8508 if (!ast_strlen_zero(keyn)) {
8509 if (!(authmethods & IAX_AUTH_RSA)) {
8510 if (ast_strlen_zero(secret)) {
8511 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));
8512 }
8513 } else if (ast_strlen_zero(challenge)) {
8514 ast_log(LOG_WARNING, "No challenge provided for RSA authentication to %s\n", ast_sockaddr_stringify_addr(addr));
8515 } else {
8516 char sig[256];
8517 struct ast_key *key;
8518 key = ast_key_get(keyn, AST_KEY_PRIVATE);
8519 if (!key) {
8520 ast_log(LOG_WARNING, "Unable to find private key '%s'\n", keyn);
8521 } else {
8522 if (ast_sign(key, (char*)challenge, sig)) {
8523 ast_log(LOG_WARNING, "Unable to sign challenge with key\n");
8524 res = -1;
8525 } else {
8527 if (pvt) {
8529 }
8530 res = 0;
8531 }
8532 }
8533
8534 if (pvt && !ast_strlen_zero(secret)) {
8535 struct MD5Context md5;
8536 unsigned char digest[16];
8537
8538 MD5Init(&md5);
8539 MD5Update(&md5, (unsigned char *) challenge, strlen(challenge));
8540 MD5Update(&md5, (unsigned char *) secret, strlen(secret));
8541 MD5Final(digest, &md5);
8542
8543 build_encryption_keys(digest, pvt);
8544 }
8545 }
8546 }
8547 /* Fall back */
8548 if (res && !ast_strlen_zero(secret)) {
8549 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
8550 struct MD5Context md5;
8551 unsigned char digest[16];
8552 char digres[128];
8553 MD5Init(&md5);
8554 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
8555 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
8556 MD5Final(digest, &md5);
8557 /* If they support md5, authenticate with it. */
8558 for (x=0;x<16;x++)
8559 sprintf(digres + (x << 1), "%02hhx", digest[x]); /* safe */
8560 if (pvt) {
8561 build_encryption_keys(digest, pvt);
8563 }
8565 res = 0;
8566 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
8567 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
8568 if (pvt) {
8570 }
8571 res = 0;
8572 } else
8573 ast_log(LOG_WARNING, "No way to send secret to peer '%s' (their methods: %d)\n", ast_sockaddr_stringify_addr(addr), authmethods);
8574 }
8575 return res;
8576}
8577
8578/*!
8579 * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
8580 * so do not call this function with a pvt lock held.
8581 */
8582static int authenticate_reply(struct chan_iax2_pvt *p, struct ast_sockaddr *addr, struct iax_ies *ies, const char *override, const char *okey)
8583{
8584 struct iax2_peer *peer = NULL;
8585 /* Start pessimistic */
8586 int res = -1;
8587 int authmethods = 0;
8588 struct iax_ie_data ied;
8589 uint16_t callno = p->callno;
8590
8591 memset(&ied, 0, sizeof(ied));
8592
8593 if (ies->username)
8594 ast_string_field_set(p, username, ies->username);
8595 if (ies->challenge)
8597 if (ies->authmethods)
8598 authmethods = ies->authmethods;
8599 if (authmethods & IAX_AUTH_MD5)
8601 else
8602 p->encmethods = 0;
8603
8604 /* Check for override RSA authentication first */
8605 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
8606 /* Normal password authentication */
8607 res = authenticate(p->challenge, override, okey, authmethods, &ied, addr, p);
8608 } else {
8609 struct ao2_iterator i = ao2_iterator_init(peers, 0);
8610 while ((peer = ao2_iterator_next(&i))) {
8611 struct ast_sockaddr peer_addr;
8612 struct ast_sockaddr tmp_sockaddr1;
8613 struct ast_sockaddr tmp_sockaddr2;
8614
8615 ast_sockaddr_copy(&peer_addr, &peer->addr);
8616
8617 ast_sockaddr_apply_netmask(addr, &peer->mask, &tmp_sockaddr1);
8618 ast_sockaddr_apply_netmask(&peer_addr, &peer->mask, &tmp_sockaddr2);
8619
8620 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
8621 /* No peer specified at our end, or this is the peer */
8622 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
8623 /* No username specified in peer rule, or this is the right username */
8624 && (ast_sockaddr_isnull(&peer_addr) || !(ast_sockaddr_cmp_addr(&tmp_sockaddr1, &tmp_sockaddr2)))
8625 /* No specified host, or this is our host */
8626 ) {
8627 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, addr, p);
8628 if (!res) {
8629 peer_unref(peer);
8630 break;
8631 }
8632 }
8633 peer_unref(peer);
8634 }
8636 if (!peer) {
8637 /* We checked our list and didn't find one. It's unlikely, but possible,
8638 that we're trying to authenticate *to* a realtime peer */
8639 const char *peer_name = ast_strdupa(p->peer);
8640 ast_mutex_unlock(&iaxsl[callno]);
8641 if ((peer = realtime_peer(peer_name, NULL))) {
8642 ast_mutex_lock(&iaxsl[callno]);
8643 if (!(p = iaxs[callno])) {
8644 peer_unref(peer);
8645 return -1;
8646 }
8647 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, addr, p);
8648 peer_unref(peer);
8649 }
8650 if (!peer) {
8651 ast_mutex_lock(&iaxsl[callno]);
8652 if (!(p = iaxs[callno]))
8653 return -1;
8654 }
8655 }
8656 }
8657
8658 if (!(ies->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT)) && (ies->authmethods & IAX_AUTH_RSA) && ast_strlen_zero(okey)) {
8659 /* If the only thing available is RSA, and we don't have an outkey, we can't do it... */
8660 ast_log(LOG_WARNING, "Call terminated. RSA authentication requires an outkey\n");
8661 return -1;
8662 }
8663
8664 if (ies->encmethods) {
8665 if (ast_strlen_zero(p->secret) &&
8667 ast_log(LOG_WARNING, "Call terminated. Encryption requested by peer but no secret available locally\n");
8668 return -1;
8669 }
8670 /* Don't even THINK about trying to encrypt or decrypt anything if we don't have valid keys, for some reason... */
8671 /* If either of these happens, it's our fault, not the user's. But we should abort rather than crash. */
8675 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
8676 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n");
8677 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */
8678 }
8679 if (!res) {
8680 struct ast_datastore *variablestore;
8681 struct ast_variable *var, *prev = NULL;
8682 AST_LIST_HEAD(, ast_var_t) *varlist;
8683 varlist = ast_calloc(1, sizeof(*varlist));
8685 if (variablestore && varlist && p->owner) {
8686 variablestore->data = varlist;
8687 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
8688 AST_LIST_HEAD_INIT(varlist);
8689 for (var = ies->vars; var; var = var->next) {
8690 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
8691 if (prev)
8692 ast_free(prev);
8693 prev = var;
8694 if (!newvar) {
8695 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */
8696 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
8697 } else {
8698 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
8699 }
8700 }
8701 if (prev)
8702 ast_free(prev);
8703 ies->vars = NULL;
8704 ast_channel_datastore_add(p->owner, variablestore);
8705 } else {
8706 if (p->owner)
8707 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
8708 if (variablestore)
8709 ast_datastore_free(variablestore);
8710 if (varlist)
8711 ast_free(varlist);
8712 }
8713 }
8714
8715 if (!res)
8716 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
8717 return res;
8718}
8719
8720static int iax2_do_register(struct iax2_registry *reg);
8721
8722static void __iax2_do_register_s(const void *data)
8723{
8724 struct iax2_registry *reg = (struct iax2_registry *)data;
8725
8726 if (ast_sockaddr_isnull(&reg->addr)) {
8727 reg->addr.ss.ss_family = AST_AF_UNSPEC;
8728 ast_dnsmgr_lookup(reg->hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL);
8729 if (!ast_sockaddr_port(&reg->addr)) {
8730 ast_sockaddr_set_port(&reg->addr, reg->port);
8731 } else {
8732 reg->port = ast_sockaddr_port(&reg->addr);
8733 }
8734 }
8735
8736 reg->expire = -1;
8737 iax2_do_register(reg);
8738}
8739
8740static int iax2_do_register_s(const void *data)
8741{
8742#ifdef SCHED_MULTITHREADED
8744#endif
8746 return 0;
8747}
8748
8749static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
8750{
8751 int newcall = 0;
8752 struct iax_ie_data ied;
8753 struct ast_sockaddr new = { {0,} };
8754
8755 memset(&ied, 0, sizeof(ied));
8756 if (!ast_sockaddr_isnull(&ies->apparent_addr)) {
8757 ast_sockaddr_copy(&new, &ies->apparent_addr);
8758 }
8759 if (ies->callno) {
8760 newcall = ies->callno;
8761 }
8762 if (!newcall || ast_sockaddr_isnull(&new)) {
8763 ast_log(LOG_WARNING, "Invalid transfer request\n");
8764 return -1;
8765 }
8766 pvt->transfercallno = newcall;
8767 ast_sockaddr_copy(&pvt->transfer, &new);
8768 pvt->transferid = ies->transferid;
8769 /* only store by transfercallno if this is a new transfer,
8770 * just in case we get a duplicate TXREQ */
8771 if (pvt->transferring == TRANSFER_NONE) {
8773 }
8775
8776 if (ies->transferid) {
8778 }
8780 return 0;
8781}
8782
8783static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
8784{
8785 char exten[256] = "";
8786 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
8787 struct iax2_dpcache *dp = NULL;
8788
8789 if (ies->called_number)
8790 ast_copy_string(exten, ies->called_number, sizeof(exten));
8791
8792 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
8794 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
8796 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
8798
8799 if (ies->refresh)
8800 expiry = ies->refresh;
8803
8806 if (strcmp(dp->exten, exten))
8807 continue;
8809 dp->callno = 0;
8810 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
8811 if (dp->flags & CACHE_FLAG_PENDING) {
8812 dp->flags &= ~CACHE_FLAG_PENDING;
8813 dp->flags |= status;
8814 dp->flags |= matchmore;
8815 }
8816 /* Wake up waiters */
8817 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
8818 if (dp->waiters[x] > -1) {
8819 if (write(dp->waiters[x], "asdf", 4) < 0) {
8820 }
8821 }
8822 }
8823 }
8826
8827 return 0;
8828}
8829
8830static int complete_transfer(int callno, struct iax_ies *ies)
8831{
8832 int peercallno = 0;
8833 struct chan_iax2_pvt *pvt = iaxs[callno];
8834 struct iax_frame *cur;
8835 jb_frame frame;
8836
8837 if (ies->callno)
8838 peercallno = ies->callno;
8839
8840 if (peercallno < 1) {
8841 ast_log(LOG_WARNING, "Invalid transfer request\n");
8842 return -1;
8843 }
8845 /* since a transfer has taken place, the address will change.
8846 * This must be accounted for in the peercnts table. Remove
8847 * the old address and add the new one */
8849 peercnt_add(&pvt->transfer);
8850 /* now copy over the new address */
8851 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
8852 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
8853 /* Reset sequence numbers */
8854 pvt->oseqno = 0;
8855 pvt->rseqno = 0;
8856 pvt->iseqno = 0;
8857 pvt->aseqno = 0;
8858
8859 if (pvt->peercallno) {
8861 }
8862 pvt->peercallno = peercallno;
8863 /*this is where the transferring call switches hash tables */
8866 pvt->svoiceformat = -1;
8867 pvt->voiceformat = 0;
8868 pvt->svideoformat = -1;
8869 pvt->videoformat = 0;
8870 pvt->transfercallno = 0;
8871 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
8872 memset(&pvt->offset, 0, sizeof(pvt->offset));
8873 /* reset jitterbuffer */
8874 while(jb_getall(pvt->jb,&frame) == JB_OK)
8875 iax2_frame_free(frame.data);
8876 jb_reset(pvt->jb);
8877 pvt->lag = 0;
8878 pvt->last = 0;
8879 pvt->lastsent = 0;
8880 pvt->nextpred = 0;
8883 /* We must cancel any packets that would have been transmitted
8884 because now we're talking to someone new. It's okay, they
8885 were transmitted to someone that didn't care anyway. */
8886 cur->retries = -1;
8887 }
8888 return 0;
8889}
8890
8891static void iax2_publish_registry(const char *username, const char *domain, const char *status, const char *cause)
8892{
8893 ast_system_publish_registry("IAX2", username, domain, status, cause);
8894}
8895
8896/*! \brief Acknowledgment received for OUR registration */
8897static int iax2_ack_registry(struct iax_ies *ies, struct ast_sockaddr *addr, int callno)
8898{
8899 struct iax2_registry *reg;
8900 /* Start pessimistic */
8901 char peer[256] = "";
8902 char msgstatus[60];
8903 int refresh = 60;
8904 char ourip[256] = "<Unspecified>";
8905 struct ast_sockaddr oldus;
8906 struct ast_sockaddr us;
8907 int oldmsgs;
8908
8909 if (!ast_sockaddr_isnull(&ies->apparent_addr)) {
8910 ast_sockaddr_copy(&us, &ies->apparent_addr);
8911 }
8912 if (ies->username) {
8913 ast_copy_string(peer, ies->username, sizeof(peer));
8914 }
8915 if (ies->refresh) {
8916 refresh = ies->refresh;
8917 }
8918 if (ies->calling_number) {
8919 /* We don't do anything with it really, but maybe we should */
8920 }
8921 reg = iaxs[callno]->reg;
8922 if (!reg) {
8923 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
8924 return -1;
8925 }
8926 ast_sockaddr_copy(&oldus, &reg->us);
8927 oldmsgs = reg->messages;
8928 if (ast_sockaddr_cmp(&reg->addr, addr)) {
8929 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_sockaddr_stringify(addr));
8930 return -1;
8931 }
8932 ast_sockaddr_copy(&reg->us, &us);
8933 if (ies->msgcount >= 0) {
8934 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */
8935 }
8936 /* always refresh the registration at the interval requested by the server
8937 we are registering to
8938 */
8939 reg->refresh = refresh;
8941 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
8942 if (ast_sockaddr_cmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
8943
8944 if (reg->messages > 255) {
8945 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
8946 } else if (reg->messages > 1) {
8947 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
8948 } else if (reg->messages > 0) {
8949 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
8950 } else {
8951 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
8952 }
8953
8954 snprintf(ourip, sizeof(ourip), "%s", ast_sockaddr_stringify(&reg->us));
8955
8956 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_sockaddr_stringify(addr), ourip, msgstatus);
8957 iax2_publish_registry(reg->username, ast_sockaddr_stringify(addr), "Registered", NULL);
8958 }
8960 return 0;
8961}
8962
8963static int iax2_append_register(const char *hostname, const char *username,
8964 const char *secret, const char *porta)
8965{
8966 struct iax2_registry *reg;
8967
8968 if (!(reg = ast_calloc(1, sizeof(*reg) + strlen(hostname) + 1))) {
8969 return -1;
8970 }
8971
8972 reg->addr.ss.ss_family = AST_AF_UNSPEC;
8973 if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
8974 ast_free(reg);
8975 return -1;
8976 }
8977
8978 ast_copy_string(reg->username, username, sizeof(reg->username));
8979 strcpy(reg->hostname, hostname); /* Note: This is safe */
8980
8981 if (secret) {
8982 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
8983 }
8984
8985 reg->expire = -1;
8987
8988 reg->port = ast_sockaddr_port(&reg->addr);
8989
8990 if (!porta && !reg->port) {
8991 reg->port = IAX_DEFAULT_PORTNO;
8992 } else if (porta) {
8993 sscanf(porta, "%5d", &reg->port);
8994 }
8995
8996 ast_sockaddr_set_port(&reg->addr, reg->port);
8997
9001
9002 return 0;
9003}
9004
9005static int iax2_register(const char *value, int lineno)
9006{
9007 char copy[256];
9008 char *username, *hostname, *secret;
9009 char *porta;
9010 char *stringp=NULL;
9011
9012 if (!value)
9013 return -1;
9014
9015 ast_copy_string(copy, value, sizeof(copy));
9016 stringp = copy;
9017 username = strsep(&stringp, "@");
9018 hostname = strsep(&stringp, "@");
9019
9020 if (!hostname) {
9021 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
9022 return -1;
9023 }
9024
9025 stringp = username;
9026 username = strsep(&stringp, ":");
9027 secret = strsep(&stringp, ":");
9028 stringp = hostname;
9029 hostname = strsep(&stringp, ":");
9030 porta = strsep(&stringp, ":");
9031
9032 if (porta && !atoi(porta)) {
9033 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
9034 return -1;
9035 }
9036
9038}
9039
9040
9041static void register_peer_exten(struct iax2_peer *peer, int onoff)
9042{
9043 char multi[256];
9044 char *stringp, *ext;
9046 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
9047 stringp = multi;
9048 while((ext = strsep(&stringp, "&"))) {
9049 if (onoff) {
9052 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
9053 } else
9055 }
9056 }
9057}
9058static void prune_peers(void);
9059
9060static void unlink_peer(struct iax2_peer *peer)
9061{
9062 if (peer->expire > -1) {
9063 if (!AST_SCHED_DEL(sched, peer->expire)) {
9064 peer->expire = -1;
9065 peer_unref(peer);
9066 }
9067 }
9068
9069 if (peer->pokeexpire > -1) {
9070 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
9071 peer->pokeexpire = -1;
9072 peer_unref(peer);
9073 }
9074 }
9075
9076 ao2_unlink(peers, peer);
9077}
9078
9079static void __expire_registry(const void *data)
9080{
9081 struct iax2_peer *peer = (struct iax2_peer *) data;
9082 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
9083
9084 if (!peer)
9085 return;
9086 if (peer->expire == -1) {
9087 /* Removed already (possibly through CLI), ignore */
9088 return;
9089 }
9090
9091 peer->expire = -1;
9092
9093 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
9095 realtime_update_peer(peer->name, &peer->addr, 0);
9097 blob = ast_json_pack("{s: s, s: s}",
9098 "peer_status", "Unregistered",
9099 "cause", "Expired");
9101 /* modify entry in peercnts table as _not_ registered */
9102 peercnt_modify((unsigned char) 0, 0, &peer->addr);
9103 /* Reset the address */
9104 ast_sockaddr_setnull(&peer->addr);
9105 /* Reset expiry value */
9106 peer->expiry = min_reg_expire;
9107 if (!ast_test_flag64(peer, IAX_TEMPONLY))
9108 ast_db_del("IAX/Registry", peer->name);
9109 register_peer_exten(peer, 0);
9110 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
9111 if (iax2_regfunk)
9112 iax2_regfunk(peer->name, 0);
9113
9115 unlink_peer(peer);
9116
9117 peer_unref(peer);
9118}
9119
9120static int expire_registry(const void *data)
9121{
9122#ifdef SCHED_MULTITHREADED
9124#endif
9125 __expire_registry(data);
9126 return 0;
9127}
9128
9129static void reg_source_db(struct iax2_peer *p)
9130{
9131 char data[80];
9132 char *expiry;
9133
9134 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
9135 return;
9136 }
9137
9138 expiry = strrchr(data, ':');
9139 if (!expiry) {
9140 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
9141 return;
9142 }
9143 *expiry++ = '\0';
9144
9145 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
9146 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
9147 return;
9148 }
9149
9150 p->expiry = atoi(expiry);
9151
9152 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
9154
9155 iax2_poke_peer(p, 0);
9156 if (p->expire > -1) {
9157 if (!AST_SCHED_DEL(sched, p->expire)) {
9158 p->expire = -1;
9159 peer_unref(p);
9160 }
9161 }
9162
9163 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
9164
9165 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
9166 if (p->expire == -1) {
9167 peer_unref(p);
9168 }
9169
9170 if (iax2_regfunk) {
9171 iax2_regfunk(p->name, 1);
9172 }
9173
9174 register_peer_exten(p, 1);
9175}
9176
9177/*!
9178 * \pre iaxsl[callno] is locked
9179 *
9180 * \note Since this function calls send_command_final(), the pvt struct for
9181 * the given call number may disappear while executing this function.
9182 */
9183static int update_registry(struct ast_sockaddr *addr, int callno, char *devtype, int fd, unsigned short refresh)
9184{
9185
9186 /* Called from IAX thread only, with proper iaxsl lock */
9187 struct iax_ie_data ied = {
9188 .pos = 0,
9189 };
9190 struct iax2_peer *p;
9191 int msgcount;
9192 char data[80];
9193 uint16_t version;
9194 const char *peer_name;
9195 int res = -1;
9196 char *str_addr;
9197
9198 peer_name = ast_strdupa(iaxs[callno]->peer);
9199
9200 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
9202 if (!(p = find_peer(peer_name, 1))) {
9204 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
9205 return -1;
9206 }
9208 if (!iaxs[callno])
9209 goto return_unref;
9210
9212 if (!ast_sockaddr_isnull(addr)) {
9213 time_t nowtime;
9214 time(&nowtime);
9215 realtime_update_peer(peer_name, addr, nowtime);
9216 } else {
9217 realtime_update_peer(peer_name, addr, 0);
9218 }
9219 }
9220
9221 /* treat an unspecified refresh interval as the minimum */
9222 if (!refresh) {
9224 }
9225 if (refresh > max_reg_expire) {
9226 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
9229 } else if (refresh < min_reg_expire) {
9230 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
9233 } else {
9234 p->expiry = refresh;
9235 }
9236
9237 if (ast_sockaddr_cmp(&p->addr, addr)) {
9238 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
9239
9240 if (iax2_regfunk) {
9241 iax2_regfunk(p->name, 1);
9242 }
9243
9244 /* modify entry in peercnts table as _not_ registered */
9245 peercnt_modify((unsigned char) 0, 0, &p->addr);
9246
9247 /* Stash the IP address from which they registered */
9249
9251
9252 snprintf(data, sizeof(data), "%s:%d", ast_sockaddr_stringify(addr), p->expiry);
9253
9255 ast_db_put("IAX/Registry", p->name, data);
9256 ast_verb(3, "Registered IAX2 '%s' (%s) at %s\n",
9257 p->name,
9258 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED",
9261 blob = ast_json_pack("{s: s, s: s, s: i}",
9262 "peer_status", "Registered",
9263 "address", str_addr,
9264 "port", ast_sockaddr_port(addr));
9265 register_peer_exten(p, 1);
9266 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
9267 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
9268 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n",
9269 p->name,
9270 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
9272 blob = ast_json_pack("{s: s}",
9273 "peer_status", "Unregistered");
9274 register_peer_exten(p, 0);
9275 ast_db_del("IAX/Registry", p->name);
9276 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
9277 }
9278
9280
9281 /* Update the host */
9282 /* Verify that the host is really there */
9284 }
9285
9286 /* modify entry in peercnts table as registered */
9287 if (p->maxcallno) {
9288 peercnt_modify((unsigned char) 1, p->maxcallno, &p->addr);
9289 }
9290
9291 /* Make sure our call still exists, an INVAL at the right point may make it go away */
9292 if (!iaxs[callno]) {
9293 res = -1;
9294 goto return_unref;
9295 }
9296
9297 /* Store socket fd */
9298 p->sockfd = fd;
9299 /* Setup the expiry */
9300 if (p->expire > -1) {
9301 if (!AST_SCHED_DEL(sched, p->expire)) {
9302 p->expire = -1;
9303 peer_unref(p);
9304 }
9305 }
9306
9307 if (p->expiry && !ast_sockaddr_isnull(addr)) {
9308 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
9309 if (p->expire == -1)
9310 peer_unref(p);
9311 }
9314 if (!ast_sockaddr_isnull(addr)) {
9315 struct ast_sockaddr peer_addr;
9316
9317 ast_sockaddr_copy(&peer_addr, &p->addr);
9318
9320 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
9321 if (!ast_strlen_zero(p->mailbox)) {
9322 int new, old;
9323 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
9324
9326 if (msg) {
9327 struct ast_mwi_state *mwi_state = stasis_message_data(msg);
9328 new = mwi_state->new_msgs;
9329 old = mwi_state->old_msgs;
9330 } else { /* Fall back on checking the mailbox directly */
9331 ast_app_inboxcount(p->mailbox, &new, &old);
9332 }
9333
9334 if (new > 255) {
9335 new = 255;
9336 }
9337 if (old > 255) {
9338 old = 255;
9339 }
9340 msgcount = (old << 8) | new;
9341
9342 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
9343 }
9347 }
9348 }
9349 if (iax_firmware_get_version(devtype, &version)) {
9351 }
9352
9353 res = 0;
9354
9355return_unref:
9356 peer_unref(p);
9357
9358 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
9359}
9360
9361static int registry_authrequest(int callno)
9362{
9363 struct iax_ie_data ied;
9364 struct iax2_peer *p;
9365 char challenge[10];
9366 const char *peer_name;
9367 int sentauthmethod;
9368
9369 peer_name = ast_strdupa(iaxs[callno]->peer);
9370
9371 /* SLD: third call to find_peer in registration */
9373 if ((p = find_peer(peer_name, 1))) {
9375 }
9376
9378 if (!iaxs[callno])
9379 goto return_unref;
9380
9381 memset(&ied, 0, sizeof(ied));
9382 /* The selection of which delayed reject is sent may leak information,
9383 * if it sets a static response. For example, if a host is known to only
9384 * use MD5 authentication, then an RSA response would indicate that the
9385 * peer does not exist, and vice-versa.
9386 * Therefore, we use whatever the last peer used (which may vary over the
9387 * course of a server, which should leak minimal information). */
9388 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : IAX_AUTH_MD5;
9389 if (!p) {
9390 iaxs[callno]->authmethods = sentauthmethod;
9391 }
9392 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
9393 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
9394 /* Build the challenge */
9395 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
9398 }
9399 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
9400
9401return_unref:
9402 if (p) {
9403 peer_unref(p);
9404 }
9405
9406 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
9407}
9408
9409static int registry_rerequest(struct iax_ies *ies, int callno, struct ast_sockaddr *addr)
9410{
9411 struct iax2_registry *reg;
9412 /* Start pessimistic */
9413 struct iax_ie_data ied;
9414 char peer[256] = "";
9415 char challenge[256] = "";
9416 int res;
9417 int authmethods = 0;
9418 if (ies->authmethods)
9419 authmethods = ies->authmethods;
9420 if (ies->username)
9421 ast_copy_string(peer, ies->username, sizeof(peer));
9422 if (ies->challenge)
9424 memset(&ied, 0, sizeof(ied));
9425 reg = iaxs[callno]->reg;
9426 if (reg) {
9427
9428 if (ast_sockaddr_cmp(&reg->addr, addr)) {
9429 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_sockaddr_stringify(addr));
9430 return -1;
9431 }
9432 if (ast_strlen_zero(reg->secret)) {
9433 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
9435 return -1;
9436 }
9439 if (reg->secret[0] == '[') {
9440 char tmpkey[256];
9441 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
9442 tmpkey[strlen(tmpkey) - 1] = '\0';
9443 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, addr, NULL);
9444 } else
9445 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, addr, NULL);
9446 if (!res) {
9448 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
9449 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
9450 } else
9451 return -1;
9452 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
9453 } else
9454 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
9455 return -1;
9456}
9457
9458static void stop_stuff(int callno)
9459{
9460 iax2_destroy_helper(iaxs[callno]);
9461}
9462
9463static void __auth_reject(const void *nothing)
9464{
9465 /* Called from IAX thread only, without iaxs lock */
9466 int callno = (int)(long)(nothing);
9467 struct iax_ie_data ied;
9468 ast_mutex_lock(&iaxsl[callno]);
9469 if (iaxs[callno]) {
9470 memset(&ied, 0, sizeof(ied));
9471 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
9472 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
9474 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
9475 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
9477 }
9478 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
9479 }
9480 ast_mutex_unlock(&iaxsl[callno]);
9481}
9482
9483static int auth_reject(const void *data)
9484{
9485 int callno = (int)(long)(data);
9486 ast_mutex_lock(&iaxsl[callno]);
9487 if (iaxs[callno])
9488 iaxs[callno]->authid = -1;
9489 ast_mutex_unlock(&iaxsl[callno]);
9490#ifdef SCHED_MULTITHREADED
9491 if (schedule_action(__auth_reject, data))
9492#endif
9493 __auth_reject(data);
9494 return 0;
9495}
9496
9497static int auth_fail(int callno, int failcode)
9498{
9499 /* Schedule sending the authentication failure in one second, to prevent
9500 guessing */
9501 if (iaxs[callno]) {
9502 iaxs[callno]->authfail = failcode;
9503 if (delayreject) {
9504 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
9505 sched, 1000, auth_reject, (void *)(long)callno);
9506 } else
9507 auth_reject((void *)(long)callno);
9508 }
9509 return 0;
9510}
9511
9512static void __auto_hangup(const void *nothing)
9513{
9514 /* Called from IAX thread only, without iaxs lock */
9515 int callno = (int)(long)(nothing);
9516 struct iax_ie_data ied;
9517 ast_mutex_lock(&iaxsl[callno]);
9518 if (iaxs[callno]) {
9519 memset(&ied, 0, sizeof(ied));
9520 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
9522 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
9523 }
9524 ast_mutex_unlock(&iaxsl[callno]);
9525}
9526
9527static int auto_hangup(const void *data)
9528{
9529 int callno = (int)(long)(data);
9530 ast_mutex_lock(&iaxsl[callno]);
9531 if (iaxs[callno]) {
9532 iaxs[callno]->autoid = -1;
9533 }
9534 ast_mutex_unlock(&iaxsl[callno]);
9535#ifdef SCHED_MULTITHREADED
9536 if (schedule_action(__auto_hangup, data))
9537#endif
9538 __auto_hangup(data);
9539 return 0;
9540}
9541
9542static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
9543{
9544 struct iax_ie_data ied;
9545 /* Auto-hangup with 30 seconds of inactivity */
9546 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
9547 sched, 30000, auto_hangup, (void *)(long)callno);
9548 memset(&ied, 0, sizeof(ied));
9550 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
9552}
9553
9554static int iax2_vnak(int callno)
9555{
9556 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
9557}
9558
9559static void vnak_retransmit(int callno, int last)
9560{
9561 struct iax_frame *f;
9562
9564 /* Send a copy immediately */
9565 if (((unsigned char) (f->oseqno - last) < 128) &&
9566 (f->retries >= 0)) {
9567 send_packet(f);
9568 }
9569 }
9570}
9571
9572static void __iax2_poke_peer_s(const void *data)
9573{
9574 struct iax2_peer *peer = (struct iax2_peer *)data;
9575 iax2_poke_peer(peer, 0);
9576 peer_unref(peer);
9577}
9578
9579static int iax2_poke_peer_s(const void *data)
9580{
9581 struct iax2_peer *peer = (struct iax2_peer *)data;
9582 peer->pokeexpire = -1;
9583#ifdef SCHED_MULTITHREADED
9585#endif
9586 __iax2_poke_peer_s(data);
9587 return 0;
9588}
9589
9590static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
9591{
9592 int res = 0;
9593 struct iax_frame *fr;
9594 struct ast_iax2_meta_hdr *meta;
9595 struct ast_iax2_meta_trunk_hdr *mth;
9596 int calls = 0;
9597
9598 /* Point to frame */
9599 fr = (struct iax_frame *)tpeer->trunkdata;
9600 /* Point to meta data */
9601 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
9602 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
9603 if (tpeer->trunkdatalen) {
9604 /* We're actually sending a frame, so fill the meta trunk header and meta header */
9605 meta->zeros = 0;
9606 meta->metacmd = IAX_META_TRUNK;
9608 meta->cmddata = IAX_META_TRUNK_MINI;
9609 else
9610 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
9611 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
9612 /* And the rest of the ast_iax2 header */
9614 fr->retrans = -1;
9615 fr->transfer = 0;
9616 /* Any appropriate call will do */
9617 fr->data = fr->afdata;
9618 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
9619 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
9620 calls = tpeer->calls;
9621#if 0
9622 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));
9623#endif
9624 /* Reset transmit trunk side data */
9625 tpeer->trunkdatalen = 0;
9626 tpeer->calls = 0;
9627 }
9628 if (res < 0)
9629 return res;
9630 return calls;
9631}
9632
9633static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
9634{
9635 /* Drop when trunk is about 5 seconds idle */
9636 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
9637 return 1;
9638 return 0;
9639}
9640
9641static int timing_read(int *id, int fd, short events, void *cbdata)
9642{
9643 int res, processed = 0, totalcalls = 0;
9644 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
9645 struct timeval now = ast_tvnow();
9646
9647 if (iaxtrunkdebug) {
9648 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
9649 }
9650
9651 if (timer) {
9652 if (ast_timer_ack(timer, 1) < 0) {
9653 ast_log(LOG_ERROR, "Timer failed acknowledge\n");
9654 return 0;
9655 }
9656 }
9657
9658 /* For each peer that supports trunking... */
9660 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
9661 processed++;
9662 res = 0;
9663 ast_mutex_lock(&tpeer->lock);
9664 /* We can drop a single tpeer per pass. That makes all this logic
9665 substantially easier */
9666 if (!drop && iax2_trunk_expired(tpeer, &now)) {
9667 /* Take it out of the list, but don't free it yet, because it
9668 could be in use */
9670 drop = tpeer;
9671 } else {
9672 res = send_trunk(tpeer, &now);
9673 trunk_timed++;
9674 if (iaxtrunkdebug) {
9675 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",
9677 res,
9678 (res != 1) ? "s" : "",
9679 tpeer->trunkdatalen,
9680 tpeer->trunkdataalloc);
9681 }
9682 }
9683 totalcalls += res;
9684 res = 0;
9685 ast_mutex_unlock(&tpeer->lock);
9686 }
9689
9690 if (drop) {
9691 ast_mutex_lock(&drop->lock);
9692 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it,
9693 because by the time they could get tpeerlock, we've already grabbed it */
9694 ast_debug(1, "Dropping unused iax2 trunk peer '%s'\n", ast_sockaddr_stringify(&drop->addr));
9695 if (drop->trunkdata) {
9696 ast_free(drop->trunkdata);
9697 drop->trunkdata = NULL;
9698 }
9699 ast_mutex_unlock(&drop->lock);
9700 ast_mutex_destroy(&drop->lock);
9701 ast_free(drop);
9702 }
9703
9704 if (iaxtrunkdebug) {
9705 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
9706 }
9707 iaxtrunkdebug = 0;
9708
9709 return 1;
9710}
9711
9712struct dpreq_data {
9713 int callno;
9716 char *callerid;
9717};
9718
9719static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
9720{
9721 unsigned short dpstatus = 0;
9722 struct iax_ie_data ied1;
9723 int mm;
9724
9725 memset(&ied1, 0, sizeof(ied1));
9726 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
9727 /* Must be started */
9728 if (ast_exists_extension(NULL, context, callednum, 1, callerid)) {
9729 dpstatus = IAX_DPSTATUS_EXISTS;
9730 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
9731 dpstatus = IAX_DPSTATUS_CANEXIST;
9732 } else {
9733 dpstatus = IAX_DPSTATUS_NONEXISTENT;
9734 }
9735 if (ast_ignore_pattern(context, callednum))
9736 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
9737 if (mm)
9738 dpstatus |= IAX_DPSTATUS_MATCHMORE;
9739 if (!skiplock)
9740 ast_mutex_lock(&iaxsl[callno]);
9741 if (iaxs[callno]) {
9742 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
9743 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
9745 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
9746 }
9747 if (!skiplock)
9748 ast_mutex_unlock(&iaxsl[callno]);
9749}
9750
9751static void *dp_lookup_thread(void *data)
9752{
9753 /* Look up for dpreq */
9754 struct dpreq_data *dpr = data;
9755 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
9756 if (dpr->callerid)
9757 ast_free(dpr->callerid);
9758 ast_free(dpr);
9759 return NULL;
9760}
9761
9762static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
9763{
9764 pthread_t newthread;
9765 struct dpreq_data *dpr;
9766
9767 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
9768 return;
9769
9770 dpr->callno = callno;
9771 ast_copy_string(dpr->context, context, sizeof(dpr->context));
9772 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
9773 if (callerid)
9775 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
9776 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
9777 }
9778}
9779
9780static int check_provisioning(struct ast_sockaddr *addr, int sockfd, char *si, unsigned int ver)
9781{
9782 unsigned int ourver;
9783 char rsi[80];
9784 snprintf(rsi, sizeof(rsi), "si-%s", si);
9785 if (iax_provision_version(&ourver, rsi, 1))
9786 return 0;
9787 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
9788 if (ourver != ver)
9789 iax2_provision(addr, sockfd, NULL, rsi, 1);
9790 return 0;
9791}
9792
9793static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
9794{
9795 jb_info stats;
9796 jb_getinfo(pvt->jb, &stats);
9797
9798 memset(iep, 0, sizeof(*iep));
9799
9801 if(stats.frames_in == 0) stats.frames_in = 1;
9802 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
9804 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
9807}
9808
9809static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
9810{
9811 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
9812 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
9813 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
9814 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
9815 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
9816 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
9817 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
9818}
9819
9820static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
9821{
9822 int i;
9823 unsigned int length, offset = 0;
9824 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
9825
9826 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
9827 length = ies->ospblocklength[i];
9828 if (length != 0) {
9829 if (length > IAX_MAX_OSPBLOCK_SIZE) {
9830 /* OSP token block length wrong, clear buffer */
9831 offset = 0;
9832 break;
9833 } else {
9834 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
9835 offset += length;
9836 }
9837 } else {
9838 break;
9839 }
9840 }
9841 *(full_osptoken + offset) = '\0';
9842 if (strlen(full_osptoken) != offset) {
9843 /* OSP token length wrong, clear buffer */
9844 *full_osptoken = '\0';
9845 }
9846
9847 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
9848}
9849
9850static void log_jitterstats(unsigned short callno)
9851{
9852 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
9853 jb_info jbinfo;
9854
9856 if (iaxs[callno] && iaxs[callno]->owner && ast_channel_name(iaxs[callno]->owner)) {
9858 jb_getinfo(iaxs[callno]->jb, &jbinfo);
9859 localjitter = jbinfo.jitter;
9860 localdelay = jbinfo.current - jbinfo.min;
9861 locallost = jbinfo.frames_lost;
9862 locallosspct = jbinfo.losspct/1000;
9863 localdropped = jbinfo.frames_dropped;
9864 localooo = jbinfo.frames_ooo;
9865 localpackets = jbinfo.frames_in;
9866 }
9867 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",
9868 ast_channel_name(iaxs[callno]->owner),
9869 iaxs[callno]->pingtime,
9870 localjitter,
9871 localdelay,
9872 locallost,
9873 locallosspct,
9874 localdropped,
9875 localooo,
9876 localpackets,
9877 iaxs[callno]->remote_rr.jitter,
9884 }
9886}
9887
9888static int socket_process(struct iax2_thread *thread);
9889
9890/*!
9891 * \brief Handle any deferred full frames for this thread
9892 */
9894{
9895 struct iax2_pkt_buf *pkt_buf;
9896
9897 ast_mutex_lock(&thread->lock);
9898
9899 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
9900 ast_mutex_unlock(&thread->lock);
9901
9902 thread->buf = pkt_buf->buf;
9903 thread->buf_len = pkt_buf->len;
9904 thread->buf_size = pkt_buf->len + 1;
9905
9907
9908 thread->buf = NULL;
9909 ast_free(pkt_buf);
9910
9911 ast_mutex_lock(&thread->lock);
9912 }
9913
9914 ast_mutex_unlock(&thread->lock);
9915}
9916
9917/*!
9918 * \brief Queue the last read full frame for processing by a certain thread
9919 *
9920 * If there are already any full frames queued, they are sorted
9921 * by sequence number.
9922 */
9923static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
9924{
9925 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
9926 struct ast_iax2_full_hdr *fh, *cur_fh;
9927
9928 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
9929 return;
9930
9931 pkt_buf->len = from_here->buf_len;
9932 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
9933
9934 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
9935 ast_mutex_lock(&to_here->lock);
9936 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
9937 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
9938 if (fh->oseqno < cur_fh->oseqno) {
9939 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
9940 break;
9941 }
9942 }
9944
9945 if (!cur_pkt_buf)
9946 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
9947
9948 to_here->iostate = IAX_IOSTATE_READY;
9949 ast_cond_signal(&to_here->cond);
9950
9951 ast_mutex_unlock(&to_here->lock);
9952}
9953
9954static int socket_read(int *id, int fd, short events, void *cbdata)
9955{
9956 struct iax2_thread *thread;
9957 time_t t;
9958 static time_t last_errtime = 0;
9959 struct ast_iax2_full_hdr *fh;
9960
9961 if (!(thread = find_idle_thread())) {
9962 time(&t);
9963 if (t != last_errtime) {
9964 last_errtime = t;
9965 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
9966 }
9967 usleep(1);
9968 return 1;
9969 }
9970
9971 thread->iofd = fd;
9972 thread->buf_len = ast_recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, &thread->ioaddr);
9973 thread->buf_size = sizeof(thread->readbuf);
9974 thread->buf = thread->readbuf;
9975 if (thread->buf_len < 0) {
9976 if (errno != ECONNREFUSED && errno != EAGAIN)
9977 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
9978 handle_error();
9979 thread->iostate = IAX_IOSTATE_IDLE;
9980 signal_condition(&thread->lock, &thread->cond);
9981 return 1;
9982 }
9983 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
9984 thread->iostate = IAX_IOSTATE_IDLE;
9985 signal_condition(&thread->lock, &thread->cond);
9986 return 1;
9987 }
9988
9989 /* Determine if this frame is a full frame; if so, and any thread is currently
9990 processing a full frame for the same callno from this peer, then drop this
9991 frame (and the peer will retransmit it) */
9992 fh = (struct ast_iax2_full_hdr *) thread->buf;
9993 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
9994 struct iax2_thread *cur = NULL;
9995 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
9996
9999 if ((cur->ffinfo.callno == callno) &&
10000 !ast_sockaddr_cmp_addr(&cur->ffinfo.addr, &thread->ioaddr))
10001 break;
10002 }
10003 if (cur) {
10004 /* we found another thread processing a full frame for this call,
10005 so queue it up for processing later. */
10008 thread->iostate = IAX_IOSTATE_IDLE;
10009 signal_condition(&thread->lock, &thread->cond);
10010 return 1;
10011 } else {
10012 /* this thread is going to process this frame, so mark it */
10013 thread->ffinfo.callno = callno;
10014 ast_sockaddr_copy(&thread->ffinfo.addr, &thread->ioaddr);
10015 thread->ffinfo.type = fh->type;
10016 thread->ffinfo.csub = fh->csub;
10018 }
10020 }
10021
10022 /* Mark as ready and send on its way */
10023 thread->iostate = IAX_IOSTATE_READY;
10024#ifdef DEBUG_SCHED_MULTITHREAD
10025 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
10026#endif
10027 signal_condition(&thread->lock, &thread->cond);
10028
10029 return 1;
10030}
10031
10032static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct ast_sockaddr *addr, int sockfd,
10033 struct iax_frame *fr)
10034{
10035 unsigned char metatype;
10036 struct ast_iax2_meta_trunk_mini *mtm;
10037 struct ast_iax2_meta_trunk_hdr *mth;
10038 struct ast_iax2_meta_trunk_entry *mte;
10039 struct iax2_trunk_peer *tpeer;
10040 unsigned int ts;
10041 void *ptr;
10042 struct timeval rxtrunktime;
10043 struct ast_frame f = { 0, };
10044
10045 if (packet_len < sizeof(*meta)) {
10046 ast_log(LOG_WARNING, "Rejecting packet from '%s' that is flagged as a meta frame but is too short\n",
10048 return 1;
10049 }
10050
10051 if (meta->metacmd != IAX_META_TRUNK)
10052 return 1;
10053
10054 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
10055 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
10056 (int) (sizeof(*meta) + sizeof(*mth)));
10057 return 1;
10058 }
10059 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
10060 ts = ntohl(mth->ts);
10061 metatype = meta->cmddata;
10062 packet_len -= (sizeof(*meta) + sizeof(*mth));
10063 ptr = mth->data;
10064 tpeer = find_tpeer(addr, sockfd);
10065 if (!tpeer) {
10066 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s': No matching peer\n",
10068 return 1;
10069 }
10070 tpeer->trunkact = ast_tvnow();
10071 if (!ts || ast_tvzero(tpeer->rxtrunktime))
10072 tpeer->rxtrunktime = tpeer->trunkact;
10073 rxtrunktime = tpeer->rxtrunktime;
10074 ast_mutex_unlock(&tpeer->lock);
10075 while (packet_len >= sizeof(*mte)) {
10076 /* Process channels */
10077 unsigned short callno, trunked_ts, len;
10078
10079 if (metatype == IAX_META_TRUNK_MINI) {
10080 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
10081 ptr += sizeof(*mtm);
10082 packet_len -= sizeof(*mtm);
10083 len = ntohs(mtm->len);
10084 callno = ntohs(mtm->mini.callno);
10085 trunked_ts = ntohs(mtm->mini.ts);
10086 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
10087 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
10088 ptr += sizeof(*mte);
10089 packet_len -= sizeof(*mte);
10090 len = ntohs(mte->len);
10091 callno = ntohs(mte->callno);
10092 trunked_ts = 0;
10093 } else {
10094 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s': dropping\n", ast_sockaddr_stringify(addr));
10095 break;
10096 }
10097 /* Stop if we don't have enough data */
10098 if (len > packet_len)
10099 break;
10100 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, addr, NEW_PREVENT, sockfd, 0);
10101 if (!fr->callno)
10102 continue;
10103
10104 /* If it's a valid call, deliver the contents. If not, we
10105 drop it, since we don't have a scallno to use for an INVAL */
10106 /* Process as a mini frame */
10107 memset(&f, 0, sizeof(f));
10109 if (!iaxs[fr->callno]) {
10110 /* drop it */
10111 } else if (iaxs[fr->callno]->voiceformat == 0) {
10112 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
10113 iax2_vnak(fr->callno);
10115 iaxs[fr->callno]->voiceformat))) {
10116 f.datalen = len;
10117 if (f.datalen >= 0) {
10118 if (f.datalen)
10119 f.data.ptr = ptr;
10120 else
10121 f.data.ptr = NULL;
10122 if (trunked_ts)
10123 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
10124 else
10125 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
10126 /* Don't pass any packets until we're started */
10128 struct iax_frame *duped_fr;
10129
10130 /* Common things */
10131 f.src = "IAX2";
10132 f.mallocd = 0;
10133 f.offset = 0;
10134 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
10136 else
10137 f.samples = 0;
10138 fr->outoforder = 0;
10139 iax_frame_wrap(fr, &f);
10140 duped_fr = iaxfrdup2(fr);
10141 if (duped_fr)
10142 schedule_delivery(duped_fr, 1, 1, &fr->ts);
10143 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
10144 iaxs[fr->callno]->last = fr->ts;
10145 }
10146 } else {
10147 ast_log(LOG_WARNING, "Datalen < 0?\n");
10148 }
10149 }
10151 ptr += len;
10152 packet_len -= len;
10153 }
10154
10155 return 1;
10156}
10157
10158static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
10159{
10160 struct ast_datastore *variablestore;
10161 AST_LIST_HEAD(, ast_var_t) *varlist;
10162 struct ast_var_t *var;
10163
10164 if (!chan) {
10165 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
10166 return -1;
10167 }
10168
10170 if (!variablestore) {
10171 *buf = '\0';
10172 return 0;
10173 }
10174 varlist = variablestore->data;
10175
10176 AST_LIST_LOCK(varlist);
10177 AST_LIST_TRAVERSE(varlist, var, entries) {
10178 if (strcmp(var->name, data) == 0) {
10179 ast_copy_string(buf, var->value, len);
10180 break;
10181 }
10182 }
10183 AST_LIST_UNLOCK(varlist);
10184 return 0;
10185}
10186
10187static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
10188{
10189 struct ast_datastore *variablestore;
10190 AST_LIST_HEAD(, ast_var_t) *varlist;
10191 struct ast_var_t *var;
10192
10193 if (!chan) {
10194 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
10195 return -1;
10196 }
10197
10199 if (!variablestore) {
10201 if (!variablestore) {
10202 ast_log(LOG_ERROR, "Memory allocation error\n");
10203 return -1;
10204 }
10205 varlist = ast_calloc(1, sizeof(*varlist));
10206 if (!varlist) {
10207 ast_datastore_free(variablestore);
10208 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
10209 return -1;
10210 }
10211
10212 AST_LIST_HEAD_INIT(varlist);
10213 variablestore->data = varlist;
10214 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10215 ast_channel_datastore_add(chan, variablestore);
10216 } else
10217 varlist = variablestore->data;
10218
10219 AST_LIST_LOCK(varlist);
10221 if (strcmp(var->name, data) == 0) {
10224 break;
10225 }
10226 }
10228 var = ast_var_assign(data, value);
10229 if (var)
10230 AST_LIST_INSERT_TAIL(varlist, var, entries);
10231 else
10232 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
10233 AST_LIST_UNLOCK(varlist);
10234 return 0;
10235}
10236
10237static struct ast_custom_function iaxvar_function = {
10238 .name = "IAXVAR",
10239 .read = acf_iaxvar_read,
10240 .write = acf_iaxvar_write,
10241};
10242
10243static void set_hangup_source_and_cause(int callno, unsigned char causecode)
10244{
10245 iax2_lock_owner(callno);
10246 if (iaxs[callno] && iaxs[callno]->owner) {
10247 struct ast_channel *owner;
10248 const char *name;
10249
10250 owner = iaxs[callno]->owner;
10251 if (causecode) {
10252 ast_channel_hangupcause_set(owner, causecode);
10253 }
10255 ast_channel_ref(owner);
10256 ast_channel_unlock(owner);
10257 ast_mutex_unlock(&iaxsl[callno]);
10258 ast_set_hangupsource(owner, name, 0);
10259 ast_channel_unref(owner);
10260 ast_mutex_lock(&iaxsl[callno]);
10261 }
10262}
10263
10264static int socket_process_helper(struct iax2_thread *thread)
10265{
10266 struct ast_sockaddr addr;
10267 int res;
10268 int updatehistory=1;
10269 int new = NEW_PREVENT;
10270 int dcallno = 0;
10271 char decrypted = 0;
10272 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
10273 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
10274 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
10275 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
10276 struct iax_frame *fr;
10277 struct iax_frame *cur;
10278 struct ast_frame f = { 0, };
10279 struct ast_channel *c = NULL;
10280 struct iax2_dpcache *dp;
10281 struct iax2_peer *peer;
10282 struct iax_ies ies;
10283 struct iax_ie_data ied0, ied1;
10284 iax2_format format;
10285 int fd;
10286 int exists;
10287 int minivid = 0;
10288 char empty[32]=""; /* Safety measure */
10289 struct iax_frame *duped_fr;
10290 char host_pref_buf[128];
10291 char caller_pref_buf[128];
10292 struct iax2_codec_pref pref;
10293 char *using_prefs = "mine";
10294
10295 /* allocate an iax_frame with 4096 bytes of data buffer */
10296 fr = ast_alloca(sizeof(*fr) + 4096);
10297 memset(fr, 0, sizeof(*fr));
10298 fr->afdatalen = 4096; /* From ast_alloca() above */
10299
10300 /* Copy frequently used parameters to the stack */
10301 res = thread->buf_len;
10302 fd = thread->iofd;
10303 ast_sockaddr_copy(&addr, &thread->ioaddr);
10304
10305 if (res < sizeof(*mh)) {
10306 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
10307 return 1;
10308 }
10309 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
10310 if (res < sizeof(*vh)) {
10311 ast_log(LOG_WARNING, "Rejecting packet from '%s' that is flagged as a video frame but is too short\n",
10312 ast_sockaddr_stringify(&addr));
10313 return 1;
10314 }
10315
10316 /* This is a video frame, get call number */
10317 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &addr, new, fd, 0);
10318 minivid = 1;
10319 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
10320 return socket_process_meta(res, meta, &addr, fd, fr);
10321
10322#ifdef DEBUG_SUPPORT
10323 if (res >= sizeof(*fh))
10324 iax_outputframe(NULL, fh, 1, &addr, res - sizeof(*fh));
10325#endif
10326 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10327 if (res < sizeof(*fh)) {
10328 ast_log(LOG_WARNING, "Rejecting packet from '%s' that is flagged as a full frame but is too short\n",
10329 ast_sockaddr_stringify(&addr));
10330 return 1;
10331 }
10332
10333 /* Get the destination call number */
10334 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
10335
10336
10337 /* check to make sure this full frame isn't encrypted before we attempt
10338 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the
10339 * callno is not found here, that just means one hasn't been allocated for
10340 * this connection yet. */
10341 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &addr, NEW_PREVENT, fd, 1))) {
10343 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
10344 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10345 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10347 return 1;
10348 }
10349 decrypted = 1;
10350 }
10352 }
10353
10354 /* Retrieve the type and subclass */
10355 f.frametype = fh->type;
10356 if (f.frametype == AST_FRAME_VIDEO) {
10358 if (!f.subclass.format) {
10359 return 1;
10360 }
10361 if ((fh->csub >> 6) & 0x1) {
10362 f.subclass.frame_ending = 1;
10363 }
10364 } else if (f.frametype == AST_FRAME_VOICE) {
10366 if (!f.subclass.format) {
10367 return 1;
10368 }
10369 } else {
10371 }
10372
10373 /* Deal with POKE/PONG without allocating a callno */
10375 /* Reply back with a PONG, but don't care about the result. */
10376 send_apathetic_reply(1, ntohs(fh->scallno), &addr, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10377 return 1;
10378 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
10379 /* Ignore */
10380 return 1;
10381 }
10382
10383 f.datalen = res - sizeof(*fh);
10384 if (f.datalen) {
10385 if (f.frametype == AST_FRAME_IAX) {
10386 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
10387 char subclass[40];
10388 iax_frame_subclass2str(f.subclass.integer, subclass, sizeof(subclass));
10389 ast_log(LOG_WARNING, "Undecodable %s frame received from '%s'\n", subclass, ast_sockaddr_stringify(&addr));
10391 return 1;
10392 }
10393 f.data.ptr = NULL;
10394 f.datalen = 0;
10395 } else {
10396 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
10397 memset(&ies, 0, sizeof(ies));
10398 }
10399 } else {
10400 if (f.frametype == AST_FRAME_IAX)
10401 f.data.ptr = NULL;
10402 else
10403 f.data.ptr = empty;
10404 memset(&ies, 0, sizeof(ies));
10405 }
10406
10407 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
10408 /* only set NEW_ALLOW if calltoken checks out */
10409 if (handle_call_token(fh, &ies, &addr, fd)) {
10411 return 1;
10412 }
10413
10414 if (ies.calltoken && ies.calltokendata) {
10415 /* if we've gotten this far, and the calltoken ie data exists,
10416 * then calltoken validation _MUST_ have taken place. If calltoken
10417 * data is provided, it is always validated regardless of any
10418 * calltokenoptional or requirecalltoken options */
10420 } else {
10421 new = NEW_ALLOW;
10422 }
10423 }
10424 } else {
10425 /* Don't know anything about it yet */
10427 f.subclass.integer = 0;
10428 memset(&ies, 0, sizeof(ies));
10429 }
10430
10431 if (!fr->callno) {
10432 int check_dcallno = 0;
10433
10434 /*
10435 * We enforce accurate destination call numbers for ACKs. This forces the other
10436 * end to know the destination call number before call setup can complete.
10437 *
10438 * Discussed in the following thread:
10439 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html
10440 */
10441
10442 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10443 check_dcallno = 1;
10444 }
10445
10446 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &addr, new, fd, check_dcallno))) {
10447 ast_debug(1, "Received frame without existent call number (%d)\n", ntohs(mh->callno) & ~IAX_FLAG_FULL);
10449 send_apathetic_reply(1, ntohs(fh->scallno), &addr, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10451 send_apathetic_reply(1, ntohs(fh->scallno), &addr, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10452 } else {
10453 ast_log(LOG_WARNING, "Silently dropping frame without existent call number: %d\n", ntohs(mh->callno) & ~IAX_FLAG_FULL);
10454 }
10456 return 1;
10457 }
10458 }
10459
10460 if (fr->callno > 0) {
10461 ast_callid mount_callid;
10463 if (iaxs[fr->callno] && ((mount_callid = iax_pvt_callid_get(fr->callno)))) {
10464 /* Bind to thread */
10465 ast_callid_threadassoc_add(mount_callid);
10466 }
10467 }
10468
10469 if (!fr->callno || !iaxs[fr->callno]) {
10470 /* A call arrived for a nonexistent destination. Unless it's an "inval"
10471 frame, reply with an inval */
10472 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10473 /* We can only raw hangup control frames */
10474 if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10478 (f.frametype != AST_FRAME_IAX))
10479 raw_hangup(&addr, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10480 fd);
10481 }
10482 if (fr->callno > 0){
10484 }
10486 return 1;
10487 }
10488 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10489 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10490 ast_log(LOG_WARNING, "Packet Decrypt Failed!\n");
10493 return 1;
10494 }
10495 decrypted = 1;
10496 }
10497
10498#ifdef DEBUG_SUPPORT
10499 if (decrypted) {
10500 iax_outputframe(NULL, fh, 3, &addr, res - sizeof(*fh));
10501 }
10502#endif
10503
10504 if (iaxs[fr->callno]->owner && fh->type == AST_FRAME_IAX &&
10505 (fh->csub == IAX_COMMAND_HANGUP
10506 || fh->csub == IAX_COMMAND_REJECT
10507 || fh->csub == IAX_COMMAND_REGREJ
10508 || fh->csub == IAX_COMMAND_TXREJ)) {
10509 struct ast_control_pvt_cause_code *cause_code;
10510 int data_size = sizeof(*cause_code);
10511 char subclass[40] = "";
10512
10513 /* get subclass text */
10514 iax_frame_subclass2str(fh->csub, subclass, sizeof(subclass));
10515
10516 /* add length of "IAX2 " */
10517 data_size += 5;
10518 /* for IAX hangup frames, add length of () and number */
10519 data_size += 3;
10520 if (ies.causecode > 9) {
10521 data_size++;
10522 }
10523 if (ies.causecode > 99) {
10524 data_size++;
10525 }
10526 /* add length of subclass */
10527 data_size += strlen(subclass);
10528
10529 cause_code = ast_alloca(data_size);
10530 memset(cause_code, 0, data_size);
10532
10533 cause_code->ast_cause = ies.causecode;
10534 snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "IAX2 %s(%d)", subclass, ies.causecode);
10535
10537 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10538 ast_queue_control_data(iaxs[fr->callno]->owner, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
10539 ast_channel_hangupcause_hash_set(iaxs[fr->callno]->owner, cause_code, data_size);
10541 }
10542 if (!iaxs[fr->callno]) {
10545 return 1;
10546 }
10547 }
10548
10549 /* count this frame */
10550 iaxs[fr->callno]->frames_received++;
10551
10552 if (!ast_sockaddr_cmp(&addr, &iaxs[fr->callno]->addr) && !minivid &&
10553 f.subclass.integer != IAX_COMMAND_TXCNT && /* for attended transfer */
10554 f.subclass.integer != IAX_COMMAND_TXACC) { /* for attended transfer */
10555 unsigned short new_peercallno;
10556
10557 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10558 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10559 if (iaxs[fr->callno]->peercallno) {
10561 }
10562 iaxs[fr->callno]->peercallno = new_peercallno;
10564 }
10565 }
10566 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10567 if (iaxdebug)
10568 ast_debug(1, "Received packet %d, (%u, %d)\n", fh->oseqno, f.frametype, f.subclass.integer);
10569 /* Check if it's out of order (and not an ACK or INVAL) */
10570 fr->oseqno = fh->oseqno;
10571 fr->iseqno = fh->iseqno;
10572 fr->ts = ntohl(fh->ts);
10573#ifdef IAXTESTS
10574 if (test_resync) {
10575 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10576 fr->ts += test_resync;
10577 }
10578#endif /* IAXTESTS */
10579#if 0
10580 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10581 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10582 (f.subclass == IAX_COMMAND_NEW ||
10585 f.subclass == IAX_COMMAND_REJECT)) ) )
10586#endif
10587 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10588 updatehistory = 0;
10589 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10590 (iaxs[fr->callno]->iseqno ||
10592 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */
10593 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */
10594 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
10596 (f.frametype != AST_FRAME_IAX))) {
10597 if (
10601 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */
10602 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */
10603 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
10606 (f.frametype != AST_FRAME_IAX)) {
10607 /* If it's not an ACK packet, it's out of order. */
10608 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %u, subclass = %d)\n",
10609 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10610 /* Check to see if we need to request retransmission,
10611 * and take sequence number wraparound into account */
10612 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10613 /* If we've already seen it, ack it XXX There's a border condition here XXX */
10614 if ((f.frametype != AST_FRAME_IAX) ||
10616 ast_debug(1, "Acking anyway\n");
10617 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
10618 we have anything to send, we'll retransmit and get an ACK back anyway XXX */
10620 }
10621 } else {
10622 /* Send a VNAK requesting retransmission */
10623 iax2_vnak(fr->callno);
10624 }
10627 return 1;
10628 }
10629 } else {
10630 /* Increment unless it's an ACK or VNAK */
10631 if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10636 (f.frametype != AST_FRAME_IAX))
10637 iaxs[fr->callno]->iseqno++;
10638 }
10639 /* Ensure text frames are NULL-terminated */
10640 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10641 if (res < thread->buf_size)
10642 thread->buf[res++] = '\0';
10643 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
10644 thread->buf[res - 1] = '\0';
10645 }
10646
10647 /* Handle implicit ACKing unless this is an INVAL, and only if this is
10648 from the real peer, not the transfer peer */
10649 if (!ast_sockaddr_cmp(&addr, &iaxs[fr->callno]->addr) &&
10651 (f.frametype != AST_FRAME_IAX))) {
10652 unsigned char x;
10653 int call_to_destroy;
10654 /* First we have to qualify that the ACKed value is within our window */
10655 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10656 x = fr->iseqno;
10657 else
10658 x = iaxs[fr->callno]->oseqno;
10659 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10660 /* The acknowledgement is within our window. Time to acknowledge everything
10661 that it says to */
10662 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10663 /* Ack the packet with the given timestamp */
10664 if (iaxdebug)
10665 ast_debug(1, "Cancelling transmission of packet %d\n", x);
10666 call_to_destroy = 0;
10667 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10668 /* If it's our call, and our timestamp, mark -1 retries */
10669 if (x == cur->oseqno) {
10670 cur->retries = -1;
10671 /* Destroy call if this is the end */
10672 if (cur->final)
10673 call_to_destroy = fr->callno;
10674 }
10675 }
10676 if (call_to_destroy) {
10677 if (iaxdebug)
10678 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10679 ast_mutex_lock(&iaxsl[call_to_destroy]);
10680 iax2_destroy(call_to_destroy);
10681 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10682 }
10683 }
10684 /* Note how much we've received acknowledgement for */
10685 if (iaxs[fr->callno])
10686 iaxs[fr->callno]->rseqno = fr->iseqno;
10687 else {
10688 /* Stop processing now */
10691 return 1;
10692 }
10693 } else {
10694 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10695 }
10696 }
10697 if (ast_sockaddr_cmp(&addr, &iaxs[fr->callno]->addr) &&
10698 ((f.frametype != AST_FRAME_IAX) ||
10701 /* Only messages we accept from a transfer host are TXACC and TXCNT */
10704 return 1;
10705 }
10706
10707 /* when we receive the first full frame for a new incoming channel,
10708 it is safe to start the PBX on the channel because we have now
10709 completed a 3-way handshake with the peer */
10710 if ((f.frametype == AST_FRAME_VOICE) ||
10711 (f.frametype == AST_FRAME_VIDEO) ||
10712 (f.frametype == AST_FRAME_IAX)) {
10720 return 1;
10721 }
10722 }
10723
10724 if (ies.vars) {
10725 struct ast_datastore *variablestore = NULL;
10726 struct ast_variable *var, *prev = NULL;
10727 AST_LIST_HEAD(, ast_var_t) *varlist;
10728
10730 if (!iaxs[fr->callno]) {
10733 return 1;
10734 }
10735 if ((c = iaxs[fr->callno]->owner)) {
10736 varlist = ast_calloc(1, sizeof(*varlist));
10738
10739 if (variablestore && varlist) {
10740 variablestore->data = varlist;
10741 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10742 AST_LIST_HEAD_INIT(varlist);
10743 ast_debug(1, "I can haz IAX vars?\n");
10744 for (var = ies.vars; var; var = var->next) {
10745 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10746 if (prev) {
10747 ast_free(prev);
10748 }
10749 prev = var;
10750 if (!newvar) {
10751 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
10752 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10753 } else {
10754 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10755 }
10756 }
10757 if (prev) {
10758 ast_free(prev);
10759 }
10760 ies.vars = NULL;
10761 ast_channel_datastore_add(c, variablestore);
10762 } else {
10763 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10764 if (variablestore) {
10765 ast_datastore_free(variablestore);
10766 }
10767 if (varlist) {
10768 ast_free(varlist);
10769 }
10770 }
10772 } else {
10773 /* No channel yet, so transfer the variables directly over to the pvt,
10774 * for later inheritance. */
10775 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10776 for (var = ies.vars; var && var->next; var = var->next);
10777 if (var) {
10778 var->next = iaxs[fr->callno]->iaxvars;
10779 iaxs[fr->callno]->iaxvars = ies.vars;
10780 ies.vars = NULL;
10781 }
10782 }
10783 }
10784
10785 if (ies.vars) {
10786 ast_debug(1, "I have IAX variables, but they were not processed\n");
10787 }
10788 }
10789
10790 /* once we receive our first IAX Full Frame that is not CallToken related, send all
10791 * queued signaling frames that were being held. */
10794 }
10795
10796 if (f.frametype == AST_FRAME_VOICE) {
10799 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_format_get_name(f.subclass.format));
10800 if (iaxs[fr->callno]->owner) {
10802 if (iaxs[fr->callno]) {
10803 if (iaxs[fr->callno]->owner) {
10805 if (native) {
10810 }
10811 ao2_ref(native, -1);
10812 }
10814 }
10815 } else {
10816 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10817 /* Free remote variables (if any) */
10818 if (ies.vars) {
10820 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
10821 ies.vars = NULL;
10822 }
10824 return 1;
10825 }
10826 }
10827 }
10828 }
10829 if (f.frametype == AST_FRAME_VIDEO) {
10831 ast_debug(1, "Ooh, video format changed to %s\n", ast_format_get_name(f.subclass.format));
10833 }
10834 }
10835 if (f.frametype == AST_FRAME_IAX) {
10837 /* Handle the IAX pseudo frame itself */
10838 if (iaxdebug)
10839 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10840
10841 /* Update last ts unless the frame's timestamp originated with us. */
10842 if (iaxs[fr->callno]->last < fr->ts &&
10846 iaxs[fr->callno]->last = fr->ts;
10847 if (iaxdebug)
10848 ast_debug(1, "For call=%d, set last=%u\n", fr->callno, fr->ts);
10849 }
10851 if (!iaxs[fr->callno]->first_iax_message) {
10853 }
10854 switch(f.subclass.integer) {
10855 case IAX_COMMAND_ACK:
10856 /* Do nothing */
10857 break;
10858 case IAX_COMMAND_QUELCH:
10861 if (ies.musiconhold) {
10862 const char *moh_suggest;
10863
10865 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10866 break;
10867 }
10868
10869 /*
10870 * We already hold the owner lock so we do not
10871 * need to check iaxs[fr->callno] after it returns.
10872 */
10873 moh_suggest = iaxs[fr->callno]->mohsuggest;
10874 iax2_queue_hold(fr->callno, moh_suggest);
10876 }
10877 }
10878 break;
10882 if (!iaxs[fr->callno]) {
10883 break;
10884 }
10885
10887 if (!iaxs[fr->callno]->owner) {
10888 break;
10889 }
10890
10891 /*
10892 * We already hold the owner lock so we do not
10893 * need to check iaxs[fr->callno] after it returns.
10894 */
10897 }
10898 break;
10899 case IAX_COMMAND_TXACC:
10900 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10901 /* Ack the packet with the given timestamp */
10902 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10903 /* Cancel any outstanding txcnt's */
10904 if (cur->transfer) {
10905 cur->retries = -1;
10906 }
10907 }
10908 memset(&ied1, 0, sizeof(ied1));
10910 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10912 }
10913 break;
10914 case IAX_COMMAND_NEW:
10915 /* Ignore if it's already up */
10917 break;
10918 if (ies.provverpres && ies.serviceident && !(ast_sockaddr_isnull(&addr))) {
10920 check_provisioning(&addr, fd, ies.serviceident, ies.provver);
10922 if (!iaxs[fr->callno]) {
10923 break;
10924 }
10925 }
10926 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
10927 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10928 int new_callno;
10929 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10930 fr->callno = new_callno;
10931 }
10932 /* For security, always ack immediately */
10933 if (delayreject)
10935 if (check_access(fr->callno, &addr, &ies)) {
10936 /* They're not allowed on */
10938 if (authdebug) {
10939 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n",
10941 }
10942 break;
10943 }
10946 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10947 break;
10948 }
10949 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10950 const char *context, *exten, *cid_num;
10951
10953 exten = ast_strdupa(iaxs[fr->callno]->exten);
10954 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10955
10956 /* This might re-enter the IAX code and need the lock */
10958 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10960
10961 if (!iaxs[fr->callno]) {
10962 break;
10963 }
10964 } else
10965 exists = 0;
10966 /* Get OSP token if it does exist */
10967 save_osptoken(fr, &ies);
10969 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10970 memset(&ied0, 0, sizeof(ied0));
10971 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10973 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10974 if (!iaxs[fr->callno]) {
10975 break;
10976 }
10977 if (authdebug) {
10978 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n",
10980 }
10981 } else {
10982 /* Select an appropriate format */
10983
10986 using_prefs = "reqonly";
10987 } else {
10988 using_prefs = "disabled";
10989 }
10990 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10991 memset(&pref, 0, sizeof(pref));
10992 strcpy(caller_pref_buf, "disabled");
10993 strcpy(host_pref_buf, "disabled");
10994 } else {
10995 struct ast_format *tmpfmt;
10996 using_prefs = "mine";
10997 /* If the information elements are in here... use them */
10998 if (ies.codec_prefs)
11000 if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11001 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
11003 pref = iaxs[fr->callno]->rprefs;
11004 using_prefs = "caller";
11005 } else {
11006 pref = iaxs[fr->callno]->prefs;
11007 }
11008 } else
11009 pref = iaxs[fr->callno]->prefs;
11010
11011 format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability);
11012 iax2_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11013 iax2_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11014 }
11015 if (!format) {
11017 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11018 if (!format) {
11019 memset(&ied0, 0, sizeof(ied0));
11020 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11022 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11023 if (!iaxs[fr->callno]) {
11024 break;
11025 }
11026 if (authdebug) {
11029 struct ast_str *peer_form_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11030
11032 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11034 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11036 } else {
11037 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11039 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11042 }
11043 }
11044 } else {
11045 /* Pick one... */
11047 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11048 format = 0;
11049 } else {
11051 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11052 memset(&pref, 0, sizeof(pref));
11054 strcpy(caller_pref_buf,"disabled");
11055 strcpy(host_pref_buf,"disabled");
11056 } else {
11057 struct ast_format *tmpfmt;
11058 using_prefs = "mine";
11059 if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11060 /* Do the opposite of what we tried above. */
11062 pref = iaxs[fr->callno]->prefs;
11063 } else {
11064 pref = iaxs[fr->callno]->rprefs;
11065 using_prefs = "caller";
11066 }
11067 format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11068 } else /* if no codec_prefs IE do it the old way */
11070 }
11071 }
11072
11073 if (!format) {
11076 struct ast_str *peer_form_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11077
11078 memset(&ied0, 0, sizeof(ied0));
11079 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11081 ast_log(LOG_ERROR, "No best format in '%s'???\n", iax2_getformatname_multiple(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, &cap_buf));
11082 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11083 if (!iaxs[fr->callno]) {
11084 break;
11085 }
11086 if (authdebug) {
11087 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11089 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11092 }
11094 break;
11095 }
11096 }
11097 }
11098 if (format) {
11099 /* No authentication required, let them in */
11100 memset(&ied1, 0, sizeof(ied1));
11101 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11103 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11104 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11106 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
11107 "%srequested format = %s,\n"
11108 "%srequested prefs = %s,\n"
11109 "%sactual format = %s,\n"
11110 "%shost prefs = %s,\n"
11111 "%spriority = %s\n",
11116 caller_pref_buf,
11118 iax2_getformatname(format),
11120 host_pref_buf,
11122 using_prefs);
11123
11124 iaxs[fr->callno]->chosenformat = format;
11125
11126 /* Since this is a new call, we should go ahead and set the callid for it. */
11129 } else {
11131 /* If this is a TBD call, we're ready but now what... */
11132 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_sockaddr_stringify(&addr));
11133 }
11134 }
11135 }
11136 break;
11137 }
11140 else
11141 iaxs[fr->callno]->encmethods = 0;
11142 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
11144 break;
11145 case IAX_COMMAND_DPREQ:
11146 /* Request status in the dialplan */
11149 if (iaxcompat) {
11150 /* Spawn a thread for the lookup */
11152 } else {
11153 /* Just look it up */
11154 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
11155 }
11156 }
11157 break;
11158 case IAX_COMMAND_HANGUP:
11160 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
11161 /* Set hangup cause according to remote and hangupsource */
11162 if (iaxs[fr->callno]->owner) {
11164 if (!iaxs[fr->callno]) {
11165 break;
11166 }
11167 }
11168
11169 /* Send ack immediately, before we destroy */
11171 iax2_destroy(fr->callno);
11172 break;
11173 case IAX_COMMAND_REJECT:
11174 /* Set hangup cause according to remote and hangup source */
11175 if (iaxs[fr->callno]->owner) {
11177 if (!iaxs[fr->callno]) {
11178 break;
11179 }
11180 }
11181
11183 if (iaxs[fr->callno]->owner && authdebug)
11184 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
11186 ies.cause ? ies.cause : "<Unknown>");
11187 ast_debug(1, "Immediately destroying %d, having received reject\n",
11188 fr->callno);
11189 }
11190 /* Send ack immediately, before we destroy */
11192 fr->ts, NULL, 0, fr->iseqno);
11194 iaxs[fr->callno]->error = EPERM;
11195 iax2_destroy(fr->callno);
11196 break;
11198 {
11200 if (!iaxs[fr->callno]) {
11201 /* Initiating call went away before we could transfer. */
11202 break;
11203 }
11204 if (iaxs[fr->callno]->owner) {
11205 struct ast_channel *owner = iaxs[fr->callno]->owner;
11206 char *context = ast_strdupa(iaxs[fr->callno]->context);
11207
11208 ast_channel_ref(owner);
11209 ast_channel_unlock(owner);
11211
11212 if (ast_bridge_transfer_blind(1, owner, ies.called_number,
11214 ast_log(LOG_WARNING, "Blind transfer of '%s' to '%s@%s' failed\n",
11215 ast_channel_name(owner), ies.called_number,
11216 context);
11217 }
11218
11219 ast_channel_unref(owner);
11221 }
11222
11223 break;
11224 }
11225 case IAX_COMMAND_ACCEPT:
11226 /* Ignore if call is already up or needs authentication or is a TBD */
11228 break;
11230 /* Send ack immediately, before we destroy */
11232 iax2_destroy(fr->callno);
11233 break;
11234 }
11235 if (ies.format) {
11236 iaxs[fr->callno]->peerformat = ies.format;
11237 } else {
11238 if (iaxs[fr->callno]->owner)
11240 else
11242 }
11243 ast_verb(3, "Call accepted by %s (format %s)\n", ast_sockaddr_stringify(&addr),
11245 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
11246 memset(&ied0, 0, sizeof(ied0));
11247 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11249 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11250 if (!iaxs[fr->callno]) {
11251 break;
11252 }
11253 if (authdebug) {
11256
11257 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
11261 }
11262 } else {
11264
11267 if (iaxs[fr->callno] && iaxs[fr->callno]->owner && native) {
11269
11270 /* Switch us to use a compatible format */
11272 iaxs[fr->callno]->peerformat, &iaxs[fr->callno]->rprefs,
11273 native);
11275 ast_verb(3, "Format for call is %s\n", ast_format_cap_get_names(ast_channel_nativeformats(iaxs[fr->callno]->owner), &cap_buf));
11276
11277 /* Setup read/write formats properly. */
11283 }
11284
11285 ao2_cleanup(native);
11286 }
11287 if (iaxs[fr->callno]) {
11289 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
11290 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
11291 iax2_dprequest(dp, fr->callno);
11293 }
11294 break;
11295 case IAX_COMMAND_POKE:
11296 /* Send back a pong packet with the original timestamp */
11298 break;
11299 case IAX_COMMAND_PING:
11300 {
11301 struct iax_ie_data pingied;
11302 construct_rr(iaxs[fr->callno], &pingied);
11303 /* Send back a pong packet with the original timestamp */
11304 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
11305 }
11306 break;
11307 case IAX_COMMAND_PONG:
11308 /* Calculate ping time */
11309 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
11310 /* save RR info */
11311 save_rr(fr, &ies);
11312
11313 /* Good time to write jb stats for this call */
11315
11316 if (iaxs[fr->callno]->peerpoke) {
11317 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
11318 peer = iaxs[fr->callno]->peerpoke;
11319 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
11320 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
11321 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %u\n", peer->name, iaxs[fr->callno]->pingtime);
11323 blob = ast_json_pack("{s: s, s: I}",
11324 "peer_status", "Reachable",
11325 "time", (ast_json_int_t)iaxs[fr->callno]->pingtime);
11326 ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
11327 }
11328 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
11329 if (iaxs[fr->callno]->pingtime > peer->maxms) {
11330 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%u ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
11332 blob = ast_json_pack("{s: s, s: I}",
11333 "peer_status", "Lagged",
11334 "time", (ast_json_int_t)iaxs[fr->callno]->pingtime);
11335 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
11336 }
11337 }
11339 peer->lastms = iaxs[fr->callno]->pingtime;
11340 if (peer->smoothing && (peer->lastms > -1))
11341 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
11342 else if (peer->smoothing && peer->lastms < 0)
11343 peer->historicms = (0 + peer->historicms) / 2;
11344 else
11345 peer->historicms = iaxs[fr->callno]->pingtime;
11346
11347 /* Remove scheduled iax2_poke_noanswer */
11348 if (peer->pokeexpire > -1) {
11349 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
11350 peer_unref(peer);
11351 peer->pokeexpire = -1;
11352 }
11353 }
11354 /* Schedule the next cycle */
11355 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
11357 else
11359 if (peer->pokeexpire == -1)
11360 peer_unref(peer);
11361 /* and finally send the ack */
11363 /* And wrap up the qualify call */
11364 iax2_destroy(fr->callno);
11365 peer->callno = 0;
11366 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
11367 }
11368 break;
11369 case IAX_COMMAND_LAGRQ:
11370 case IAX_COMMAND_LAGRP:
11371 f.src = "LAGRQ";
11372 f.mallocd = 0;
11373 f.offset = 0;
11374 f.samples = 0;
11375 iax_frame_wrap(fr, &f);
11377 /* Received a LAGRQ - echo back a LAGRP */
11379 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
11380 } else {
11381 /* Received LAGRP in response to our LAGRQ */
11382 unsigned int ts;
11383 /* This is a reply we've been given, actually measure the difference */
11384 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
11385 iaxs[fr->callno]->lag = ts - fr->ts;
11386 if (iaxdebug)
11387 ast_debug(1, "Peer %s lag measured as %dms\n",
11388 ast_sockaddr_stringify(&addr), iaxs[fr->callno]->lag);
11389 }
11390 break;
11393 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>");
11394 break;
11395 }
11396 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
11397 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
11398 .subclass.integer = AST_CONTROL_HANGUP,
11399 };
11401 "I don't know how to authenticate %s to %s\n",
11402 ies.username ? ies.username : "<unknown>", ast_sockaddr_stringify(&addr));
11403 iax2_queue_frame(fr->callno, &hangup_fr);
11404 }
11405 break;
11407 /* For security, always ack immediately */
11408 if (delayreject)
11410 /* Ignore once we've started */
11412 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>");
11413 break;
11414 }
11415 if (authenticate_verify(iaxs[fr->callno], &ies)) {
11416 if (authdebug)
11417 ast_log(LOG_WARNING, "Host %s failed to authenticate as %s\n", ast_sockaddr_stringify(&addr),
11418 iaxs[fr->callno]->username);
11419 memset(&ied0, 0, sizeof(ied0));
11421 break;
11422 }
11423 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
11424 /* This might re-enter the IAX code and need the lock */
11426 } else
11427 exists = 0;
11428 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
11429 if (authdebug)
11430 ast_log(LOG_WARNING, "Rejected connect attempt from %s, request '%s@%s' does not exist\n",
11432 iaxs[fr->callno]->exten,
11433 iaxs[fr->callno]->context);
11434 memset(&ied0, 0, sizeof(ied0));
11435 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11437 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11438 if (!iaxs[fr->callno]) {
11439 break;
11440 }
11441 } else {
11442 /* Select an appropriate format */
11445 using_prefs = "reqonly";
11446 } else {
11447 using_prefs = "disabled";
11448 }
11449 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
11450 memset(&pref, 0, sizeof(pref));
11451 strcpy(caller_pref_buf, "disabled");
11452 strcpy(host_pref_buf, "disabled");
11453 } else {
11454 struct ast_format *tmpfmt;
11455 using_prefs = "mine";
11456 if (ies.codec_prefs)
11458 if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11460 pref = iaxs[fr->callno]->rprefs;
11461 using_prefs = "caller";
11462 } else {
11463 pref = iaxs[fr->callno]->prefs;
11464 }
11465 } else /* if no codec_prefs IE do it the old way */
11466 pref = iaxs[fr->callno]->prefs;
11467 format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability);
11468 iax2_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11469 iax2_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11470 }
11471 if (!format) {
11474 struct ast_str *peer_form_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11475
11477 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11480 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11481 }
11482 if (!format) {
11483 if (authdebug) {
11485 ast_log(LOG_WARNING, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11487 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11489 } else {
11490 ast_log(LOG_WARNING, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11492 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11495 }
11496 }
11497 memset(&ied0, 0, sizeof(ied0));
11498 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11500 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11501 if (!iaxs[fr->callno]) {
11502 break;
11503 }
11504 } else {
11505 /* Pick one... */
11507 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11508 format = 0;
11509 } else {
11511 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11512 memset(&pref, 0, sizeof(pref));
11514 ? iaxs[fr->callno]->peerformat
11516 strcpy(caller_pref_buf,"disabled");
11517 strcpy(host_pref_buf,"disabled");
11518 } else {
11519 struct ast_format *tmpfmt;
11520 using_prefs = "mine";
11521 if (iax2_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11522 /* Do the opposite of what we tried above. */
11524 pref = iaxs[fr->callno]->prefs;
11525 } else {
11526 pref = iaxs[fr->callno]->rprefs;
11527 using_prefs = "caller";
11528 }
11529 format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11530 } else /* if no codec_prefs IE do it the old way */
11532 }
11533 }
11534 if (!format) {
11537 struct ast_str *peer_form_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
11538
11539 ast_log(LOG_ERROR, "No best format in %s???\n",
11541 if (authdebug) {
11543 ast_log(LOG_WARNING, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11545 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11547 } else {
11548 ast_log(LOG_WARNING, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11550 iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &peer_form_buf),
11553 }
11554 }
11555 memset(&ied0, 0, sizeof(ied0));
11556 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11558 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11559 if (!iaxs[fr->callno]) {
11560 break;
11561 }
11562 }
11563 }
11564 }
11565 if (format) {
11566 /* Authentication received */
11567 memset(&ied1, 0, sizeof(ied1));
11568 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11570 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11571 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11572 char authmethodnames[AUTH_METHOD_NAMES_BUFSIZE];
11574 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11575 "%srequested auth methods = (%s),\n"
11576 "%sactual auth method = %s,\n"
11577 "%sencrypted = %s,\n"
11578 "%srequested format = %s,\n"
11579 "%srequested prefs = %s,\n"
11580 "%sactual format = %s,\n"
11581 "%shost prefs = %s,\n"
11582 "%spriority = %s\n",
11585 auth_method_names(iaxs[fr->callno]->authmethods, authmethodnames),
11589 IAX_CALLENCRYPTED(iaxs[fr->callno]) ? "yes" : "no",
11591 iax2_getformatname(iaxs[fr->callno]->peerformat),
11593 caller_pref_buf,
11595 iax2_getformatname(format),
11597 host_pref_buf,
11599 using_prefs);
11600
11601 /* Unlike unauthenticated calls, we don't need to store
11602 * the chosen format for channel creation.
11603 * However, this is helpful for __get_from_jb. */
11604 iaxs[fr->callno]->chosenformat = format;
11605
11607 c = ast_iax2_new(fr->callno, AST_STATE_RING, format,
11608 &iaxs[fr->callno]->rprefs, NULL, NULL, 1);
11609 if (!c) {
11610 iax2_destroy(fr->callno);
11611 } else if (ies.vars) {
11612 struct ast_datastore *variablestore;
11613 struct ast_variable *var, *prev = NULL;
11614 AST_LIST_HEAD(, ast_var_t) *varlist;
11615 varlist = ast_calloc(1, sizeof(*varlist));
11617 if (variablestore && varlist) {
11618 variablestore->data = varlist;
11619 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11620 AST_LIST_HEAD_INIT(varlist);
11621 ast_debug(1, "I can haz IAX vars? w00t\n");
11622 for (var = ies.vars; var; var = var->next) {
11623 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11624 if (prev)
11625 ast_free(prev);
11626 prev = var;
11627 if (!newvar) {
11628 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11629 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11630 } else {
11631 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11632 }
11633 }
11634 if (prev)
11635 ast_free(prev);
11636 ies.vars = NULL;
11637 ast_channel_datastore_add(c, variablestore);
11638 } else {
11639 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11640 if (variablestore)
11641 ast_datastore_free(variablestore);
11642 if (varlist)
11643 ast_free(varlist);
11644 }
11645 }
11646 } else {
11648 /* If this is a TBD call, we're ready but now what... */
11649 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_sockaddr_stringify(&addr));
11651 goto immediatedial;
11652 }
11653 }
11654 }
11655 }
11656 break;
11657 case IAX_COMMAND_DIAL:
11658immediatedial:
11661 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11662 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11663 if (authdebug)
11664 ast_log(LOG_WARNING, "Rejected dial attempt from %s, request '%s@%s' does not exist\n",
11666 iaxs[fr->callno]->exten,
11667 iaxs[fr->callno]->context);
11668 memset(&ied0, 0, sizeof(ied0));
11669 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11671 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11672 if (!iaxs[fr->callno]) {
11673 break;
11674 }
11675 } else {
11678 ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11684 iaxs[fr->callno]->peerformat, &iaxs[fr->callno]->rprefs,
11685 NULL, NULL, 1);
11686 if (!c) {
11687 iax2_destroy(fr->callno);
11688 } else if (ies.vars) {
11689 struct ast_datastore *variablestore;
11690 struct ast_variable *var, *prev = NULL;
11691 AST_LIST_HEAD(, ast_var_t) *varlist;
11692 varlist = ast_calloc(1, sizeof(*varlist));
11694 ast_debug(1, "I can haz IAX vars? w00t\n");
11695 if (variablestore && varlist) {
11696 variablestore->data = varlist;
11697 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11698 AST_LIST_HEAD_INIT(varlist);
11699 for (var = ies.vars; var; var = var->next) {
11700 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11701 if (prev)
11702 ast_free(prev);
11703 prev = var;
11704 if (!newvar) {
11705 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11706 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11707 } else {
11708 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11709 }
11710 }
11711 if (prev)
11712 ast_free(prev);
11713 ies.vars = NULL;
11714 ast_channel_datastore_add(c, variablestore);
11715 } else {
11716 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11717 if (variablestore)
11718 ast_datastore_free(variablestore);
11719 if (varlist)
11720 ast_free(varlist);
11721 }
11722 }
11723 }
11724 }
11725 break;
11726 case IAX_COMMAND_INVAL:
11727 iaxs[fr->callno]->error = ENOTCONN;
11728 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11729 iax2_destroy(fr->callno);
11730 ast_debug(1, "Destroying call %d\n", fr->callno);
11731 break;
11732 case IAX_COMMAND_VNAK:
11733 ast_debug(1, "Received VNAK: resending outstanding frames\n");
11734 /* Force retransmission */
11735 vnak_retransmit(fr->callno, fr->iseqno);
11736 break;
11737 case IAX_COMMAND_REGREQ:
11738 case IAX_COMMAND_REGREL:
11739 /* For security, always ack immediately */
11740 if (delayreject)
11742 if (register_verify(fr->callno, &addr, &ies)) {
11743 if (!iaxs[fr->callno]) {
11744 break;
11745 }
11746 /* Send delayed failure */
11748 break;
11749 }
11750 if (!iaxs[fr->callno]) {
11751 break;
11752 }
11755
11757 ast_sockaddr_setnull(&addr);
11758 }
11759 if (update_registry(&addr, fr->callno, ies.devicetype, fd, ies.refresh)) {
11760 ast_log(LOG_WARNING, "Registry error\n");
11761 }
11762 if (!iaxs[fr->callno]) {
11763 break;
11764 }
11765 if (ies.provverpres && ies.serviceident && !(ast_sockaddr_isnull(&addr))) {
11767 check_provisioning(&addr, fd, ies.serviceident, ies.provver);
11769 }
11770 break;
11771 }
11773 break;
11774 case IAX_COMMAND_REGACK:
11775 if (iax2_ack_registry(&ies, &addr, fr->callno)) {
11776 ast_log(LOG_WARNING, "Registration failure\n");
11777 }
11778 /* Send ack immediately, before we destroy */
11780 iax2_destroy(fr->callno);
11781 break;
11782 case IAX_COMMAND_REGREJ:
11783 if (iaxs[fr->callno]->reg) {
11784 if (authdebug) {
11785 ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n",
11786 iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>",
11787 ast_sockaddr_stringify(&addr));
11788 }
11789 iax2_publish_registry(iaxs[fr->callno]->reg->username, ast_sockaddr_stringify(&addr), "Rejected", S_OR(ies.cause, "<unknown>"));
11791 }
11792 /* Send ack immediately, before we destroy */
11794 iax2_destroy(fr->callno);
11795 break;
11797 /* Authentication request */
11798 if (registry_rerequest(&ies, fr->callno, &addr)) {
11799 memset(&ied0, 0, sizeof(ied0));
11800 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11802 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11803 }
11804 break;
11805 case IAX_COMMAND_TXREJ:
11806 while (iaxs[fr->callno]
11807 && iaxs[fr->callno]->bridgecallno
11810 }
11811 if (!iaxs[fr->callno]) {
11812 break;
11813 }
11814
11816 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11817 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11818
11819 if (!iaxs[fr->callno]->bridgecallno) {
11820 break;
11821 }
11822
11823 if (iaxs[iaxs[fr->callno]->bridgecallno]
11827 }
11829 break;
11831 while (iaxs[fr->callno]
11832 && iaxs[fr->callno]->bridgecallno
11835 }
11836 if (!iaxs[fr->callno]) {
11837 break;
11838 }
11839
11840 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
11842 } else if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) {
11844 } else {
11845 if (iaxs[fr->callno]->bridgecallno) {
11847 }
11848 break;
11849 }
11850 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11851
11852 if (!iaxs[fr->callno]->bridgecallno) {
11853 break;
11854 }
11855
11856 if (!iaxs[iaxs[fr->callno]->bridgecallno]
11860 break;
11861 }
11862
11863 /* Both sides are ready */
11864
11865 /* XXX what isn't checked here is that both sides match transfer types. */
11866
11867 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11868 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
11869 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : "<Unknown>");
11870
11873
11874 memset(&ied0, 0, sizeof(ied0));
11875 memset(&ied1, 0, sizeof(ied1));
11878 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11879 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11880 } else {
11881 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
11882 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : "<Unknown>");
11883
11888
11889 /* Stop doing lag & ping requests */
11890 stop_stuff(fr->callno);
11892
11893 memset(&ied0, 0, sizeof(ied0));
11894 memset(&ied1, 0, sizeof(ied1));
11897 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11898 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11899 }
11901 break;
11902 case IAX_COMMAND_TXREQ:
11903 try_transfer(iaxs[fr->callno], &ies);
11904 break;
11905 case IAX_COMMAND_TXCNT:
11906 if (iaxs[fr->callno]->transferring)
11908 break;
11909 case IAX_COMMAND_TXREL:
11910 /* Send ack immediately, rather than waiting until we've changed addresses */
11912 complete_transfer(fr->callno, &ies);
11913 stop_stuff(fr->callno); /* for attended transfer to work with libiax */
11914 break;
11916 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11917 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11918 /* Cancel any outstanding frames and start anew */
11919 if (cur->transfer) {
11920 cur->retries = -1;
11921 }
11922 }
11923 /* Start sending our media to the transfer address, but otherwise leave the call as-is */
11925 }
11926 break;
11927 case IAX_COMMAND_RTKEY:
11928 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11930 "we've been told to rotate our encryption key, "
11931 "but this isn't an encrypted call. bad things will happen.\n"
11932 );
11933 break;
11934 }
11935
11936 IAX_DEBUGDIGEST("Receiving", ies.challenge);
11937
11938 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11939 break;
11940 case IAX_COMMAND_DPREP:
11941 complete_dpreply(iaxs[fr->callno], &ies);
11942 break;
11944 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11945 break;
11947 /* Firmware download */
11950 break;
11951 }
11952 memset(&ied0, 0, sizeof(ied0));
11953 res = iax_firmware_append(&ied0, ies.devicetype, ies.fwdesc);
11954 if (res < 0)
11955 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11956 else if (res > 0)
11957 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11958 else
11959 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11960 break;
11962 {
11963 struct iax_frame *cur;
11964 /* find last sent frame */
11965 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11966 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11967 }
11968 break;
11969 }
11970 default:
11971 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11972 memset(&ied0, 0, sizeof(ied0));
11974 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11975 }
11976 /* Free remote variables (if any) */
11977 if (ies.vars) {
11979 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11980 ies.vars = NULL;
11981 }
11982
11983 /* Don't actually pass these frames along */
11984 if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11989 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) {
11991 }
11992 }
11994 return 1;
11995 }
11996 /* Unless this is an ACK or INVAL frame, ack it */
11997 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11999 } else if (minivid) {
12001 if (iaxs[fr->callno]->videoformat > 0) {
12002 if (ntohs(vh->ts) & 0x8000LL) {
12003 f.subclass.frame_ending = 1;
12004 }
12006 if (!f.subclass.format) {
12009 return 1;
12010 }
12011 } else {
12012 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
12013 iax2_vnak(fr->callno);
12016 return 1;
12017 }
12018 f.datalen = res - sizeof(*vh);
12019 if (f.datalen)
12020 f.data.ptr = thread->buf + sizeof(*vh);
12021 else
12022 f.data.ptr = NULL;
12023#ifdef IAXTESTS
12024 if (test_resync) {
12025 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
12026 } else
12027#endif /* IAXTESTS */
12028 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
12029 } else {
12030 /* A mini frame */
12032 if (iaxs[fr->callno]->voiceformat > 0) {
12034 if (!f.subclass.format) {
12037 return 1;
12038 }
12039 } else {
12040 ast_debug(1, "Received mini frame before first full voice frame\n");
12041 iax2_vnak(fr->callno);
12044 return 1;
12045 }
12046 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
12047 if (f.datalen < 0) {
12048 ast_log(LOG_WARNING, "Datalen < 0?\n");
12051 return 1;
12052 }
12053 if (f.datalen)
12054 f.data.ptr = thread->buf + sizeof(*mh);
12055 else
12056 f.data.ptr = NULL;
12057#ifdef IAXTESTS
12058 if (test_resync) {
12059 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
12060 } else
12061#endif /* IAXTESTS */
12062 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
12063 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
12064 }
12065
12066 /* Don't pass any packets until we're started */
12067 if (!iaxs[fr->callno]
12071 return 1;
12072 }
12073
12074 if (f.frametype == AST_FRAME_CONTROL) {
12076 /* Control frame not allowed to come from the wire. */
12077 ast_debug(2, "Callno %d: Blocked receiving control frame %d.\n",
12078 fr->callno, f.subclass.integer);
12081 return 1;
12082 }
12085 if (iaxs[fr->callno]
12087 /* We are not configured to allow receiving these updates. */
12088 ast_debug(2, "Callno %d: Config blocked receiving control frame %d.\n",
12089 fr->callno, f.subclass.integer);
12092 return 1;
12093 }
12094 }
12095
12097 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
12100 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
12102 }
12104 }
12105 }
12106
12109 && iaxs[fr->callno]) {
12111
12112 /*
12113 * Process a received connected line update.
12114 *
12115 * Initialize defaults.
12116 */
12118 connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
12119 connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
12120
12122 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
12123 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
12125
12127 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
12129 S_COR(connected.id.number.valid, connected.id.number.str, ""),
12130 S_COR(connected.id.name.valid, connected.id.name.str, ""),
12131 NULL);
12132 ast_channel_caller(iaxs[fr->callno]->owner)->id.number.presentation = connected.id.number.presentation;
12133 ast_channel_caller(iaxs[fr->callno]->owner)->id.name.presentation = connected.id.name.presentation;
12135 }
12136 }
12138 }
12139
12140 /* Common things */
12141 f.src = "IAX2";
12142 f.mallocd = 0;
12143 f.offset = 0;
12144 f.len = 0;
12145 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
12147 /* We need to byteswap incoming slinear samples from network byte order */
12150 } else
12151 f.samples = 0;
12152 iax_frame_wrap(fr, &f);
12153
12154 /* If this is our most recent packet, use it as our basis for timestamping */
12155 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
12156 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
12157 fr->outoforder = 0;
12158 } else {
12159 if (iaxdebug && iaxs[fr->callno]) {
12160 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);
12161 }
12162 fr->outoforder = 1;
12163 }
12165 if (iaxs[fr->callno]) {
12166 duped_fr = iaxfrdup2(fr);
12167 if (duped_fr) {
12168 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
12169 }
12170 }
12171 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
12172 iaxs[fr->callno]->last = fr->ts;
12173#if 1
12174 if (iaxdebug)
12175 ast_debug(8, "For call=%d, set last=%u\n", fr->callno, fr->ts);
12176#endif
12177 }
12178
12179 /* Always run again */
12182 return 1;
12183}
12184
12185static int socket_process(struct iax2_thread *thread)
12186{
12187 int res = socket_process_helper(thread);
12190 }
12191 return res;
12192}
12193
12194/* Function to clean up process thread if it is cancelled */
12195static void iax2_process_thread_cleanup(void *data)
12196{
12197 struct iax2_thread *thread = data;
12198 ast_mutex_destroy(&thread->lock);
12199 ast_cond_destroy(&thread->cond);
12200 ast_mutex_destroy(&thread->init_lock);
12201 ast_cond_destroy(&thread->init_cond);
12203 /* Ignore check_return warning from Coverity for ast_atomic_dec_and_test below */
12205}
12206
12207static void *iax2_process_thread(void *data)
12208{
12209 struct iax2_thread *thread = data;
12210 struct timeval wait;
12211 struct timespec ts;
12212 int put_into_idle = 0;
12213 int first_time = 1;
12214 int old_state;
12215
12217
12218 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
12219 pthread_cleanup_push(iax2_process_thread_cleanup, data);
12220
12221 for (;;) {
12222 /* Wait for something to signal us to be awake */
12223 ast_mutex_lock(&thread->lock);
12224
12225 if (thread->stop) {
12226 ast_mutex_unlock(&thread->lock);
12227 break;
12228 }
12229
12230 /* Flag that we're ready to accept signals */
12231 if (first_time) {
12232 signal_condition(&thread->init_lock, &thread->init_cond);
12233 first_time = 0;
12234 }
12235
12236 /* Put into idle list if applicable */
12237 if (put_into_idle) {
12239 }
12240
12241 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
12242 struct iax2_thread *t = NULL;
12243 /* Wait to be signalled or time out */
12244 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
12245 ts.tv_sec = wait.tv_sec;
12246 ts.tv_nsec = wait.tv_usec * 1000;
12247 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
12248 /* This thread was never put back into the available dynamic
12249 * thread list, so just go away. */
12250 if (!put_into_idle || thread->stop) {
12251 ast_mutex_unlock(&thread->lock);
12252 break;
12253 }
12255 /* Account for the case where this thread is acquired *right* after a timeout */
12259 if (t) {
12260 /* This dynamic thread timed out waiting for a task and was
12261 * not acquired immediately after the timeout,
12262 * so it's time to go away. */
12263 ast_mutex_unlock(&thread->lock);
12264 break;
12265 }
12266 /* Someone grabbed our thread *right* after we timed out.
12267 * Wait for them to set us up with something to do and signal
12268 * us to continue. */
12269 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
12270 ts.tv_sec = wait.tv_sec;
12271 ts.tv_nsec = wait.tv_usec * 1000;
12272 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
12273 ast_mutex_unlock(&thread->lock);
12274 break;
12275 }
12276 }
12277 } else {
12278 ast_cond_wait(&thread->cond, &thread->lock);
12279 }
12280
12281 /* Go back into our respective list */
12282 put_into_idle = 1;
12283
12284 ast_mutex_unlock(&thread->lock);
12285
12286 if (thread->stop) {
12287 break;
12288 }
12289
12290 /* See what we need to do */
12291 switch (thread->iostate) {
12292 case IAX_IOSTATE_IDLE:
12293 continue;
12294 case IAX_IOSTATE_READY:
12295 thread->actions++;
12296 thread->iostate = IAX_IOSTATE_PROCESSING;
12299 break;
12301 thread->actions++;
12302 thread->iostate = IAX_IOSTATE_PROCESSING;
12303#ifdef SCHED_MULTITHREADED
12304 thread->schedfunc(thread->scheddata);
12305#endif
12306 break;
12307 default:
12308 break;
12309 }
12310
12311 /* The network thread added us to the active_thread list when we were given
12312 * frames to process, Now that we are done, we must remove ourselves from
12313 * the active list, and return to the idle list */
12317
12318 /* Make sure another frame didn't sneak in there after we thought we were done. */
12320
12321 time(&thread->checktime);
12322 thread->iostate = IAX_IOSTATE_IDLE;
12323#ifdef DEBUG_SCHED_MULTITHREAD
12324 thread->curfunc[0]='\0';
12325#endif
12326 }
12327
12328 /*!
12329 * \note For some reason, idle threads are exiting without being
12330 * removed from an idle list, which is causing memory
12331 * corruption. Forcibly remove it from the list, if it's there.
12332 */
12336
12340
12341 if (!thread->stop) {
12342 /* Nobody asked me to stop so nobody is waiting to join me. */
12343 pthread_detach(pthread_self());
12344 }
12345
12346 /* I am exiting here on my own volition, I need to clean up my own data structures
12347 * Assume that I am no longer in any of the lists (idle, active, or dynamic)
12348 */
12349 pthread_cleanup_pop(1);
12350 return NULL;
12351}
12352
12353static int iax2_do_register(struct iax2_registry *reg)
12354{
12355 struct iax_ie_data ied;
12356 if (iaxdebug)
12357 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
12358
12359 if (reg->dnsmgr &&
12360 ((reg->regstate == REG_STATE_TIMEOUT) || ast_sockaddr_isnull(&reg->addr))) {
12361 /* Maybe the IP has changed, force DNS refresh */
12363 }
12364
12365 /*
12366 * if IP has Changed, free allocated call to create a new one with new IP
12367 * call has the pointer to IP and must be updated to the new one
12368 */
12369 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
12370 int callno = reg->callno;
12371 ast_mutex_lock(&iaxsl[callno]);
12372 iax2_destroy(callno);
12373 ast_mutex_unlock(&iaxsl[callno]);
12374 reg->callno = 0;
12375 }
12376 if (ast_sockaddr_isnull(&reg->addr)) {
12377 if (iaxdebug)
12378 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
12379 /* Setup the next registration attempt */
12381 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
12382 return -1;
12383 }
12384 if (!ast_sockaddr_port(&reg->addr) && reg->port) {
12385 ast_sockaddr_set_port(&reg->addr, reg->port);
12386 }
12387
12388 if (!reg->callno) {
12389
12390 ast_debug(3, "Allocate call number\n");
12391
12392 reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
12393 if (reg->callno < 1) {
12394 ast_log(LOG_WARNING, "Unable to create call for registration\n");
12395 return -1;
12396 } else
12397 ast_debug(3, "Registration created on call %d\n", reg->callno);
12398 iaxs[reg->callno]->reg = reg;
12400 }
12401 /* Setup the next registration a little early */
12403 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
12404 /* Send the request */
12405 memset(&ied, 0, sizeof(ied));
12408 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */
12411 return 0;
12412}
12413
12414static int iax2_provision(struct ast_sockaddr *end, int sockfd, const char *dest, const char *template, int force)
12415{
12416 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
12417 is found for template */
12418 struct iax_ie_data provdata;
12419 struct iax_ie_data ied;
12420 unsigned int sig;
12421 struct ast_sockaddr addr;
12422 int callno;
12423 struct create_addr_info cai;
12424
12425 memset(&cai, 0, sizeof(cai));
12426
12427 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
12428
12429 if (iax_provision_build(&provdata, &sig, template, force)) {
12430 ast_debug(1, "No provisioning found for template '%s'\n", template);
12431 return 0;
12432 }
12433
12434 if (end) {
12435 ast_sockaddr_copy(&addr, end);
12436 cai.sockfd = sockfd;
12437 } else if (create_addr(dest, NULL, &addr, &cai))
12438 return -1;
12439
12440 /* Build the rest of the message */
12441 memset(&ied, 0, sizeof(ied));
12442 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
12443
12444 callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
12445 if (!callno)
12446 return -1;
12447
12448 if (iaxs[callno]) {
12449 /* Schedule autodestruct in case they don't ever give us anything back */
12450 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
12451 sched, 15000, auto_hangup, (void *)(long)callno);
12453 /* Got a call number now, so go ahead and send the provisioning information */
12454 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
12455 }
12456 ast_mutex_unlock(&iaxsl[callno]);
12457
12458 return 1;
12459}
12460
12461static char *papp = "IAX2Provision";
12462
12463/*! iax2provision
12464\ingroup applications
12465*/
12466static int iax2_prov_app(struct ast_channel *chan, const char *data)
12467{
12468 int res;
12469 char *sdata;
12470 char *opts;
12471 int force =0;
12472 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(chan));
12473 if (ast_strlen_zero(data))
12474 data = "default";
12475 sdata = ast_strdupa(data);
12476 opts = strchr(sdata, '|');
12477 if (opts)
12478 *opts='\0';
12479
12480 if (ast_channel_tech(chan) != &iax2_tech) {
12481 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
12482 return -1;
12483 }
12484 if (!callno || !iaxs[callno] || ast_sockaddr_isnull(&iaxs[callno]->addr)) {
12485 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
12486 return -1;
12487 }
12488 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
12489 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
12490 ast_sockaddr_stringify(&iaxs[callno]->addr),
12491 sdata, res);
12492 return res;
12493}
12494
12495static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
12496{
12497 int force = 0;
12498 int res;
12499
12500 switch (cmd) {
12501 case CLI_INIT:
12502 e->command = "iax2 provision";
12503 e->usage =
12504 "Usage: iax2 provision <host> <template> [forced]\n"
12505 " Provisions the given peer or IP address using a template\n"
12506 " matching either 'template' or '*' if the template is not\n"
12507 " found. If 'forced' is specified, even empty provisioning\n"
12508 " fields will be provisioned as empty fields.\n";
12509 return NULL;
12510 case CLI_GENERATE:
12511 if (a->pos == 3)
12512 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
12513 return NULL;
12514 }
12515
12516 if (a->argc < 4)
12517 return CLI_SHOWUSAGE;
12518 if (a->argc > 4) {
12519 if (!strcasecmp(a->argv[4], "forced"))
12520 force = 1;
12521 else
12522 return CLI_SHOWUSAGE;
12523 }
12524 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
12525 if (res < 0)
12526 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
12527 else if (res < 1)
12528 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
12529 else
12530 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
12531 return CLI_SUCCESS;
12532}
12533
12534static void __iax2_poke_noanswer(const void *data)
12535{
12536 struct iax2_peer *peer = (struct iax2_peer *)data;
12537 int callno;
12538
12539 if (peer->lastms > -1) {
12540 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
12541
12542 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
12544 blob = ast_json_pack("{s: s, s: i}",
12545 "peer_status", "Unreachable",
12546 "time", peer->lastms);
12548 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
12549 }
12550 if ((callno = peer->callno) > 0) {
12554 }
12555 peer->callno = 0;
12556 peer->lastms = -1;
12557 /* Try again quickly */
12559 if (peer->pokeexpire == -1)
12560 peer_unref(peer);
12561}
12562
12563static int iax2_poke_noanswer(const void *data)
12564{
12565 struct iax2_peer *peer = (struct iax2_peer *)data;
12566 peer->pokeexpire = -1;
12567#ifdef SCHED_MULTITHREADED
12569#endif
12571 peer_unref(peer);
12572 return 0;
12573}
12574
12575static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
12576{
12577 struct iax2_peer *peer = obj;
12578
12579 iax2_poke_peer(peer, 0);
12580
12581 return 0;
12582}
12583
12584static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
12585{
12586 int callno;
12587 int poke_timeout;
12588
12589 if (!peer->maxms || (ast_sockaddr_isnull(&peer->addr) && !peer->dnsmgr)) {
12590 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
12591 immediately after clearing things out */
12592 peer->lastms = 0;
12593 peer->historicms = 0;
12594 peer->pokeexpire = -1;
12595 peer->callno = 0;
12596 return 0;
12597 }
12598
12599 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
12600 if ((callno = peer->callno) > 0) {
12601 ast_log(LOG_NOTICE, "Still have a callno...\n");
12605 }
12606 if (heldcall)
12607 ast_mutex_unlock(&iaxsl[heldcall]);
12608 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
12609 if (heldcall)
12610 ast_mutex_lock(&iaxsl[heldcall]);
12611 if (callno < 1) {
12612 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12613 return -1;
12614 }
12615
12616 if (peer->pokeexpire > -1) {
12617 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
12618 peer->pokeexpire = -1;
12619 peer_unref(peer);
12620 }
12621 }
12622
12623 if (peer->lastms < 0){
12624 /* If the host is already unreachable then use time less than the unreachable
12625 * interval. 5/6 is arbitrary multiplier to get value less than
12626 * peer->pokefreqnotok. Value less than peer->pokefreqnotok is used to expire
12627 * current POKE before starting new POKE (which is scheduled after
12628 * peer->pokefreqnotok). */
12629 poke_timeout = peer->pokefreqnotok * 5 / 6;
12630 } else {
12631 /* If the host is reachable, use timeout large enough to allow for multiple
12632 * POKE retries. Limit this value to less than peer->pokefreqok. 5/6 is arbitrary
12633 * multiplier to get value less than peer->pokefreqok. Value less than
12634 * peer->pokefreqok is used to expire current POKE before starting new POKE
12635 * (which is scheduled after peer->pokefreqok). */
12636 poke_timeout = MIN(MAX_RETRY_TIME * 2 + peer->maxms, peer->pokefreqok * 5 / 6);
12637 }
12638
12639 /* Queue up a new task to handle no reply */
12640 peer->pokeexpire = iax2_sched_add(sched, poke_timeout, iax2_poke_noanswer, peer_ref(peer));
12641
12642 if (peer->pokeexpire == -1)
12643 peer_unref(peer);
12644
12645 /* And send the poke */
12647 if (iaxs[callno]) {
12648 struct iax_ie_data ied = {
12649 .buf = { 0 },
12650 .pos = 0,
12651 };
12652
12653 /* Speed up retransmission times for this qualify call */
12654 iaxs[callno]->pingtime = peer->maxms / 8;
12655 iaxs[callno]->peerpoke = peer;
12656
12657 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
12658 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12659 }
12660 ast_mutex_unlock(&iaxsl[callno]);
12661
12662 return 0;
12663}
12664
12665static void free_context(struct iax2_context *con)
12666{
12667 struct iax2_context *conl;
12668 while(con) {
12669 conl = con;
12670 con = con->next;
12671 ast_free(conl);
12672 }
12673}
12674
12675static 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)
12676{
12677 int callno;
12678 int res;
12679 struct ast_sockaddr addr;
12680 struct ast_channel *c;
12681 struct parsed_dial_string pds;
12682 struct create_addr_info cai;
12683 char *tmpstr;
12684 ast_callid callid;
12685
12686 memset(&pds, 0, sizeof(pds));
12687 tmpstr = ast_strdupa(data);
12688 parse_dial_string(tmpstr, &pds);
12689
12691
12692 if (ast_strlen_zero(pds.peer)) {
12693 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
12694 return NULL;
12695 }
12696 memset(&cai, 0, sizeof(cai));
12698
12700
12701 /* Populate our address from the given */
12702 if (create_addr(pds.peer, NULL, &addr, &cai)) {
12703 *cause = AST_CAUSE_UNREGISTERED;
12704 return NULL;
12705 }
12706
12707 if (pds.port) {
12708 int bindport;
12709 ast_parse_arg(pds.port, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535);
12710 ast_sockaddr_set_port(&addr, bindport);
12711 }
12712
12713 callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
12714 if (callno < 1) {
12715 ast_log(LOG_WARNING, "Unable to create call\n");
12716 *cause = AST_CAUSE_CONGESTION;
12717 return NULL;
12718 }
12719
12720 /* If this is a trunk, update it now */
12722 if (ast_test_flag64(&cai, IAX_TRUNK)) {
12723 int new_callno;
12724 if ((new_callno = make_trunk(callno, 1)) != -1)
12725 callno = new_callno;
12726 }
12727 iaxs[callno]->maxtime = cai.maxtime;
12728 if (callid) {
12729 iax_pvt_callid_set(callno, callid);
12730 }
12731
12732 if (cai.found) {
12733 ast_string_field_set(iaxs[callno], host, pds.peer);
12734 }
12735
12736 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, &cai.prefs, assignedids,
12737 requestor, cai.found);
12738
12739 ast_mutex_unlock(&iaxsl[callno]);
12740
12741 if (c) {
12742 struct ast_format_cap *joint;
12743 struct ast_format *format;
12744 if (callid) {
12746 ast_channel_callid_set(c, callid);
12748 }
12749
12751 if (!joint) {
12752 ast_hangup(c);
12753 return NULL;
12754 }
12755
12757
12758 /* If there is no joint format find one through translation */
12759 if (!ast_format_cap_count(joint)) {
12760 struct ast_format *best_fmt_cap = NULL;
12761 struct ast_format *best_fmt_native = NULL;
12762
12763 res = ast_translator_best_choice(cap, ast_channel_nativeformats(c), &best_fmt_cap, &best_fmt_native);
12764 if (res < 0) {
12765 struct ast_str *native_cap_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
12767
12768 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12770 ast_format_cap_get_names(cap, &cap_buf),
12772 ast_hangup(c);
12773 ao2_ref(joint, -1);
12774 return NULL;
12775 }
12776 ast_format_cap_append(joint, best_fmt_native, 0);
12777 ao2_ref(best_fmt_cap, -1);
12778 ao2_ref(best_fmt_native, -1);
12779 }
12784
12785 ao2_ref(joint, -1);
12786 ao2_ref(format, -1);
12787 }
12788
12789 return c;
12790}
12791
12792static void *network_thread(void *ignore)
12793{
12794 int res;
12795
12796 if (timer) {
12798 }
12799
12800 for (;;) {
12801 pthread_testcancel();
12802 /* Wake up once a second just in case SIGURG was sent while
12803 * we weren't in poll(), to make sure we don't hang when trying
12804 * to unload. */
12805 res = ast_io_wait(io, 1000);
12806 /* Timeout(=0), and EINTR is not a thread exit condition. We do
12807 * not want to exit the thread loop on these conditions. */
12808 if (res < 0 && errno != -EINTR) {
12809 ast_log(LOG_ERROR, "IAX2 network thread unexpected exit: %s\n", strerror(errno));
12810 break;
12811 }
12812 }
12813
12814 return NULL;
12815}
12816
12817static int start_network_thread(void)
12818{
12819 struct iax2_thread *thread;
12820 int threadcount = 0;
12821 int x;
12822 for (x = 0; x < iaxthreadcount; x++) {
12823 thread = ast_calloc(1, sizeof(*thread));
12824 if (thread) {
12826 thread->threadnum = ++threadcount;
12827 ast_mutex_init(&thread->lock);
12828 ast_cond_init(&thread->cond, NULL);
12829 ast_mutex_init(&thread->init_lock);
12830 ast_cond_init(&thread->init_cond, NULL);
12831
12832 ast_mutex_lock(&thread->init_lock);
12833
12835 ast_log(LOG_WARNING, "Failed to create new thread!\n");
12836 ast_mutex_destroy(&thread->lock);
12837 ast_cond_destroy(&thread->cond);
12838 ast_mutex_unlock(&thread->init_lock);
12839 ast_mutex_destroy(&thread->init_lock);
12840 ast_cond_destroy(&thread->init_cond);
12842 thread = NULL;
12843 continue;
12844 }
12845 /* Wait for the thread to be ready */
12846 ast_cond_wait(&thread->init_cond, &thread->init_lock);
12847
12848 /* Done with init_lock */
12849 ast_mutex_unlock(&thread->init_lock);
12850
12854 }
12855 }
12857 ast_log(LOG_ERROR, "Failed to create new thread!\n");
12858 return -1;
12859 }
12860 ast_verb(2, "%d helper threads started\n", threadcount);
12861 return 0;
12862}
12863
12864static struct iax2_context *build_context(const char *context)
12865{
12866 struct iax2_context *con;
12867
12868 if ((con = ast_calloc(1, sizeof(*con))))
12869 ast_copy_string(con->context, context, sizeof(con->context));
12870
12871 return con;
12872}
12873
12874static int get_auth_methods(const char *value)
12875{
12876 int methods = 0;
12877 if (strstr(value, "rsa"))
12879 if (strstr(value, "md5"))
12881 if (strstr(value, "plaintext"))
12883 return methods;
12884}
12885
12886
12887/*! \brief Check if address can be used as packet source.
12888 \retval 0 address available
12889 \retval 1 address unavailable
12890 \retval -1 error
12891*/
12892static int check_srcaddr(struct ast_sockaddr *addr)
12893{
12894 int sd;
12895
12896 sd = socket(addr->ss.ss_family, SOCK_DGRAM, 0);
12897 if (sd < 0) {
12898 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12899 return -1;
12900 }
12901
12902 if (ast_bind(sd, addr) < 0) {
12903 ast_debug(1, "Can't bind: %s\n", strerror(errno));
12904 close(sd);
12905 return 1;
12906 }
12907
12908 close(sd);
12909 return 0;
12910}
12911
12912/*! \brief Parse the "sourceaddress" value,
12913 lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
12914 not found. */
12915static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
12916{
12917 struct ast_sockaddr addr;
12918 int nonlocal = 1;
12919 int port = IAX_DEFAULT_PORTNO;
12920 int sockfd = defaultsockfd;
12921 char *tmp;
12922 char *host;
12923 char *portstr;
12924
12925 tmp = ast_strdupa(srcaddr);
12926 ast_sockaddr_split_hostport(tmp, &host, &portstr, 0);
12927
12928 if (portstr) {
12929 port = atoi(portstr);
12930 if (port < 1)
12931 port = IAX_DEFAULT_PORTNO;
12932 }
12933
12934 addr.ss.ss_family = AST_AF_UNSPEC;
12935 if (!ast_get_ip(&addr, host)) {
12936 struct ast_netsock *sock;
12937
12938 if (check_srcaddr(&addr) == 0) {
12939 /* ip address valid. */
12940 ast_sockaddr_set_port(&addr, port);
12941
12942 if (!(sock = ast_netsock_find(netsock, &addr)))
12943 sock = ast_netsock_find(outsock, &addr);
12944 if (sock) {
12945 sockfd = ast_netsock_sockfd(sock);
12946 nonlocal = 0;
12947 } else {
12948 /* INADDR_ANY matches anyway! */
12949 ast_sockaddr_parse(&addr, "0.0.0.0", 0);
12950 ast_sockaddr_set_port(&addr, port);
12951 if (ast_netsock_find(netsock, &addr)) {
12952 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12953 if (sock) {
12954 sockfd = ast_netsock_sockfd(sock);
12955 ast_netsock_unref(sock);
12956 nonlocal = 0;
12957 } else {
12958 nonlocal = 2;
12959 }
12960 }
12961 }
12962 }
12963 }
12964
12965 peer->sockfd = sockfd;
12966
12967 if (nonlocal == 1) {
12969 "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12970 srcaddr,
12971 peer->name);
12972 return -1;
12973 } else if (nonlocal == 2) {
12975 "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12976 srcaddr,
12977 peer->name);
12978 return -1;
12979 } else {
12980 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12981 return 0;
12982 }
12983}
12984
12985static void peer_destructor(void *obj)
12986{
12987 struct iax2_peer *peer = obj;
12988 int callno = peer->callno;
12989
12990 ast_free_acl_list(peer->acl);
12991
12992 if (callno > 0) {
12996 }
12997
12998 register_peer_exten(peer, 0);
12999
13000 if (peer->dnsmgr)
13002
13003 if (peer->mwi_event_sub) {
13005 }
13006
13008
13010}
13011
13012/*! \brief Create peer structure based on configuration */
13013static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
13014{
13015 struct iax2_peer *peer = NULL;
13016 struct ast_acl_list *oldacl = NULL;
13017 int maskfound = 0;
13018 int found = 0;
13019 int firstpass = 1;
13020 int subscribe_acl_change = 0;
13021
13022 if (!temponly) {
13023 peer = ao2_find(peers, name, OBJ_KEY);
13024 if (peer && !ast_test_flag64(peer, IAX_DELME))
13025 firstpass = 0;
13026 }
13027
13028 if (peer) {
13029 found++;
13030 if (firstpass) {
13031 oldacl = peer->acl;
13032 peer->acl = NULL;
13033 }
13034 unlink_peer(peer);
13035 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
13036 peer->expire = -1;
13037 peer->pokeexpire = -1;
13038 peer->sockfd = defaultsockfd;
13039 if (ast_string_field_init(peer, 32))
13040 peer = peer_unref(peer);
13041 if (!(peer->endpoint = ast_endpoint_create("IAX2", name))) {
13042 peer = peer_unref(peer);
13043 }
13044 }
13045
13046 if (peer) {
13047 if (firstpass) {
13051 peer->adsi = adsi;
13052 ast_string_field_set(peer, secret, "");
13053 if (!found) {
13055 ast_sockaddr_parse(&peer->addr, "0.0.0.0", 0);
13057 peer->expiry = min_reg_expire;
13058 }
13059 peer->prefs = prefs_global;
13061 peer->smoothing = 0;
13064 peer->maxcallno = 0;
13065 peercnt_modify((unsigned char) 0, 0, &peer->addr);
13067 ast_string_field_set(peer,context,"");
13068 ast_string_field_set(peer,peercontext,"");
13070 ast_string_field_set(peer, cid_name, "");
13071 ast_string_field_set(peer, cid_num, "");
13074 }
13075
13076 if (!v) {
13077 v = alt;
13078 alt = NULL;
13079 }
13080 while(v) {
13081 if (!strcasecmp(v->name, "secret")) {
13082 ast_string_field_set(peer, secret, v->value);
13083 } else if (!strcasecmp(v->name, "mailbox")) {
13084 ast_string_field_set(peer, mailbox, v->value);
13085 } else if (!strcasecmp(v->name, "mohinterpret")) {
13087 } else if (!strcasecmp(v->name, "mohsuggest")) {
13089 } else if (!strcasecmp(v->name, "dbsecret")) {
13090 ast_string_field_set(peer, dbsecret, v->value);
13091 } else if (!strcasecmp(v->name, "description")) {
13092 ast_string_field_set(peer, description, v->value);
13093 } else if (!strcasecmp(v->name, "trunk")) {
13095 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
13096 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
13098 }
13099 } else if (!strcasecmp(v->name, "auth")) {
13101 if (peer->authmethods & IAX_AUTH_PLAINTEXT) {
13102 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);
13103 }
13104 } else if (!strcasecmp(v->name, "encryption")) {
13106 if (!peer->encmethods) {
13108 }
13109 } else if (!strcasecmp(v->name, "forceencryption")) {
13110 if (ast_false(v->value)) {
13112 } else {
13114 if (peer->encmethods) {
13116 }
13117 }
13118 } else if (!strcasecmp(v->name, "transfer")) {
13119 if (!strcasecmp(v->value, "mediaonly")) {
13121 } else if (ast_true(v->value)) {
13123 } else
13125 } else if (!strcasecmp(v->name, "jitterbuffer")) {
13127 } else if (!strcasecmp(v->name, "host")) {
13128 if (!strcasecmp(v->value, "dynamic")) {
13129 /* They'll register with us */
13131 if (!found) {
13132 int peer_port = ast_sockaddr_port(&peer->addr);
13133 if (peer_port) {
13134 ast_sockaddr_set_port(&peer->defaddr, peer_port);
13135 }
13136 ast_sockaddr_setnull(&peer->addr);
13137 }
13138 } else {
13139 /* Non-dynamic. Make sure we become that way if we're not */
13140 AST_SCHED_DEL(sched, peer->expire);
13142 if (peer->dnsmgr) {
13143 // Make sure we refresh dnsmgr if we're using it
13145 } else {
13146 // Or just invalidate the address
13147 peer->addr.ss.ss_family = AST_AF_UNSPEC;
13148 }
13149 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) {
13150 return peer_unref(peer);
13151 }
13152 if (!ast_sockaddr_port(&peer->addr)) {
13154 }
13155 }
13156 } else if (!strcasecmp(v->name, "defaultip")) {
13157 struct ast_sockaddr peer_defaddr_tmp;
13158 peer_defaddr_tmp.ss.ss_family = AF_UNSPEC;
13159 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
13160 return peer_unref(peer);
13161 }
13162 ast_sockaddr_set_port(&peer_defaddr_tmp, ast_sockaddr_port(&peer->defaddr));
13163 ast_sockaddr_copy(&peer->defaddr, &peer_defaddr_tmp);
13164 } else if (!strcasecmp(v->name, "sourceaddress")) {
13165 peer_set_srcaddr(peer, v->value);
13166 } else if (!strcasecmp(v->name, "permit") ||
13167 !strcasecmp(v->name, "deny") ||
13168 !strcasecmp(v->name, "acl")) {
13169 ast_append_acl(v->name, v->value, &peer->acl, NULL, &subscribe_acl_change);
13170 } else if (!strcasecmp(v->name, "mask")) {
13171 maskfound++;
13172 ast_sockaddr_parse(&peer->mask, v->value, 0);
13173 } else if (!strcasecmp(v->name, "context")) {
13174 ast_string_field_set(peer, context, v->value);
13175 } else if (!strcasecmp(v->name, "regexten")) {
13176 ast_string_field_set(peer, regexten, v->value);
13177 } else if (!strcasecmp(v->name, "peercontext")) {
13178 ast_string_field_set(peer, peercontext, v->value);
13179 } else if (!strcasecmp(v->name, "port")) {
13180 int bindport;
13181 if (ast_parse_arg(v->value, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535)) {
13182 bindport = IAX_DEFAULT_PORTNO;
13183 }
13184 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
13185 ast_sockaddr_set_port(&peer->defaddr, bindport);
13186 } else {
13187 ast_sockaddr_set_port(&peer->addr, bindport);
13188 }
13189 } else if (!strcasecmp(v->name, "username")) {
13190 ast_string_field_set(peer, username, v->value);
13191 } else if (!strcasecmp(v->name, "allow")) {
13192 iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
13193 } else if (!strcasecmp(v->name, "disallow")) {
13194 iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
13195 } else if (!strcasecmp(v->name, "callerid")) {
13196 if (!ast_strlen_zero(v->value)) {
13197 char name2[80];
13198 char num2[80];
13199 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
13200 ast_string_field_set(peer, cid_name, name2);
13201 ast_string_field_set(peer, cid_num, num2);
13202 } else {
13203 ast_string_field_set(peer, cid_name, "");
13204 ast_string_field_set(peer, cid_num, "");
13205 }
13207 } else if (!strcasecmp(v->name, "fullname")) {
13208 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
13210 } else if (!strcasecmp(v->name, "cid_number")) {
13211 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
13213 } else if (!strcasecmp(v->name, "sendani")) {
13215 } else if (!strcasecmp(v->name, "inkeys")) {
13216 ast_string_field_set(peer, inkeys, v->value);
13217 } else if (!strcasecmp(v->name, "outkey")) {
13218 ast_string_field_set(peer, outkey, v->value);
13219 } else if (!strcasecmp(v->name, "qualify")) {
13220 if (!strcasecmp(v->value, "no")) {
13221 peer->maxms = 0;
13222 } else if (!strcasecmp(v->value, "yes")) {
13223 peer->maxms = DEFAULT_MAXMS;
13224 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
13225 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);
13226 peer->maxms = 0;
13227 }
13228 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
13229 peer->smoothing = ast_true(v->value);
13230 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
13231 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
13232 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);
13233 }
13234 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
13235 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
13236 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);
13237 }
13238 } else if (!strcasecmp(v->name, "timezone")) {
13240 } else if (!strcasecmp(v->name, "adsi")) {
13241 peer->adsi = ast_true(v->value);
13242 } else if (!strcasecmp(v->name, "connectedline")) {
13243 if (ast_true(v->value)) {
13245 } else if (!strcasecmp(v->value, "send")) {
13248 } else if (!strcasecmp(v->value, "receive")) {
13251 } else {
13253 }
13254 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13255 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
13256 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
13257 } else {
13258 peercnt_modify((unsigned char) 1, peer->maxcallno, &peer->addr);
13259 }
13260 } else if (!strcasecmp(v->name, "requirecalltoken")) {
13261 /* default is required unless in optional ip list */
13262 if (ast_false(v->value)) {
13264 } else if (!strcasecmp(v->value, "auto")) {
13266 } else if (ast_true(v->value)) {
13268 } else {
13269 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13270 }
13271 } /* else if (strcasecmp(v->name,"type")) */
13272 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13273 v = v->next;
13274 if (!v) {
13275 v = alt;
13276 alt = NULL;
13277 }
13278 }
13279 if (!peer->authmethods)
13280 peer->authmethods = IAX_AUTH_MD5;
13282 }
13283
13284 if (!maskfound && !ast_sockaddr_isnull(&peer->addr)) {
13285 if (ast_sockaddr_is_ipv4_mapped(&peer->addr)) {
13286 ast_sockaddr_parse(&peer->mask, "::ffff:ffff:ffff", 0);
13287 } else if (ast_sockaddr_is_ipv6(&peer->addr)) {
13288 ast_sockaddr_parse(&peer->mask, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0);
13289 } else {
13290 ast_sockaddr_parse(&peer->mask, "255.255.255.255", 0);
13291 }
13292 }
13293
13294 if (oldacl) {
13295 ast_free_acl_list(oldacl);
13296 }
13297
13298 if (!ast_strlen_zero(peer->mailbox) && !peer->mwi_event_sub) {
13299 /* The MWI subscriptions exist just so the core knows we care about those
13300 * mailboxes. However, we just grab the events out of the cache when it
13301 * is time to send MWI, since it is only sent with a REGACK. */
13303 }
13304
13305 if (subscribe_acl_change) {
13307 }
13308
13309 return peer;
13310}
13311
13312static void user_destructor(void *obj)
13313{
13314 struct iax2_user *user = obj;
13315
13316 ast_free_acl_list(user->acl);
13317 free_context(user->contexts);
13318 if(user->vars) {
13320 user->vars = NULL;
13321 }
13323}
13324
13325/*! \brief Create in-memory user structure from configuration */
13326static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
13327{
13328 struct iax2_user *user = NULL;
13329 struct iax2_context *con, *conl = NULL;
13330 struct ast_acl_list *oldacl = NULL;
13331 struct iax2_context *oldcon = NULL;
13332 int format;
13333 int firstpass=1;
13334 int oldcurauthreq = 0;
13335 int subscribe_acl_change = 0;
13336 char *varname = NULL, *varval = NULL;
13337 struct ast_variable *tmpvar = NULL;
13338
13339 if (!temponly) {
13342 firstpass = 0;
13343 }
13344
13345 if (user) {
13346 if (firstpass) {
13347 oldcurauthreq = user->curauthreq;
13348 oldacl = user->acl;
13349 oldcon = user->contexts;
13350 user->acl = NULL;
13351 user->contexts = NULL;
13352 }
13353 /* Already in the list, remove it and it will be added back (or FREE'd) */
13355 } else {
13356 user = ao2_alloc(sizeof(*user), user_destructor);
13357 }
13358
13359 if (user) {
13360 if (firstpass) {
13362 memset(user, 0, sizeof(struct iax2_user));
13363 if (ast_string_field_init(user, 32)) {
13364 user = user_unref(user);
13365 goto cleanup;
13366 }
13367 user->maxauthreq = maxauthreq;
13368 user->curauthreq = oldcurauthreq;
13369 user->prefs = prefs_global;
13370 user->capability = iax2_capability;
13371 user->encmethods = iax2_encryption;
13372 user->authmethods = iax2_authmethods;
13373 user->adsi = adsi;
13374 user->calltoken_required = CALLTOKEN_DEFAULT;
13379 ast_string_field_set(user, cid_name, "");
13380 ast_string_field_set(user, cid_num, "");
13384 }
13385 if (!v) {
13386 v = alt;
13387 alt = NULL;
13388 }
13389 while(v) {
13390 if (!strcasecmp(v->name, "context")) {
13391 con = build_context(v->value);
13392 if (con) {
13393 if (conl)
13394 conl->next = con;
13395 else
13396 user->contexts = con;
13397 conl = con;
13398 }
13399 } else if (!strcasecmp(v->name, "permit") ||
13400 !strcasecmp(v->name, "deny") ||
13401 !strcasecmp(v->name, "acl")) {
13402 ast_append_acl(v->name, v->value, &user->acl, NULL, &subscribe_acl_change);
13403 } else if (!strcasecmp(v->name, "setvar")) {
13404 varname = ast_strdupa(v->value);
13405 if ((varval = strchr(varname, '='))) {
13406 *varval = '\0';
13407 varval++;
13408 if ((tmpvar = ast_variable_new(varname, varval, ""))) {
13409 if (ast_variable_list_replace(&user->vars, tmpvar)) {
13410 tmpvar->next = user->vars;
13411 user->vars = tmpvar;
13412 }
13413 }
13414 }
13415 } else if (!strcasecmp(v->name, "allow")) {
13416 iax2_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
13417 } else if (!strcasecmp(v->name, "disallow")) {
13418 iax2_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
13419 } else if (!strcasecmp(v->name, "trunk")) {
13421 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
13422 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
13424 }
13425 } else if (!strcasecmp(v->name, "auth")) {
13426 user->authmethods = get_auth_methods(v->value);
13427 if (user->authmethods & IAX_AUTH_PLAINTEXT) {
13428 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);
13429 }
13430 } else if (!strcasecmp(v->name, "encryption")) {
13431 user->encmethods |= get_encrypt_methods(v->value);
13432 if (!user->encmethods) {
13434 }
13435 } else if (!strcasecmp(v->name, "forceencryption")) {
13436 if (ast_false(v->value)) {
13438 } else {
13439 user->encmethods |= get_encrypt_methods(v->value);
13440 if (user->encmethods) {
13442 }
13443 }
13444 } else if (!strcasecmp(v->name, "transfer")) {
13445 if (!strcasecmp(v->value, "mediaonly")) {
13447 } else if (ast_true(v->value)) {
13449 } else
13451 } else if (!strcasecmp(v->name, "codecpriority")) {
13452 if(!strcasecmp(v->value, "caller"))
13454 else if(!strcasecmp(v->value, "disabled"))
13456 else if(!strcasecmp(v->value, "reqonly")) {
13459 }
13460 } else if (!strcasecmp(v->name, "immediate")) {
13462 } else if (!strcasecmp(v->name, "jitterbuffer")) {
13464 } else if (!strcasecmp(v->name, "dbsecret")) {
13465 ast_string_field_set(user, dbsecret, v->value);
13466 } else if (!strcasecmp(v->name, "secret")) {
13467 if (!ast_strlen_zero(user->secret)) {
13468 char *old = ast_strdupa(user->secret);
13469
13470 ast_string_field_build(user, secret, "%s;%s", old, v->value);
13471 } else
13472 ast_string_field_set(user, secret, v->value);
13473 } else if (!strcasecmp(v->name, "callerid")) {
13474 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
13475 char name2[80];
13476 char num2[80];
13477 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
13478 ast_string_field_set(user, cid_name, name2);
13479 ast_string_field_set(user, cid_num, num2);
13481 } else {
13483 ast_string_field_set(user, cid_name, "");
13484 ast_string_field_set(user, cid_num, "");
13485 }
13486 } else if (!strcasecmp(v->name, "fullname")) {
13487 if (!ast_strlen_zero(v->value)) {
13488 ast_string_field_set(user, cid_name, v->value);
13490 } else {
13491 ast_string_field_set(user, cid_name, "");
13492 if (ast_strlen_zero(user->cid_num))
13494 }
13495 } else if (!strcasecmp(v->name, "cid_number")) {
13496 if (!ast_strlen_zero(v->value)) {
13497 ast_string_field_set(user, cid_num, v->value);
13499 } else {
13500 ast_string_field_set(user, cid_num, "");
13501 if (ast_strlen_zero(user->cid_name))
13503 }
13504 } else if (!strcasecmp(v->name, "accountcode")) {
13506 } else if (!strcasecmp(v->name, "mohinterpret")) {
13508 } else if (!strcasecmp(v->name, "mohsuggest")) {
13510 } else if (!strcasecmp(v->name, "parkinglot")) {
13511 ast_string_field_set(user, parkinglot, v->value);
13512 } else if (!strcasecmp(v->name, "language")) {
13514 } else if (!strcasecmp(v->name, "amaflags")) {
13515 format = ast_channel_string2amaflag(v->value);
13516 if (format < 0) {
13517 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13518 } else {
13519 user->amaflags = format;
13520 }
13521 } else if (!strcasecmp(v->name, "inkeys")) {
13522 ast_string_field_set(user, inkeys, v->value);
13523 } else if (!strcasecmp(v->name, "maxauthreq")) {
13524 user->maxauthreq = atoi(v->value);
13525 if (user->maxauthreq < 0)
13526 user->maxauthreq = 0;
13527 } else if (!strcasecmp(v->name, "adsi")) {
13528 user->adsi = ast_true(v->value);
13529 } else if (!strcasecmp(v->name, "connectedline")) {
13530 if (ast_true(v->value)) {
13532 } else if (!strcasecmp(v->value, "send")) {
13535 } else if (!strcasecmp(v->value, "receive")) {
13538 } else {
13540 }
13541 } else if (!strcasecmp(v->name, "requirecalltoken")) {
13542 /* default is required unless in optional ip list */
13543 if (ast_false(v->value)) {
13544 user->calltoken_required = CALLTOKEN_NO;
13545 } else if (!strcasecmp(v->value, "auto")) {
13546 user->calltoken_required = CALLTOKEN_AUTO;
13547 } else if (ast_true(v->value)) {
13548 user->calltoken_required = CALLTOKEN_YES;
13549 } else {
13550 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13551 }
13552 } /* else if (strcasecmp(v->name,"type")) */
13553 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13554 v = v->next;
13555 if (!v) {
13556 v = alt;
13557 alt = NULL;
13558 }
13559 }
13560 if (!user->authmethods) {
13561 if (!ast_strlen_zero(user->secret)) {
13562 user->authmethods = IAX_AUTH_MD5;
13563 if (!ast_strlen_zero(user->inkeys))
13564 user->authmethods |= IAX_AUTH_RSA;
13565 } else if (!ast_strlen_zero(user->inkeys)) {
13566 user->authmethods = IAX_AUTH_RSA;
13567 } else {
13568 user->authmethods = IAX_AUTH_MD5;
13569 }
13570 }
13572 }
13573cleanup:
13574 if (oldacl) {
13575 ast_free_acl_list(oldacl);
13576 }
13577 if (oldcon) {
13578 free_context(oldcon);
13579 }
13580
13581 if (subscribe_acl_change) {
13583 }
13584
13585 return user;
13586}
13587
13588static int peer_delme_cb(void *obj, void *arg, int flags)
13589{
13590 struct iax2_peer *peer = obj;
13591
13593
13594 return 0;
13595}
13596
13597static int user_delme_cb(void *obj, void *arg, int flags)
13598{
13599 struct iax2_user *user = obj;
13600
13602
13603 return 0;
13604}
13605
13606static void delete_users(void)
13607{
13608 struct iax2_registry *reg;
13609
13611
13613 while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
13614 if (sched) {
13615 AST_SCHED_DEL(sched, reg->expire);
13616 }
13617 if (reg->callno) {
13618 int callno = reg->callno;
13620 if (iaxs[callno]) {
13621 iaxs[callno]->reg = NULL;
13623 }
13625 }
13626 if (reg->dnsmgr)
13628 ast_free(reg);
13629 }
13631
13633}
13634
13635static void prune_users(void)
13636{
13637 struct iax2_user *user;
13638 struct ao2_iterator i;
13639
13640 i = ao2_iterator_init(users, 0);
13641 while ((user = ao2_iterator_next(&i))) {
13644 }
13646 }
13648}
13649
13650/* Prune peers who still are supposed to be deleted */
13651static void prune_peers(void)
13652{
13653 struct iax2_peer *peer;
13654 struct ao2_iterator i;
13655
13656 i = ao2_iterator_init(peers, 0);
13657 while ((peer = ao2_iterator_next(&i))) {
13659 unlink_peer(peer);
13660 }
13661 peer_unref(peer);
13662 }
13664}
13665
13666static void set_config_destroy(void)
13667{
13668 strcpy(accountcode, "");
13669 strcpy(language, "");
13670 strcpy(mohinterpret, "");
13671 strcpy(mohsuggest, "");
13673 amaflags = 0;
13674 delayreject = 0;
13677 delete_users();
13680}
13681
13682/*! \brief Load configuration */
13683static int set_config(const char *config_file, int reload, int forced)
13684{
13685 struct ast_config *cfg;
13686 iax2_format capability;
13687 struct ast_variable *v;
13688 char *cat;
13689 const char *utype;
13690 const char *tosval;
13691 int format;
13692 int portno = IAX_DEFAULT_PORTNO;
13693 int x;
13694 int mtuv;
13695 int subscribe_network_change = 1;
13696 struct iax2_user *user;
13697 struct iax2_peer *peer;
13698 struct ast_netsock *ns;
13699 struct ast_flags config_flags = { (reload && !forced) ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13700 struct ast_sockaddr bindaddr;
13701 struct iax2_codec_pref prefs_new;
13702
13703 cfg = ast_config_load(config_file, config_flags);
13704
13705 if (!cfg) {
13706 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13707 return -1;
13708 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13710 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13711 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13712 return 0;
13713 }
13714 if (!cfg) {
13715 /* should have been able to load the config here */
13716 ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file);
13717 return -1;
13718 }
13719 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13720 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13721 return 0;
13722 } else { /* iax.conf changed */
13724 }
13725
13726 if (reload) {
13728 }
13729
13730 ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0);
13731
13732 /* Setup new codec prefs */
13734
13735 /* Reset Global Flags */
13736 memset(&globalflags, 0, sizeof(globalflags));
13739
13740#ifdef SO_NO_CHECK
13741 nochecksums = 0;
13742#endif
13743 /* Reset default parking lot */
13744 default_parkinglot[0] = '\0';
13745
13751
13752 maxauthreq = 3;
13753
13754 srvlookup = 0;
13755 iax2_authmethods = 0;
13756
13757 v = ast_variable_browse(cfg, "general");
13758
13759 /* Seed initial tos value */
13760 tosval = ast_variable_retrieve(cfg, "general", "tos");
13761 if (tosval) {
13762 if (ast_str2tos(tosval, &qos.tos))
13763 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13764 }
13765 /* Seed initial cos value */
13766 tosval = ast_variable_retrieve(cfg, "general", "cos");
13767 if (tosval) {
13768 if (ast_str2cos(tosval, &qos.cos))
13769 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13770 }
13771 while(v) {
13772 if (!strcasecmp(v->name, "bindport")) {
13773 if (reload) {
13774 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13775 }
13776 else if (ast_parse_arg(v->value, PARSE_UINT32 | PARSE_IN_RANGE, &portno, 1024, 65535)) {
13777 portno = IAX_DEFAULT_PORTNO;
13778 }
13779 } else if (!strcasecmp(v->name, "pingtime")){
13780 ping_time = atoi(v->value);
13781 }
13782 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13783 if (reload) {
13784 if (atoi(v->value) != iaxthreadcount)
13785 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13786 } else {
13787 iaxthreadcount = atoi(v->value);
13788 if (iaxthreadcount < 1) {
13789 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13790 iaxthreadcount = 1;
13791 } else if (iaxthreadcount > 256) {
13792 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13793 iaxthreadcount = 256;
13794 }
13795 }
13796 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13797 if (reload) {
13799 iaxmaxthreadcount = atoi(v->value);
13801 } else {
13802 iaxmaxthreadcount = atoi(v->value);
13803 if (iaxmaxthreadcount < 0) {
13804 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13806 } else if (iaxmaxthreadcount > 256) {
13807 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13808 iaxmaxthreadcount = 256;
13809 }
13810 }
13811 } else if (!strcasecmp(v->name, "nochecksums")) {
13812#ifdef SO_NO_CHECK
13813 if (ast_true(v->value))
13814 nochecksums = 1;
13815 else
13816 nochecksums = 0;
13817#else
13818 if (ast_true(v->value))
13819 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13820#endif
13821 }
13822 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13823 maxjitterbuffer = atoi(v->value);
13824 else if (!strcasecmp(v->name, "resyncthreshold"))
13825 resyncthreshold = atoi(v->value);
13826 else if (!strcasecmp(v->name, "maxjitterinterps"))
13827 maxjitterinterps = atoi(v->value);
13828 else if (!strcasecmp(v->name, "jittertargetextra"))
13829 jittertargetextra = atoi(v->value);
13830 else if (!strcasecmp(v->name, "lagrqtime"))
13831 lagrq_time = atoi(v->value);
13832 else if (!strcasecmp(v->name, "maxregexpire"))
13833 max_reg_expire = atoi(v->value);
13834 else if (!strcasecmp(v->name, "minregexpire"))
13835 min_reg_expire = atoi(v->value);
13836 else if (!strcasecmp(v->name, "bindaddr")) {
13837 if (reload) {
13838 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13839 } else {
13840
13841 if (!ast_parse_arg(v->value, PARSE_ADDR, NULL)) {
13842
13844
13845 if (!ast_sockaddr_port(&bindaddr)) {
13847 }
13848
13849 if (!(ns = ast_netsock_bindaddr(netsock, io, &bindaddr, qos.tos, qos.cos, socket_read, NULL))) {
13850 ast_log(LOG_WARNING, "Unable to apply binding to '%s' at line %d\n", v->value, v->lineno);
13851 } else {
13852 ast_verb(2, "Binding IAX2 to address %s\n", ast_sockaddr_stringify(&bindaddr));
13853
13854 if (defaultsockfd < 0) {
13856 }
13858 }
13859
13860 } else {
13861 ast_log(LOG_WARNING, "Invalid address '%s' specified, at line %d\n", v->value, v->lineno);
13862 }
13863 }
13864 } else if (!strcasecmp(v->name, "auth")) {
13867 ast_log(LOG_WARNING, "Default auth method is set to deprecated 'plaintext' at line %d of iax.conf\n", v->lineno);
13868 }
13869 } else if (!strcasecmp(v->name, "authdebug")) {
13870 authdebug = ast_true(v->value);
13871 } else if (!strcasecmp(v->name, "encryption")) {
13873 if (!iax2_encryption) {
13875 }
13876 } else if (!strcasecmp(v->name, "forceencryption")) {
13877 if (ast_false(v->value)) {
13879 } else {
13881 if (iax2_encryption) {
13883 }
13884 }
13885 } else if (!strcasecmp(v->name, "transfer")) {
13886 if (!strcasecmp(v->value, "mediaonly")) {
13888 } else if (ast_true(v->value)) {
13890 } else
13892 } else if (!strcasecmp(v->name, "codecpriority")) {
13893 if(!strcasecmp(v->value, "caller"))
13895 else if(!strcasecmp(v->value, "disabled"))
13897 else if(!strcasecmp(v->value, "reqonly")) {
13900 }
13901 } else if (!strcasecmp(v->name, "jitterbuffer"))
13903 else if (!strcasecmp(v->name, "delayreject"))
13905 else if (!strcasecmp(v->name, "allowfwdownload"))
13907 else if (!strcasecmp(v->name, "rtcachefriends"))
13909 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13911 else if (!strcasecmp(v->name, "rtupdate"))
13913 else if (!strcasecmp(v->name, "rtsavesysname"))
13915 else if (!strcasecmp(v->name, "trunktimestamps"))
13917 else if (!strcasecmp(v->name, "rtautoclear")) {
13918 int i = atoi(v->value);
13919 if(i > 0)
13921 else
13922 i = 0;
13924 } else if (!strcasecmp(v->name, "trunkfreq")) {
13925 trunkfreq = atoi(v->value);
13926 if (trunkfreq < 10) {
13927 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n");
13928 trunkfreq = 10;
13929 } else if (trunkfreq > 1000) {
13930 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n");
13931 trunkfreq = 1000;
13932 }
13933 if (timer) {
13935 }
13936 } else if (!strcasecmp(v->name, "trunkmtu")) {
13937 mtuv = atoi(v->value);
13938 if (mtuv == 0 )
13940 else if (mtuv >= 172 && mtuv < 4000)
13941 global_max_trunk_mtu = mtuv;
13942 else
13943 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13944 mtuv, v->lineno);
13945 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13946 trunkmaxsize = atoi(v->value);
13947 if (trunkmaxsize == 0)
13949 } else if (!strcasecmp(v->name, "autokill")) {
13950 if (sscanf(v->value, "%30d", &x) == 1) {
13951 if (x >= 0)
13952 autokill = x;
13953 else
13954 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13955 } else if (ast_true(v->value)) {
13957 } else {
13958 autokill = 0;
13959 }
13960 } else if (!strcasecmp(v->name, "bandwidth")) {
13961 if (!strcasecmp(v->value, "low")) {
13962 capability = iax2_codec_pref_from_bitfield(&prefs_new,
13964 } else if (!strcasecmp(v->value, "medium")) {
13965 capability = iax2_codec_pref_from_bitfield(&prefs_new,
13967 } else if (!strcasecmp(v->value, "high")) {
13968 capability = iax2_codec_pref_from_bitfield(&prefs_new,
13970 } else {
13971 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13972 }
13973 } else if (!strcasecmp(v->name, "allow")) {
13974 iax2_parse_allow_disallow(&prefs_new, &capability, v->value, 1);
13975 } else if (!strcasecmp(v->name, "disallow")) {
13976 iax2_parse_allow_disallow(&prefs_new, &capability, v->value, 0);
13977 } else if (!strcasecmp(v->name, "register")) {
13978 iax2_register(v->value, v->lineno);
13979 } else if (!strcasecmp(v->name, "iaxcompat")) {
13980 iaxcompat = ast_true(v->value);
13981 } else if (!strcasecmp(v->name, "regcontext")) {
13983 /* Create context if it doesn't exist already */
13985 } else if (!strcasecmp(v->name, "tos")) {
13986 if (ast_str2tos(v->value, &qos.tos))
13987 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13988 } else if (!strcasecmp(v->name, "cos")) {
13989 if (ast_str2cos(v->value, &qos.cos))
13990 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13991 } else if (!strcasecmp(v->name, "parkinglot")) {
13993 } else if (!strcasecmp(v->name, "accountcode")) {
13995 } else if (!strcasecmp(v->name, "mohinterpret")) {
13997 } else if (!strcasecmp(v->name, "mohsuggest")) {
13999 } else if (!strcasecmp(v->name, "amaflags")) {
14000 format = ast_channel_string2amaflag(v->value);
14001 if (format < 0) {
14002 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
14003 } else {
14004 amaflags = format;
14005 }
14006 } else if (!strcasecmp(v->name, "language")) {
14007 ast_copy_string(language, v->value, sizeof(language));
14008 } else if (!strcasecmp(v->name, "maxauthreq")) {
14009 maxauthreq = atoi(v->value);
14010 if (maxauthreq < 0)
14011 maxauthreq = 0;
14012 } else if (!strcasecmp(v->name, "adsi")) {
14013 adsi = ast_true(v->value);
14014 } else if (!strcasecmp(v->name, "srvlookup")) {
14015 srvlookup = ast_true(v->value);
14016 } else if (!strcasecmp(v->name, "connectedline")) {
14017 if (ast_true(v->value)) {
14019 } else if (!strcasecmp(v->value, "send")) {
14022 } else if (!strcasecmp(v->value, "receive")) {
14025 } else {
14027 }
14028 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
14029 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
14030 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
14031 }
14032 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
14033 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
14034 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);
14035 }
14036 } else if (!strcasecmp(v->name, "calltokenoptional")) {
14037 if (add_calltoken_ignore(v->value)) {
14038 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
14039 return -1;
14040 }
14041 } else if (!strcasecmp(v->name, "calltokenexpiration")) {
14042 int temp = -1;
14043 sscanf(v->value, "%u", &temp);
14044 if( temp <= 0 ){
14045 ast_log(LOG_WARNING, "Invalid calltokenexpiration value %s. Should be integer greater than 0.\n", v->value);
14046 } else {
14047 max_calltoken_delay = temp;
14048 }
14049 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
14050 if (ast_true(v->value)) {
14051 subscribe_network_change = 1;
14052 } else if (ast_false(v->value)) {
14053 subscribe_network_change = 0;
14054 } else {
14055 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
14056 }
14057 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
14058 if (ast_true(v->value)) {
14060 } else if (ast_false(v->value)) {
14062 } else {
14063 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
14064 }
14065 }/*else if (strcasecmp(v->name,"type")) */
14066 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
14067 v = v->next;
14068 }
14069
14070 if (subscribe_network_change) {
14072 } else {
14074 }
14075
14076 if (defaultsockfd < 0) {
14077
14079
14080 if (!(ns = ast_netsock_bindaddr(netsock, io, &bindaddr, qos.tos, qos.cos, socket_read, NULL))) {
14081 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
14082 } else {
14083 ast_verb(2, "Binding IAX2 to default address %s\n", ast_sockaddr_stringify(&bindaddr));
14086 }
14087 }
14088 if (reload) {
14091 if (!outsock) {
14092 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14093 return -1;
14094 }
14096 }
14097
14099 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
14102 }
14103 prefs_global = prefs_new;
14104 iax2_capability = capability;
14105
14106 cat = ast_category_browse(cfg, NULL);
14107 while(cat) {
14108 if (strcasecmp(cat, "general")) {
14109 utype = ast_variable_retrieve(cfg, cat, "type");
14110 if (!strcasecmp(cat, "callnumberlimits")) {
14112 } else if (utype) {
14113 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
14114 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
14115 if (user) {
14117 user = user_unref(user);
14118 }
14119 }
14120 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
14121 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
14122 if (peer) {
14123 if (ast_test_flag64(peer, IAX_DYNAMIC))
14124 reg_source_db(peer);
14125 ao2_link(peers, peer);
14126 peer = peer_unref(peer);
14127 }
14128 } else if (strcasecmp(utype, "user")) {
14129 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
14130 }
14131 } else
14132 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
14133 }
14134 cat = ast_category_browse(cfg, cat);
14135 }
14136 ast_config_destroy(cfg);
14137 return 1;
14138}
14139
14140static void poke_all_peers(void)
14141{
14142 struct ao2_iterator i;
14143 struct iax2_peer *peer;
14144
14145 i = ao2_iterator_init(peers, 0);
14146 while ((peer = ao2_iterator_next(&i))) {
14147 iax2_poke_peer(peer, 0);
14148 peer_unref(peer);
14149 }
14151}
14152static int reload_config(int forced_reload)
14153{
14154 static const char config[] = "iax.conf";
14155 struct iax2_registry *reg;
14156
14157 if (set_config(config, 1, forced_reload) > 0) {
14158 prune_peers();
14159 prune_users();
14165 memset(&debugaddr, '\0', sizeof(debugaddr));
14166
14169 iax2_do_register(reg);
14171
14172 /* Qualify hosts, too */
14174 }
14175
14178 ast_unload_realtime("iaxpeers");
14179
14180 return 0;
14181}
14182
14183static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14184{
14185 switch (cmd) {
14186 case CLI_INIT:
14187 e->command = "iax2 reload";
14188 e->usage =
14189 "Usage: iax2 reload\n"
14190 " Reloads IAX configuration from iax.conf\n";
14191 return NULL;
14192 case CLI_GENERATE:
14193 return NULL;
14194 }
14195
14196 reload_config(0);
14197
14198 return CLI_SUCCESS;
14199}
14200
14201static int reload(void)
14202{
14203 return reload_config(0);
14204}
14205
14206static int cache_get_callno_locked(const char *data)
14207{
14208 struct ast_sockaddr addr;
14209 int x;
14210 int callno;
14211 struct iax_ie_data ied;
14212 struct create_addr_info cai;
14213 struct parsed_dial_string pds;
14214 char *tmpstr;
14215
14216 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14217 /* Look for an *exact match* call. Once a call is negotiated, it can only
14218 look up entries for a single context */
14219 if (!ast_mutex_trylock(&iaxsl[x])) {
14220 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
14221 return x;
14223 }
14224 }
14225
14226 /* No match found, we need to create a new one */
14227
14228 memset(&cai, 0, sizeof(cai));
14229 memset(&ied, 0, sizeof(ied));
14230 memset(&pds, 0, sizeof(pds));
14231
14232 tmpstr = ast_strdupa(data);
14233 parse_dial_string(tmpstr, &pds);
14234
14235 if (ast_strlen_zero(pds.peer)) {
14236 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
14237 return -1;
14238 }
14239
14240 /* Populate our address from the given */
14241 if (create_addr(pds.peer, NULL, &addr, &cai))
14242 return -1;
14243
14244 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
14245 pds.peer, pds.username, pds.password, pds.context);
14246
14247 callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
14248 if (callno < 1) {
14249 ast_log(LOG_WARNING, "Unable to create call\n");
14250 return -1;
14251 }
14252
14253 ast_string_field_set(iaxs[callno], dproot, data);
14255
14258 /* the string format is slightly different from a standard dial string,
14259 because the context appears in the 'exten' position
14260 */
14261 if (pds.exten)
14263 if (pds.username)
14267 /* Keep password handy */
14268 if (pds.password)
14269 ast_string_field_set(iaxs[callno], secret, pds.password);
14270 if (pds.key)
14271 ast_string_field_set(iaxs[callno], outkey, pds.key);
14272 /* Start the call going */
14273 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
14274 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
14275
14276 return callno;
14277}
14278
14279static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
14280{
14281 struct iax2_dpcache *dp = NULL;
14282 struct timeval now = ast_tvnow();
14283 int x, com[2], timeout, doabort, callno;
14284
14285 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
14286 if (ast_tvcmp(now, dp->expiry) > 0) {
14287 AST_LIST_REMOVE_CURRENT(cache_list);
14288 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
14289 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
14290 else
14291 ast_free(dp);
14292 continue;
14293 }
14294 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
14295 break;
14296 }
14298
14299 if (!dp) {
14300 /* No matching entry. Create a new one. */
14301 /* First, can we make a callno? */
14302 if ((callno = cache_get_callno_locked(data)) < 0) {
14303 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
14304 return NULL;
14305 }
14306 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
14307 ast_mutex_unlock(&iaxsl[callno]);
14308 return NULL;
14309 }
14310 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
14311 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
14312 dp->expiry = ast_tvnow();
14313 dp->orig = dp->expiry;
14314 /* Expires in 30 mins by default */
14315 dp->expiry.tv_sec += iaxdefaultdpcache;
14317 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
14318 dp->waiters[x] = -1;
14319 /* Insert into the lists */
14320 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
14321 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
14322 /* Send the request if we're already up */
14323 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
14324 iax2_dprequest(dp, callno);
14325 ast_mutex_unlock(&iaxsl[callno]);
14326 }
14327
14328 /* By here we must have a dp */
14329 if (dp->flags & CACHE_FLAG_PENDING) {
14330 int res;
14331 struct pollfd pfd;
14332 /* Okay, here it starts to get nasty. We need a pipe now to wait
14333 for a reply to come back so long as it's pending */
14334 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
14335 /* Find an empty slot */
14336 if (dp->waiters[x] < 0)
14337 break;
14338 }
14339 if (x >= ARRAY_LEN(dp->waiters)) {
14340 ast_log(LOG_WARNING, "No more waiter positions available\n");
14341 return NULL;
14342 }
14343 if (pipe(com)) {
14344 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
14345 return NULL;
14346 }
14347 dp->waiters[x] = com[1];
14348 /* Okay, now we wait */
14349 timeout = iaxdefaulttimeout * 1000;
14350 /* Temporarily unlock */
14352 doabort = 0;
14353
14354 /* chan is in autoservice here, so do NOT service it here! */
14355 pfd.fd = com[0];
14356 pfd.events = POLLIN;
14357 pfd.revents = 0;
14358 /* Wait for pipe activity... if the channel hangs up, we'll catch it on the way out. */
14359 res = ast_poll(&pfd, 1, timeout);
14360 if (res < 0) {
14361 ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
14362 return NULL;
14363 } else if (!pfd.revents) {
14364 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
14365 }
14366
14367 if (chan && ast_check_hangup(chan)) {
14368 doabort = 1;
14369 }
14370
14372 dp->waiters[x] = -1;
14373 close(com[1]);
14374 close(com[0]);
14375 if (doabort) {
14376 /* Don't interpret anything, just abort. */
14377 return NULL;
14378 }
14379 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
14380 /* Now to do non-independent analysis the results of our wait */
14381 if (dp->flags & CACHE_FLAG_PENDING) {
14382 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer
14383 pending. Don't let it take as long to timeout. */
14384 dp->flags &= ~CACHE_FLAG_PENDING;
14386 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded
14387 systems without leaving it unavailable once the server comes back online */
14388 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
14389 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
14390 if (dp->waiters[x] > -1) {
14391 if (write(dp->waiters[x], "asdf", 4) < 0) {
14392 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
14393 }
14394 }
14395 }
14396 }
14397 }
14398 /* Our caller will obtain the rest */
14399 }
14400 return dp;
14401}
14402
14403/*! \brief Part of the IAX2 switch interface */
14404static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
14405{
14406 int res = 0;
14407 struct iax2_dpcache *dp = NULL;
14408#if 0
14409 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14410#endif
14411 if ((priority != 1) && (priority != 2))
14412 return 0;
14413
14415 if ((dp = find_cache(chan, data, context, exten, priority))) {
14416 if (dp->flags & CACHE_FLAG_EXISTS)
14417 res = 1;
14418 } else {
14419 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14420 }
14422
14423 return res;
14424}
14425
14426/*! \brief part of the IAX2 dial plan switch interface */
14427static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
14428{
14429 int res = 0;
14430 struct iax2_dpcache *dp = NULL;
14431#if 0
14432 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14433#endif
14434 if ((priority != 1) && (priority != 2))
14435 return 0;
14436
14438 if ((dp = find_cache(chan, data, context, exten, priority))) {
14439 if (dp->flags & CACHE_FLAG_CANEXIST)
14440 res = 1;
14441 } else {
14442 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14443 }
14445
14446 return res;
14447}
14448
14449/*! \brief Part of the IAX2 Switch interface */
14450static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
14451{
14452 int res = 0;
14453 struct iax2_dpcache *dp = NULL;
14454#if 0
14455 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14456#endif
14457 if ((priority != 1) && (priority != 2))
14458 return 0;
14459
14461 if ((dp = find_cache(chan, data, context, exten, priority))) {
14462 if (dp->flags & CACHE_FLAG_MATCHMORE)
14463 res = 1;
14464 } else {
14465 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14466 }
14468
14469 return res;
14470}
14471
14472/*! \brief Execute IAX2 dialplan switch */
14473static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
14474{
14475 char odata[256];
14476 char req[sizeof(odata) + AST_MAX_CONTEXT + AST_MAX_EXTENSION + sizeof("IAX2//@")];
14477 char *ncontext;
14478 struct iax2_dpcache *dp = NULL;
14479 struct ast_app *dial = NULL;
14480#if 0
14481 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);
14482#endif
14483 if (priority == 2) {
14484 /* Indicate status, can be overridden in dialplan */
14485 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
14486 if (dialstatus) {
14487 dial = pbx_findapp(dialstatus);
14488 if (dial)
14489 pbx_exec(chan, dial, "");
14490 }
14491 return -1;
14492 } else if (priority != 1)
14493 return -1;
14494
14496 if ((dp = find_cache(chan, data, context, exten, priority))) {
14497 if (dp->flags & CACHE_FLAG_EXISTS) {
14498 ast_copy_string(odata, data, sizeof(odata));
14499 ncontext = strchr(odata, '/');
14500 if (ncontext) {
14501 *ncontext = '\0';
14502 ncontext++;
14503 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
14504 } else {
14505 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
14506 }
14507 ast_verb(3, "Executing Dial('%s')\n", req);
14508 } else {
14510 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
14511 return -1;
14512 }
14513 }
14515
14516 if ((dial = pbx_findapp("Dial")))
14517 return pbx_exec(chan, dial, req);
14518 else
14519 ast_log(LOG_WARNING, "No dial application registered\n");
14520
14521 return -1;
14522}
14523
14524static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
14525{
14526 struct iax2_peer *peer;
14527 char *peername, *colname;
14528
14529 peername = ast_strdupa(data);
14530
14531 /* if our channel, return the IP address of the endpoint of current channel */
14532 if (!strcmp(peername,"CURRENTCHANNEL")) {
14533 unsigned short callno;
14534 if (!chan || ast_channel_tech(chan) != &iax2_tech) {
14535 return -1;
14536 }
14539 return 0;
14540 }
14541
14542 if ((colname = strchr(peername, ',')))
14543 *colname++ = '\0';
14544 else
14545 colname = "ip";
14546
14547 if (!(peer = find_peer(peername, 1)))
14548 return -1;
14549
14550 if (!strcasecmp(colname, "ip")) {
14552 } else if (!strcasecmp(colname, "status")) {
14553 peer_status(peer, buf, len);
14554 } else if (!strcasecmp(colname, "mailbox")) {
14555 ast_copy_string(buf, peer->mailbox, len);
14556 } else if (!strcasecmp(colname, "context")) {
14557 ast_copy_string(buf, peer->context, len);
14558 } else if (!strcasecmp(colname, "expire")) {
14559 snprintf(buf, len, "%d", peer->expire);
14560 } else if (!strcasecmp(colname, "dynamic")) {
14561 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
14562 } else if (!strcasecmp(colname, "callerid_name")) {
14564 } else if (!strcasecmp(colname, "callerid_num")) {
14565 ast_copy_string(buf, peer->cid_num, len);
14566 } else if (!strcasecmp(colname, "codecs")) {
14567 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
14568
14569 iax2_getformatname_multiple(peer->capability, &codec_buf);
14570 ast_copy_string(buf, ast_str_buffer(codec_buf), len);
14571 } else if (!strncasecmp(colname, "codec[", 6)) {
14572 char *codecnum, *ptr;
14573 struct ast_format *tmpfmt;
14574
14575 /* skip over "codec" to the '[' */
14576 codecnum = colname + 5;
14577 *codecnum = '\0';
14578 codecnum++;
14579 if ((ptr = strchr(codecnum, ']'))) {
14580 *ptr = '\0';
14581 }
14582 if((iax2_codec_pref_index(&peer->prefs, atoi(codecnum), &tmpfmt))) {
14584 } else {
14585 buf[0] = '\0';
14586 }
14587 } else {
14588 buf[0] = '\0';
14589 }
14590
14591 peer_unref(peer);
14592
14593 return 0;
14594}
14595
14596static struct ast_custom_function iaxpeer_function = {
14597 .name = "IAXPEER",
14598 .read = function_iaxpeer,
14599};
14600
14601static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
14602{
14603 struct chan_iax2_pvt *pvt;
14604 unsigned int callno;
14605 int res = 0;
14606
14607 if (!chan || ast_channel_tech(chan) != &iax2_tech) {
14608 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
14609 return -1;
14610 }
14611
14614 if (!(pvt = iaxs[callno])) {
14616 return -1;
14617 }
14618
14619 if (!strcasecmp(args, "osptoken")) {
14620 ast_copy_string(buf, pvt->osptoken, buflen);
14621 } else if (!strcasecmp(args, "peerip")) {
14623 } else if (!strcasecmp(args, "peername")) {
14624 ast_copy_string(buf, pvt->username, buflen);
14625 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
14626 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
14627 } else {
14628 res = -1;
14629 }
14630
14632
14633 return res;
14634}
14635
14636/*! \brief Part of the device state notification system ---*/
14637static int iax2_devicestate(const char *data)
14638{
14639 struct parsed_dial_string pds;
14640 char *tmp = ast_strdupa(data);
14641 struct iax2_peer *p;
14642 int res = AST_DEVICE_INVALID;
14643
14644 memset(&pds, 0, sizeof(pds));
14645 parse_dial_string(tmp, &pds);
14646
14647 if (ast_strlen_zero(pds.peer)) {
14648 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
14649 return res;
14650 }
14651
14652 ast_debug(3, "Checking device state for device %s\n", pds.peer);
14653
14654 /* SLD: FIXME: second call to find_peer during registration */
14655 if (!(p = find_peer(pds.peer, 1)))
14656 return res;
14657
14659
14660 ast_debug(3, "Found peer. What's device state of %s? addr=%s, defaddr=%s maxms=%d, lastms=%d\n",
14662
14663 if (((!ast_sockaddr_isnull(&p->addr)) || (!ast_sockaddr_isnull(&p->defaddr))) &&
14664 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
14665 /* Peer is registered, or have default IP address
14666 and a valid registration */
14667 if (p->historicms == 0 || p->historicms <= p->maxms)
14668 /* let the core figure out whether it is in use or not */
14669 res = AST_DEVICE_UNKNOWN;
14670 }
14671
14672 peer_unref(p);
14673
14674 return res;
14675}
14676
14677static struct ast_switch iax2_switch =
14678{
14679 .name = "IAX2",
14680 .description = "IAX Remote Dialplan Switch",
14681 .exists = iax2_exists,
14682 .canmatch = iax2_canmatch,
14683 .exec = iax2_exec,
14684 .matchmore = iax2_matchmore,
14685};
14686
14687static struct ast_cli_entry cli_iax2[] = {
14688 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
14689 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
14690 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
14691 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
14692 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
14693 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
14694 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
14695 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
14696 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
14697 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
14698 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
14699 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
14700 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
14701 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
14702 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
14703 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
14704 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
14705 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
14706 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
14707 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
14708#ifdef IAXTESTS
14709 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
14710 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
14711 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
14712#endif /* IAXTESTS */
14713};
14714
14715static void cleanup_thread_list(void *head)
14716{
14717 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14718 struct iax2_thread_list *list_head = head;
14719 struct iax2_thread *thread;
14720
14721 AST_LIST_LOCK(list_head);
14722 while ((thread = AST_LIST_REMOVE_HEAD(list_head, list))) {
14723 pthread_t thread_id = thread->threadid;
14724
14725 thread->stop = 1;
14726 signal_condition(&thread->lock, &thread->cond);
14727
14728 AST_LIST_UNLOCK(list_head);
14729 pthread_join(thread_id, NULL);
14730 AST_LIST_LOCK(list_head);
14731 }
14732 AST_LIST_UNLOCK(list_head);
14733}
14734
14735static int __unload_module(void)
14736{
14737 int x;
14738
14741
14742 ast_manager_unregister("IAXpeers");
14743 ast_manager_unregister("IAXpeerlist");
14744 ast_manager_unregister("IAXnetstats");
14745 ast_manager_unregister("IAXregistry");
14750
14752 pthread_cancel(netthreadid);
14753 pthread_kill(netthreadid, SIGURG);
14754 pthread_join(netthreadid, NULL);
14755 }
14756
14757 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14758 if (iaxs[x]) {
14759 iax2_destroy(x);
14760 }
14761 }
14762
14763 /* Call for all threads to halt */
14767
14770 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14771 if (iaxs[x]) {
14772 iax2_destroy(x);
14773 }
14774 }
14775 ast_manager_unregister( "IAXpeers" );
14776 ast_manager_unregister( "IAXpeerlist" );
14777 ast_manager_unregister( "IAXnetstats" );
14778 ast_manager_unregister( "IAXregistry" );
14783 delete_users();
14786
14787 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14789 }
14790
14791 ao2_ref(peers, -1);
14792 ao2_ref(users, -1);
14797 if (timer) {
14799 timer = NULL;
14800 }
14802
14805 sched = NULL;
14806 ao2_ref(peercnts, -1);
14807
14809 ast_unload_realtime("iaxpeers");
14810
14813 return 0;
14814}
14815
14816static int unload_module(void)
14817{
14820 return __unload_module();
14821}
14822
14823static int peer_set_sock_cb(void *obj, void *arg, int flags)
14824{
14825 struct iax2_peer *peer = obj;
14826
14827 if (peer->sockfd < 0)
14828 peer->sockfd = defaultsockfd;
14829
14830 return 0;
14831}
14832
14833static int pvt_hash_cb(const void *obj, const int flags)
14834{
14835 const struct chan_iax2_pvt *pvt = obj;
14836
14837 return pvt->peercallno;
14838}
14839
14840static int pvt_cmp_cb(void *obj, void *arg, int flags)
14841{
14842 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14843
14844 /* The frames_received field is used to hold whether we're matching
14845 * against a full frame or not ... */
14846
14847 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14848 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14849}
14850
14851static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
14852{
14853 const struct chan_iax2_pvt *pvt = obj;
14854
14855 return pvt->transfercallno;
14856}
14857
14858static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
14859{
14860 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14861
14862 /* The frames_received field is used to hold whether we're matching
14863 * against a full frame or not ... */
14864
14865 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14866 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14867}
14868
14869static int load_objects(void)
14870{
14873
14876 if (!peers) {
14877 goto container_fail;
14878 }
14879
14882 if (!users) {
14883 goto container_fail;
14884 }
14885
14888 if (!iax_peercallno_pvts) {
14889 goto container_fail;
14890 }
14891
14895 goto container_fail;
14896 }
14897
14900 if (!peercnts) {
14901 goto container_fail;
14902 }
14903
14906 if (!callno_limits) {
14907 goto container_fail;
14908 }
14909
14912 if (!calltoken_ignores) {
14913 goto container_fail;
14914 }
14915
14916 if (create_callno_pools()) {
14917 goto container_fail;
14918 }
14919
14921 if (!transmit_processor) {
14922 goto container_fail;
14923 }
14924
14925 return 0;
14926
14927container_fail:
14928 if (peers) {
14929 ao2_ref(peers, -1);
14930 }
14931 if (users) {
14932 ao2_ref(users, -1);
14933 }
14934 if (iax_peercallno_pvts) {
14936 }
14939 }
14940 if (peercnts) {
14941 ao2_ref(peercnts, -1);
14942 }
14943 if (callno_limits) {
14945 }
14946 if (calltoken_ignores) {
14948 }
14949 return -1;
14950}
14951
14952/*!
14953 * \brief Load the module
14954 *
14955 * Module loading including tests for configuration or dependencies.
14956 * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
14957 * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
14958 * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
14959 * configuration file or other non-critical problem return
14960 * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
14961 */
14962static int load_module(void)
14963{
14964 static const char config[] = "iax.conf";
14965 int x = 0;
14966 struct iax2_registry *reg = NULL;
14967
14970 }
14972
14973 if (load_objects()) {
14977 }
14978
14979 memset(iaxs, 0, sizeof(iaxs));
14980
14981 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14982 ast_mutex_init(&iaxsl[x]);
14983 }
14984
14985 if (!(sched = ast_sched_context_create())) {
14986 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14990 }
14991
14996 sched = NULL;
14998 }
14999
15000 if (!(io = io_context_create())) {
15001 ast_log(LOG_ERROR, "Failed to create I/O context\n");
15005 sched = NULL;
15007 }
15008
15009 if (!(netsock = ast_netsock_list_alloc())) {
15010 ast_log(LOG_ERROR, "Failed to create netsock list\n");
15015 sched = NULL;
15017 }
15019
15021 if (!outsock) {
15022 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
15027 sched = NULL;
15029 }
15031
15033
15037
15038 if ((timer = ast_timer_open())) {
15040 }
15041
15042 if (set_config(config, 0, 0) == -1) {
15043 if (timer) {
15045 timer = NULL;
15046 }
15049 }
15050
15052
15054
15057
15062
15064 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
15067 }
15068
15070 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
15071 }
15072
15073 if (start_network_thread()) {
15074 ast_log(LOG_ERROR, "Unable to start network thread\n");
15077 } else {
15078 ast_verb(2, "IAX Ready and Listening\n");
15079 }
15080
15083 iax2_do_register(reg);
15085
15088
15089
15092
15093 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
15094
15096
15098}
15099
15100AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchange (Ver 2)",
15101 .support_level = AST_MODULE_SUPPORT_CORE,
15102 .load = load_module,
15103 .unload = unload_module,
15104 .reload = reload,
15105 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
15106 .requires = "dnsmgr",
15107 .optional_modules = "res_crypto",
15108);
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
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition acl.c:222
int ast_str2tos(const char *value, unsigned int *tos)
Convert a string to the appropriate TOS value.
Definition acl.c:983
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
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
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
@ AST_SENSE_ALLOW
Definition acl.h:38
@ AST_SENSE_DENY
Definition acl.h:37
int ast_get_ip(struct ast_sockaddr *addr, const char *hostname)
Get the IP address given a hostname.
Definition acl.c:1016
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
int ast_str2cos(const char *value, unsigned int *cos)
Convert a string to the appropriate COS value.
Definition acl.c:969
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition acl.c:233
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
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
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408
static const struct adsi_event events[]
char digit
jack_status_t status
Definition app_jack.c:149
pthread_t thread
Definition app_sla.c:335
ast_cond_t cond
Definition app_sla.c:336
ast_mutex_t lock
Definition app_sla.c:337
static char zonetag[80]
static int copy(char *infile, char *outfile)
Utility function to copy a file.
#define var
Definition ast_expr2f.c:605
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition db.c:335
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
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Definition db.c:472
char * strsep(char **str, const char *delims)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition astmm.h:288
#define ast_free(a)
Definition astmm.h:180
#define ast_realloc(p, len)
A wrapper for realloc()
Definition astmm.h:226
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
void ast_free_ptr(void *ptr)
free() wrapper
Definition astmm.c:1739
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
#define ast_malloc(len)
A wrapper for malloc()
Definition astmm.h:191
#define ast_log
Definition astobj2.c:42
#define ao2_iterator_next(iter)
Definition astobj2.h:1911
#define ao2_link(container, obj)
Add an object to a container.
Definition astobj2.h:1532
@ CMP_MATCH
Definition astobj2.h:1027
@ CMP_STOP
Definition astobj2.h:1028
#define OBJ_KEY
Definition astobj2.h:1151
#define OBJ_POINTER
Definition astobj2.h:1150
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition astobj2.h:363
#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
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition astobj2.h:1578
#define ao2_find(container, arg, flags)
Definition astobj2.h:1736
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_unlock(a)
Definition astobj2.h:729
#define ao2_lock(a)
Definition astobj2.h:717
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_NODATA
Definition astobj2.h:1044
@ OBJ_MULTIPLE
Definition astobj2.h:1049
@ OBJ_UNLINK
Definition astobj2.h:1039
#define ao2_alloc(data_size, destructor_fn)
Definition astobj2.h:409
#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
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:4504
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition bridge.h:1104
#define AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
Definition callerid.h:440
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition callerid.c:1273
#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
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition callerid.c:1292
#define AST_CAUSE_CONGESTION
Definition causes.h:153
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition causes.h:130
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition causes.h:115
#define AST_CAUSE_NO_USER_RESPONSE
Definition causes.h:108
#define AST_CAUSE_FACILITY_NOT_SUBSCRIBED
Definition causes.h:126
#define AST_CAUSE_CALL_REJECTED
Definition causes.h:111
#define AST_CAUSE_FACILITY_REJECTED
Definition causes.h:117
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition causes.h:100
#define AST_CAUSE_UNREGISTERED
Definition causes.h:154
#define AST_CAUSE_BUSY
Definition causes.h:149
static int priority
static const char config_file[]
Definition cdr_odbc.c:54
static int connected
Definition cdr_pgsql.c:73
static char * tz
Definition cdr_pgsql.c:71
#define MAX_USER_BUCKETS
Definition chan_iax2.c:1027
static int timing_read(int *id, int fd, short events, void *cbdata)
Definition chan_iax2.c:9642
#define IAX_TRUNKTIMESTAMPS
Definition chan_iax2.c:543
static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
Definition chan_iax2.c:5851
static void set_peercnt_limit(struct peercnt *peercnt)
Definition chan_iax2.c:2626
static int check_access(int callno, struct ast_sockaddr *addr, struct iax_ies *ies)
Definition chan_iax2.c:7927
static int iaxthreadcount
Definition chan_iax2.c:744
static int send_ping(const void *data)
Definition chan_iax2.c:1813
static int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
Definition chan_iax2.c:9634
iax2_thread_iostate
Definition chan_iax2.c:1115
@ 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
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 struct ao2_container * peercnts
Definition chan_iax2.c:1031
static struct iax2_context * build_context(const char *context)
static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
Definition chan_iax2.c:9810
#define IAX_ALREADYGONE
Definition chan_iax2.c:531
#define IAX_PROVISION
Definition chan_iax2.c:532
static int update_registry(struct ast_sockaddr *addr, int callno, char *devtype, int fd, unsigned short refresh)
Definition chan_iax2.c:9184
static int iax2_write(struct ast_channel *c, struct ast_frame *f)
Definition chan_iax2.c:7823
#define AUTH_METHOD_NAMES_BUFSIZE
Definition chan_iax2.c:431
static struct iax2_peer * realtime_peer(const char *peername, struct ast_sockaddr *addr)
Definition chan_iax2.c:4457
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 struct iax2_user * user_unref(struct iax2_user *user)
Definition chan_iax2.c:2112
static int apply_context(struct iax2_context *con, const char *context)
Definition chan_iax2.c:7916
static struct ast_channel_tech iax2_tech
Definition chan_iax2.c:1366
static void __auto_hangup(const void *nothing)
Definition chan_iax2.c:9513
static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
Definition chan_iax2.c:2161
static char * complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags)
Definition chan_iax2.c:3964
static int autokill
Definition chan_iax2.c:370
static int randomcalltokendata
Definition chan_iax2.c:1009
static int iaxdynamicthreadcount
Definition chan_iax2.c:746
static void iax2_lock_owner(int callno)
Definition chan_iax2.c:1406
static int delayreject
Definition chan_iax2.c:502
static int iax2_queue_hold(int callno, const char *musicclass)
Queue a hold frame on the ast_channel owner.
Definition chan_iax2.c:3349
#define MAX_TIMESTAMP_SKEW
Definition chan_iax2.c:736
static void acl_change_stasis_subscribe(void)
Definition chan_iax2.c:1542
static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
Definition chan_iax2.c:2472
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 jb_error_output(const char *fmt,...)
Definition chan_iax2.c:1281
static int peer_hash_cb(const void *obj, const int flags)
Definition chan_iax2.c:2035
static void iax2_publish_registry(const char *username, const char *domain, const char *status, const char *cause)
Definition chan_iax2.c:8892
static int replace_callno(const void *obj)
Definition chan_iax2.c:3055
#define CALLNO_ENTRY_IS_VALIDATED(a)
Definition chan_iax2.c:979
static int auto_congest(const void *data)
Definition chan_iax2.c:4835
static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
Definition chan_iax2.c:6145
static void __iax2_poke_noanswer(const void *data)
static int iax2_predestroy(int callno)
Definition chan_iax2.c:3509
static int update_packet(struct iax_frame *f)
Definition chan_iax2.c:3594
static int iaxcompat
Definition chan_iax2.c:371
static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
Definition chan_iax2.c:6400
static char * handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:3713
static int peercnt_hash_cb(const void *obj, const int flags)
Definition chan_iax2.c:2532
static int check_provisioning(struct ast_sockaddr *addr, int sockfd, char *si, unsigned int ver)
Definition chan_iax2.c:9781
static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
Definition chan_iax2.c:5484
static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int)
Definition chan_iax2.c:7911
static void unwrap_timestamp(struct iax_frame *fr)
Definition chan_iax2.c:4146
static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
Definition chan_iax2.c:5465
static int iax2_hangup(struct ast_channel *c)
Definition chan_iax2.c:5417
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 __schedule_action(void(*func)(const void *data), const void *data, const char *funcname)
Definition chan_iax2.c:1725
static int addr_range_match_address_cb(void *obj, void *arg, int flags)
Definition chan_iax2.c:2548
static int maxjitterbuffer
Definition chan_iax2.c:359
static int auth_fail(int callno, int failcode)
Definition chan_iax2.c:9498
static char * handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:3774
#define PEERS_FORMAT2
Definition chan_iax2.c:6982
#define PTR_TO_CALLNO(a)
Definition chan_iax2.c:316
static int iax2_queue_hangup(int callno)
Queue a hangup frame on the ast_channel owner.
Definition chan_iax2.c:3395
static int peercnt_remove_cb(const void *obj)
Definition chan_iax2.c:2781
static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
Definition chan_iax2.c:6174
static unsigned char compress_subclass(iax2_format subclass)
Definition chan_iax2.c:1886
static int handle_error(void)
Definition chan_iax2.c:3428
#define IAX_TRUNK
Definition chan_iax2.c:525
static const char * auth_method_labels[]
Name of effective auth method.
Definition chan_iax2.c:423
static int peer_cmp_cb(void *obj, void *arg, int flags)
Definition chan_iax2.c:2046
static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
Definition chan_iax2.c:4908
static int get_auth_methods(const char *value)
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 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 struct iax2_trunk_peer * find_tpeer(struct ast_sockaddr *addr, int fd)
Definition chan_iax2.c:6364
static void iax_error_output(const char *data)
Definition chan_iax2.c:1276
static void vnak_retransmit(int callno, int last)
Definition chan_iax2.c:9560
static int user_delme_cb(void *obj, void *arg, int flags)
static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
Definition chan_iax2.c:7906
static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen)
static struct ast_custom_function iaxvar_function
#define IAX_SHRINKCALLERID
Definition chan_iax2.c:552
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
static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Execute IAX2 dialplan switch.
static int __unload_module(void)
static char * handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:7724
static struct stasis_subscription * acl_change_sub
Definition chan_iax2.c:352
static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
static iax2_format iax2_capability
Definition chan_iax2.c:483
#define DEFAULT_MAX_THREAD_COUNT
Definition chan_iax2.c:320
static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)]
chan_iax2_pvt structure locks
Definition chan_iax2.c:1236
static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
Definition chan_iax2.c:4419
static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL
Definition chan_iax2.c:1041
static struct ast_sched_context * sched
Definition chan_iax2.c:481
static void * dp_lookup_thread(void *data)
Definition chan_iax2.c:9752
static uint16_t DEFAULT_MAXCALLNO_LIMIT
Definition chan_iax2.c:1039
static void peercnt_modify(unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
Definition chan_iax2.c:2676
static int transmit_trunk(struct iax_frame *f, struct ast_sockaddr *addr, int sockfd)
Definition chan_iax2.c:3462
static int registry_rerequest(struct iax_ies *ies, int callno, struct ast_sockaddr *addr)
Definition chan_iax2.c:9410
static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
Definition chan_iax2.c:7871
static void encmethods_to_str(int e, struct ast_str **buf)
Definition chan_iax2.c:1823
static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
Definition chan_iax2.c:9794
static struct ast_custom_function iaxpeer_function
static int load_objects(void)
static int complete_transfer(int callno, struct iax_ies *ies)
Definition chan_iax2.c:8831
static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
Definition chan_iax2.c:4441
static struct ast_format * codec_choose_from_prefs(struct iax2_codec_pref *pref, struct ast_format_cap *cap)
Definition chan_iax2.c:1920
static int prune_addr_range_cb(void *obj, void *arg, int flags)
Definition chan_iax2.c:2665
static void iax_debug_output(const char *data)
Definition chan_iax2.c:1270
#define IAX_CALLENCRYPTED(pvt)
Definition chan_iax2.c:464
static char * handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static uint16_t global_maxcallno_nonval
Definition chan_iax2.c:1046
static int maxjitterinterps
Definition chan_iax2.c:361
static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
Definition chan_iax2.c:4316
#define IAX_ENCRYPTED
Definition chan_iax2.c:534
static void jb_debug_output(const char *fmt,...)
Definition chan_iax2.c:1305
#define IAX_CODEC_NOCAP
Definition chan_iax2.c:538
static int ping_time
Definition chan_iax2.c:357
static void iax_pvt_callid_new(int callno)
Definition chan_iax2.c:1210
static char * regstate2str(int regstate)
Definition chan_iax2.c:7446
static int last_authmethod
Definition chan_iax2.c:372
#define IAX_NOTRANSFER
Definition chan_iax2.c:526
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 IAX_IMMEDIATE
Definition chan_iax2.c:548
static int iax2_call(struct ast_channel *c, const char *dest, int timeout)
Definition chan_iax2.c:5192
static char * handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Set trunk MTU from CLI.
Definition chan_iax2.c:4033
static int trunk_untimed
Definition chan_iax2.c:342
static void pvt_destructor(void *obj)
Definition chan_iax2.c:2269
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)
static int iax2_queue_unhold(int callno)
Queue an unhold frame on the ast_channel owner.
Definition chan_iax2.c:3372
#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 iax2_getpeername(struct ast_sockaddr addr, char *host, int len)
Definition chan_iax2.c:2118
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.
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
static void * iax2_process_thread(void *data)
static int iax2_digit_begin(struct ast_channel *c, char digit)
Definition chan_iax2.c:4414
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.
static char regcontext[AST_MAX_CONTEXT]
Definition chan_iax2.c:349
static int socket_process_helper(struct iax2_thread *thread)
#define IAX_CAPABILITY_FULLBANDWIDTH
Definition chan_iax2.c:397
static struct ao2_container * peers
Definition chan_iax2.c:1025
static int set_config(const char *config_file, int reload, int forced)
Load configuration.
static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
Definition chan_iax2.c:8750
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
static void __auto_congest(const void *nothing)
Definition chan_iax2.c:4822
#define IAX_HASCALLERID
Definition chan_iax2.c:522
static void free_signaling_queue_entry(struct signaling_queue_entry *s)
Definition chan_iax2.c:2221
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
#define MARK_IAX_SUBCLASS_TX
Definition chan_iax2.c:742
static int iax2_key_rotate(const void *vpvt)
Definition chan_iax2.c:5579
#define schedule_action(func, data)
Definition chan_iax2.c:1750
static int invalid_key(ast_aes_decrypt_key *ecx)
Definition chan_iax2.c:6483
static int user_cmp_cb(void *obj, void *arg, int flags)
Definition chan_iax2.c:2069
static void __expire_registry(const void *data)
Definition chan_iax2.c:9080
static void reg_source_db(struct iax2_peer *p)
Definition chan_iax2.c:9130
static int scheduled_destroy(const void *vid)
Definition chan_iax2.c:2209
static void prune_peers(void)
static time_t max_calltoken_delay
Definition chan_iax2.c:1011
static struct ao2_container * callno_limits
Definition chan_iax2.c:1034
static int calltoken_required(struct ast_sockaddr *addr, const char *name, int subclass)
Definition chan_iax2.c:2567
static struct ast_frame * iax2_read(struct ast_channel *c)
Definition chan_iax2.c:5573
static struct ast_netsock_list * netsock
Definition chan_iax2.c:390
static int min_reg_expire
Definition chan_iax2.c:383
static int add_calltoken_ignore(const char *addr)
Definition chan_iax2.c:2868
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
#define ACN_FORMAT2
static char * handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:7358
static int iax2_transfer(struct ast_channel *c, const char *dest)
Definition chan_iax2.c:5904
static int iax2_transmit(struct iax_frame *fr)
Definition chan_iax2.c:4407
#define IAX_SENDANI
Definition chan_iax2.c:529
struct iax_frame * last
Definition chan_iax2.c:1005
static void __auth_reject(const void *nothing)
Definition chan_iax2.c:9464
static int adsi
Definition chan_iax2.c:501
static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
Definition chan_iax2.c:6505
iax2_thread_type
Definition chan_iax2.c:1122
@ IAX_THREAD_TYPE_DYNAMIC
Definition chan_iax2.c:1124
@ IAX_THREAD_TYPE_POOL
Definition chan_iax2.c:1123
#define CALLNO_ENTRY_GET_CALLNO(a)
Definition chan_iax2.c:980
static int iax2_getpeertrunk(struct ast_sockaddr addr)
Definition chan_iax2.c:5924
static int attempt_transmit(const void *data)
Definition chan_iax2.c:3704
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
static struct ast_netsock_list * outsock
Definition chan_iax2.c:391
static void prune_users(void)
#define DEFAULT_CONTEXT
Definition chan_iax2.c:344
static void user_destructor(void *obj)
static struct ao2_container * iax_transfercallno_pvts
Another container of iax2_pvt structures.
Definition chan_iax2.c:1243
static struct iax2_user * find_user(const char *name)
Definition chan_iax2.c:2107
static int resyncthreshold
Definition chan_iax2.c:360
#define IAX_RECVCONNECTEDLINE
Definition chan_iax2.c:550
static void register_peer_exten(struct iax2_peer *peer, int onoff)
Definition chan_iax2.c:9042
static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
#define MAX_RETRY_TIME
Definition chan_iax2.c:729
static int iaxdynamicthreadnum
Definition chan_iax2.c:747
static ast_mutex_t callno_pool_lock
Definition chan_iax2.c:988
#define TRUNK_CALL_START
Definition chan_iax2.c:1247
static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
Definition chan_iax2.c:7896
#define MAX_TRUNKDATA
Definition chan_iax2.c:364
static int trunk_maxmtu
Definition chan_iax2.c:342
#define DEFAULT_FREQ_OK
Definition chan_iax2.c:419
static void free_context(struct iax2_context *con)
static char * handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:7551
#define CALLNO_ENTRY_SET_VALIDATED(a)
Definition chan_iax2.c:978
static uint16_t total_nonval_callno_used
Definition chan_iax2.c:1048
static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
Definition chan_iax2.c:8784
#define IAX_DEBUGDIGEST(msg, key)
Definition chan_iax2.c:467
static const char tdesc[]
Definition chan_iax2.c:334
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 global_rtautoclear
Definition chan_iax2.c:553
static void iax2_destroy(int callno)
Definition chan_iax2.c:3532
static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
Definition chan_iax2.c:7338
static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
Definition chan_iax2.c:9763
#define CALLNO_TO_PTR(a)
Definition chan_iax2.c:317
static struct iax_frame * iaxfrdup2(struct iax_frame *fr)
Definition chan_iax2.c:2359
static int transmit_frame(void *data)
Definition chan_iax2.c:4380
static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
static int iax2_answer(struct ast_channel *c)
Definition chan_iax2.c:5844
static int iax2_authmethods
Definition chan_iax2.c:504
static const char * iax2_getformatname_multiple(iax2_format format, struct ast_str **codec_buf)
Definition chan_iax2.c:1988
static void set_hangup_source_and_cause(int callno, unsigned char causecode)
#define IAX_RTUPDATE
Definition chan_iax2.c:540
#define IAX_QUELCH
Definition chan_iax2.c:533
static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
part of the IAX2 dial plan switch interface
static void __send_ping(const void *data)
Definition chan_iax2.c:1789
static struct iax2_peer * find_peer(const char *name, int realtime)
Definition chan_iax2.c:2082
static char * handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:7701
#define MIN_RETRY_TIME
Definition chan_iax2.c:728
static int iaxactivethreadcount
Definition chan_iax2.c:748
static int check_srcaddr(struct ast_sockaddr *addr)
Check if address can be used as packet source.
#define IAX_MAXAUTHREQ
Definition chan_iax2.c:545
static void insert_idle_thread(struct iax2_thread *thread)
Definition chan_iax2.c:1643
static void acl_change_stasis_unsubscribe(void)
Definition chan_iax2.c:1552
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
static int pvt_cmp_cb(void *obj, void *arg, int flags)
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
static void network_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition chan_iax2.c:1570
static int iaxdefaulttimeout
Definition chan_iax2.c:376
static struct ao2_container * users
Definition chan_iax2.c:1028
static int auth_reject(const void *data)
Definition chan_iax2.c:9484
@ 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
static int create_callno_pools(void)
Definition chan_iax2.c:3094
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
#define CALLTOKEN_IE_FORMAT
static char * handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:4074
#define IAX_FORCE_ENCRYPT
Definition chan_iax2.c:551
static char * handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void network_change_stasis_subscribe(void)
Definition chan_iax2.c:1527
static struct ast_switch iax2_switch
iax_transfer_state
Definition chan_iax2.c:695
@ 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
static void poke_all_peers(void)
#define IAX_SENDCONNECTEDLINE
Definition chan_iax2.c:549
static int(* iax2_regfunk)(const char *username, int onoff)
Definition chan_iax2.c:394
static int network_change_sched_cb(const void *data)
Definition chan_iax2.c:1557
static struct @123 frame_queue[IAX_MAX_CALLS]
a list of frames that may need to be retransmitted
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 __do_deliver(void *data)
Definition chan_iax2.c:3413
#define IAX_RTCACHEFRIENDS
Definition chan_iax2.c:539
#define IAX_RTIGNOREREGEXPIRE
Definition chan_iax2.c:542
static char * papp
static int socket_process(struct iax2_thread *thread)
static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
Definition chan_iax2.c:7509
static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
Definition chan_iax2.c:9720
static int iax2_poke_noanswer(const void *data)
static int get_unused_callno(enum callno_type type, int validated, callno_entry *entry)
Definition chan_iax2.c:2978
static char * handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:2909
static char * handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:3987
static int authdebug
Definition chan_iax2.c:369
static struct ast_taskprocessor * transmit_processor
Definition chan_iax2.c:1007
static int iaxdefaultdpcache
Definition chan_iax2.c:374
static int trunk_nmaxmtu
Definition chan_iax2.c:342
static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
#define DEFAULT_MAXMS
Definition chan_iax2.c:418
static int send_lagrq(const void *data)
Definition chan_iax2.c:1877
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...
static int peercnt_add(struct ast_sockaddr *addr)
Definition chan_iax2.c:2704
static int iax2_do_register(struct iax2_registry *reg)
static int iax2_register(const char *value, int lineno)
Definition chan_iax2.c:9006
static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
Definition chan_iax2.c:4431
static struct ast_timer * timer
Definition chan_iax2.c:388
static void __send_lagrq(const void *data)
Definition chan_iax2.c:1853
static void unlink_peer(struct iax2_peer *peer)
Definition chan_iax2.c:9061
static int authenticate_request(int call_num)
Definition chan_iax2.c:8197
static struct iax2_peer * peer_unref(struct iax2_peer *peer)
Definition chan_iax2.c:2101
static int iax2_append_register(const char *hostname, const char *username, const char *secret, const char *porta)
Definition chan_iax2.c:8964
static int maxauthreq
Definition chan_iax2.c:355
static int firmware_show_callback(struct ast_iax2_firmware_header *header, void *user_data)
Definition chan_iax2.c:7345
static int get_from_jb(const void *p)
Definition chan_iax2.c:4301
static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
Definition chan_iax2.c:9821
static int max_reg_expire
Definition chan_iax2.c:384
iax_reg_state
Definition chan_iax2.c:685
@ 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
static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen)
Definition chan_iax2.c:5556
static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
Definition chan_iax2.c:6189
#define ACN_FORMAT1
#define DEFAULT_RETRY_TIME
Definition chan_iax2.c:321
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
static void set_config_destroy(void)
static int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
Definition chan_iax2.c:3158
#define IAX_RTSAVE_SYSNAME
Definition chan_iax2.c:530
static iax2_format iax2_codec_choose(struct iax2_codec_pref *pref, iax2_format formats)
Definition chan_iax2.c:1954
static int iax2_delete_from_sched(const void *data)
Definition chan_iax2.c:2150
static int lagrq_time
Definition chan_iax2.c:358
static char * handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:7797
#define DEFAULT_FREQ_NOTOK
Definition chan_iax2.c:420
static void update_jbsched(struct chan_iax2_pvt *pvt)
Definition chan_iax2.c:4181
static void store_by_peercallno(struct chan_iax2_pvt *pvt)
Definition chan_iax2.c:2491
static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
Definition chan_iax2.c:2651
static int trunkmaxsize
Definition chan_iax2.c:367
static void handle_deferred_full_frames(struct iax2_thread *thread)
Handle any deferred full frames for this thread.
Definition chan_iax2.c:9894
static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
Definition chan_iax2.c:7617
static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
static int test_losspct
Definition chan_iax2.c:489
static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
Definition chan_iax2.c:6655
static int srvlookup
Definition chan_iax2.c:386
static void iax_pvt_callid_set(int callno, ast_callid callid)
Definition chan_iax2.c:1205
static void __get_from_jb(const void *p)
Definition chan_iax2.c:4198
static int iax2_encryption
Definition chan_iax2.c:503
static int peercnt_remove_by_addr(struct ast_sockaddr *addr)
Definition chan_iax2.c:2795
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
static struct call_number_pool callno_pool
Definition chan_iax2.c:991
static pthread_t netthreadid
Definition chan_iax2.c:508
#define CALLNO_ENTRY_TO_PTR(a)
Definition chan_iax2.c:976
static int trunkfreq
Definition chan_iax2.c:366
static void build_rand_pad(unsigned char *buf, ssize_t len)
Definition chan_iax2.c:6473
static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
Definition chan_iax2.c:1183
static char * handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:7771
static char * handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:7468
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 socket_read(int *id, int fd, short events, void *cbdata)
Definition chan_iax2.c:9955
static int peer_delme_cb(void *obj, void *arg, int flags)
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 char * auth_method_names(int authmethods, char *restrict buf)
Get names of all auth methods.
Definition chan_iax2.c:439
static int user_hash_cb(const void *obj, const int flags)
Definition chan_iax2.c:2058
static void peer_destructor(void *obj)
static void __iax2_do_register_s(const void *data)
Definition chan_iax2.c:8723
#define IAX_USEJITTERBUF
Definition chan_iax2.c:527
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
static void jb_warning_output(const char *fmt,...)
Definition chan_iax2.c:1293
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.
calltoken_peer_enum
Call token validation settings.
Definition chan_iax2.c:560
@ 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
static int get_encrypt_methods(const char *s)
Definition chan_iax2.c:1839
static int jittertargetextra
Definition chan_iax2.c:362
static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Part of the IAX2 Switch interface.
static struct @122 qos
static struct ast_flags64 globalflags
Definition chan_iax2.c:506
static struct iax2_dpcache * find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
static iax2_format uncompress_subclass(unsigned char csub)
Definition chan_iax2.c:1906
static void * network_thread(void *ignore)
static char * handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:7313
static int iax2_is_control_frame_allowed(int subtype)
Definition chan_iax2.c:1430
static void network_change_stasis_unsubscribe(void)
Definition chan_iax2.c:1537
static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
Definition chan_iax2.c:4664
static struct io_context * io
Definition chan_iax2.c:480
static int trunk_timed
Definition chan_iax2.c:342
static char * complete_iax2_unregister(const char *line, const char *word, int pos, int state)
Definition chan_iax2.c:7288
static struct stasis_subscription * network_change_sub
Definition chan_iax2.c:351
static int raw_hangup(struct ast_sockaddr *addr, unsigned short src, unsigned short dst, int sockfd)
Definition chan_iax2.c:8160
#define PTR_TO_CALLNO_ENTRY(a)
Definition chan_iax2.c:975
static struct ao2_container * calltoken_ignores
Definition chan_iax2.c:1037
static void * iax2_dup_variable_datastore(void *)
Definition chan_iax2.c:1601
static struct iax2_codec_pref prefs_global
Definition chan_iax2.c:332
iax2_state
Definition chan_iax2.c:510
@ IAX_STATE_TBD
Definition chan_iax2.c:513
@ IAX_STATE_AUTHENTICATED
Definition chan_iax2.c:512
@ IAX_STATE_STARTED
Definition chan_iax2.c:511
static struct iax2_user * realtime_user(const char *username, struct ast_sockaddr *addr)
Definition chan_iax2.c:4589
#define IAX2_TRUNK_PREFACE
Definition chan_iax2.c:662
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 void __iax2_poke_peer_s(const void *data)
Definition chan_iax2.c:9573
static int load_module(void)
Load the module.
static int iax2_vnak(int callno)
Definition chan_iax2.c:9555
#define IAX_CAPABILITY_MEDBANDWIDTH
Definition chan_iax2.c:399
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 DEFAULT_TRUNKDATA
Definition chan_iax2.c:734
static char * handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Show one peer in detail.
Definition chan_iax2.c:3888
static void iax2_process_thread_cleanup(void *data)
#define IAX_TRANSFERMEDIA
Definition chan_iax2.c:544
static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
Definition chan_iax2.c:4436
#define IAX_KEYPOPULATED
Definition chan_iax2.c:535
static int addr_range_cmp_cb(void *obj, void *arg, int flags)
Definition chan_iax2.c:2524
#define IAX_RTAUTOCLEAR
Definition chan_iax2.c:541
static int registry_authrequest(int callno)
Definition chan_iax2.c:9362
static int iax2_provision(struct ast_sockaddr *end, int sockfd, const char *dest, const char *template, int force)
#define FORMAT
const char * iax2_getformatname(iax2_format format)
iax2 wrapper function for ast_getformatname
Definition chan_iax2.c:1976
#define DEFAULT_THREAD_COUNT
Definition chan_iax2.c:319
static int iaxdebug
Definition chan_iax2.c:485
static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static void iax2_free_variable_datastore(void *)
Definition chan_iax2.c:1625
uint16_t callno_entry
Definition chan_iax2.c:764
static int iax2_poke_peer_s(const void *data)
Definition chan_iax2.c:9580
static int addr_range_delme_cb(void *obj, void *arg, int flags)
Definition chan_iax2.c:2511
static struct iax2_thread * find_idle_thread(void)
Definition chan_iax2.c:1658
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)
#define IAX_DYNAMIC
Definition chan_iax2.c:528
static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
Definition chan_iax2.c:4898
static int max_retries
Definition chan_iax2.c:356
static void delete_users(void)
#define MIN_REUSE_TIME
Definition chan_iax2.c:327
#define FORMAT2
#define IAX_TEMPONLY
Definition chan_iax2.c:524
#define IAX_DELAYPBXSTART
Definition chan_iax2.c:546
static int cache_get_callno_locked(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)
Definition chan_iax2.c:1252
static int unload_module(void)
static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
Definition chan_iax2.c:2482
static struct chan_iax2_pvt * iaxs[IAX_MAX_CALLS]
an array of iax2 pvt structures
Definition chan_iax2.c:1198
static int reload(void)
static int peer_set_sock_cb(void *obj, void *arg, int flags)
static int amaflags
Definition chan_iax2.c:500
static void stop_stuff(int callno)
Definition chan_iax2.c:9459
static char * handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:6897
static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
Definition chan_iax2.c:9591
static void log_jitterstats(unsigned short callno)
Definition chan_iax2.c:9851
static struct iax2_peer * peer_ref(struct iax2_peer *peer)
Definition chan_iax2.c:2095
static ast_callid iax_pvt_callid_get(int callno)
Definition chan_iax2.c:1200
#define IAX_CAPABILITY_LOWBANDWIDTH
Definition chan_iax2.c:409
static void cleanup_thread_list(void *head)
static int iaxtrunkdebug
Definition chan_iax2.c:487
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 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 authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
Definition chan_iax2.c:8248
static int iax2_sendtext(struct ast_channel *c, const char *text)
Definition chan_iax2.c:4424
static struct ast_sockaddr debugaddr
Definition chan_iax2.c:1250
static int send_packet(struct iax_frame *f)
Definition chan_iax2.c:3475
static char language[MAX_LANGUAGE]
Definition chan_iax2.c:348
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition chan_iax2.c:497
static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
Definition chan_iax2.c:8176
static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
Definition chan_iax2.c:6515
static char * handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:7247
#define IAX_ALLOWFWDOWNLOAD
Definition chan_iax2.c:547
#define IAX_CODEC_USER_FIRST
Definition chan_iax2.c:536
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
static struct call_number_pool callno_pool_trunk
Definition chan_iax2.c:994
static uint16_t global_maxcallno
Definition chan_iax2.c:1043
static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
Definition chan_iax2.c:2501
#define CALLTOKEN_HASH_FORMAT
#define IAX_DELME
Definition chan_iax2.c:523
static int start_network_thread(void)
#define PEERS_FORMAT
Definition chan_iax2.c:6983
static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
Definition chan_iax2.c:6324
callno_type
Definition chan_iax2.c:970
@ CALLNO_TYPE_TRUNK
Definition chan_iax2.c:972
@ CALLNO_TYPE_NORMAL
Definition chan_iax2.c:971
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
static char mohsuggest[MAX_MUSICCLASS]
Definition chan_iax2.c:499
@ 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
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
static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
Definition chan_iax2.c:6499
static void build_callno_limits(struct ast_variable *v)
Definition chan_iax2.c:2813
static void __attempt_transmit(const void *data)
Definition chan_iax2.c:3621
static struct ast_cli_entry cli_iax2[]
static unsigned int iax2_datetime(const char *tz)
Definition chan_iax2.c:4844
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
#define IAX_CODEC_NOPREFS
Definition chan_iax2.c:537
static int auto_hangup(const void *data)
Definition chan_iax2.c:9528
static char * handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition chan_iax2.c:7178
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition chan_iax2.c:1584
static char mohinterpret[MAX_MUSICCLASS]
Definition chan_iax2.c:498
static const struct ast_datastore_info iax2_variable_datastore_info
Definition chan_iax2.c:1595
static void sched_delay_remove(struct ast_sockaddr *addr, callno_entry entry)
Definition chan_iax2.c:3127
static int iax2_do_register_s(const void *data)
Definition chan_iax2.c:8741
static int iax2_devicestate(const char *data)
Part of the device state notification system —.
static void peercnt_remove(struct peercnt *peercnt)
Definition chan_iax2.c:2755
static int network_change_sched_id
Definition chan_iax2.c:353
static int expire_registry(const void *data)
Definition chan_iax2.c:9121
#define MAX_PEER_BUCKETS
Definition chan_iax2.c:1023
static void iax2_frame_free(struct iax_frame *fr)
Definition chan_iax2.c:2203
static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
Definition chan_iax2.c:6539
static void requirecalltoken_mark_auto(const char *name, int subclass)
Definition chan_iax2.c:4990
static int defaultsockfd
Definition chan_iax2.c:392
static int iaxmaxthreadcount
Definition chan_iax2.c:745
static int peercnt_cmp_cb(void *obj, void *arg, int flags)
Definition chan_iax2.c:2542
static struct ao2_container * iax_peercallno_pvts
Another container of iax2_pvt structures.
Definition chan_iax2.c:1227
static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int)
Definition chan_iax2.c:7882
static int make_trunk(unsigned short callno, int locked)
Definition chan_iax2.c:2406
static int register_verify(int callno, struct ast_sockaddr *addr, struct iax_ies *ies)
Verify inbound registration.
Definition chan_iax2.c:8343
static int global_max_trunk_mtu
Definition chan_iax2.c:341
static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
Definition chan_iax2.c:9543
static const char type[]
struct ast_sockaddr bindaddr
static char version[AST_MAX_EXTENSION]
static const char config[]
static int transfer(void *data)
static int reload_config(void)
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
const char * ast_channel_name(const struct ast_channel *chan)
#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_channel_tech_pvt(const struct ast_channel *chan)
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition channel.c:2375
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition channel.c:2538
#define AST_BRIDGE_DTMF_CHANNEL_0
Report DTMF on channel 0.
Definition channel.h:2420
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition channel.h:1299
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition channel.c:1181
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition channel.c:1807
#define DATASTORE_INHERIT_FOREVER
Definition channel.h:194
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition channel.c:2058
struct ast_channel * ast_waitfor_n(struct ast_channel **chan, int n, int *ms)
Waits for input on a group of channels Wait for input on an array of channels for a given # of millis...
Definition channel.c:3154
#define ast_channel_lock(chan)
Definition channel.h:2982
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition channel.c:570
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
#define ast_channel_ref(c)
Increase channel reference count.
Definition channel.h:3007
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
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:1170
const char * ast_channel_context(const struct ast_channel *chan)
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition channel.c:5139
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition channel.c:4250
#define AST_BRIDGE_DTMF_CHANNEL_1
Report DTMF on channel 1.
Definition channel.h:2422
#define ast_channel_trylock(chan)
Definition channel.h:2984
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:1295
ast_channel_adsicpe
Definition channel.h:888
@ AST_ADSI_UNAVAILABLE
Definition channel.h:891
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:7346
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition channel.c:5757
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)
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:8829
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition channel.c:445
int ast_channel_hangupcause(const struct ast_channel *chan)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
#define AST_MAX_ACCOUNT_CODE
Definition channel.h:172
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition channel.c:1570
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:2496
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:4340
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition channel.c:1273
ast_bridge_result
Definition channel.h:208
@ AST_BRIDGE_FAILED_NOWARN
Definition channel.h:211
@ AST_BRIDGE_RETRY
Definition channel.h:212
@ AST_BRIDGE_COMPLETE
Definition channel.h:209
@ AST_BRIDGE_FAILED
Definition channel.h:210
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition channel.c:1248
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
#define AST_CHANNEL_NAME
Definition channel.h:173
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition channel.c:539
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
#define ast_channel_unref(c)
Decrease channel reference count.
Definition channel.h:3018
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:5798
#define AST_MAX_CONTEXT
Definition channel.h:135
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition channel.c:2008
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
const char * ast_channel_language(const struct ast_channel *chan)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
@ AST_CHAN_TP_WANTSJITTER
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
Definition channel.h:980
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
Definition channel.c:4354
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
@ AST_FLAG_DISABLE_DEVSTATE_CACHE
Definition channel.h:1049
void ast_channel_callid_set(struct ast_channel *chan, ast_callid value)
void ast_channel_hangupcause_set(struct ast_channel *chan, int 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)
@ AST_SOFTHANGUP_DEV
Definition channel.h:1141
#define ast_channel_unlock(chan)
Definition channel.h:2983
#define AST_MAX_EXTENSION
Definition channel.h:134
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
#define MAX_MUSICCLASS
Definition channel.h:175
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:2389
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.
uint64_t iax2_format_compatibility_cap2bitfield(const struct ast_format_cap *cap)
Convert a format capabilities structure to a bitfield.
int iax2_format_compatibility_bitfield2cap(uint64_t bitfield, struct ast_format_cap *cap)
Convert a bitfield to a format capabilities structure.
ast_channel_state
ast_channel states
@ AST_STATE_RING
@ AST_STATE_RINGING
@ AST_STATE_DOWN
@ AST_STATE_RESERVED
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition channel.c:7398
static struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags, int rdlock)
const char * ast_var_name(const struct ast_var_t *var)
Definition chanvars.c:60
#define ast_var_assign(name, value)
Definition chanvars.h:40
const char * ast_var_value(const struct ast_var_t *var)
Definition chanvars.c:80
void ast_var_delete(struct ast_var_t *var)
Definition extconf.c:2469
#define CLI_SHOWUSAGE
Definition cli.h:45
#define CLI_SUCCESS
Definition cli.h:44
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197
#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
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition main/cli.c:1823
@ CLI_HANDLER
Definition cli.h:154
@ CLI_INIT
Definition cli.h:152
@ CLI_GENERATE
Definition cli.h:153
#define CLI_FAILURE
Definition cli.h:46
#define RESULT_FAILURE
Definition cli.h:42
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition cli.h:265
@ AST_MEDIA_TYPE_AUDIO
Definition codec.h:32
@ AST_MEDIA_TYPE_UNKNOWN
Definition codec.h:31
unsigned int ast_codec_samples_count(struct ast_frame *frame)
Get the number of samples contained within a frame.
Definition codec.c:379
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
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
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
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
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
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
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 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
short word
#define attribute_pure
Definition compiler.h:35
#define SENTINEL
Definition compiler.h:87
int AST_OPTIONAL_API_NAME() 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_OPTIONAL_API_NAME() 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_OPTIONAL_API_NAME() ast_sign(struct ast_key *key, char *msg, char *sig)
Sign a message signature using a given private key.
Definition res_crypto.c:584
int AST_OPTIONAL_API_NAME() ast_aes_decrypt(const unsigned char *in, unsigned char *out, const ast_aes_decrypt_key *key)
AES decrypt data.
Definition res_crypto.c:790
#define AST_KEY_PUBLIC
Definition crypto.h:46
#define AST_KEY_PRIVATE
Definition crypto.h:47
struct ast_key *AST_OPTIONAL_API_NAME() ast_key_get(const char *kname, int ktype)
Retrieve a key.
Definition res_crypto.c:149
int AST_OPTIONAL_API_NAME() ast_aes_set_decrypt_key(const unsigned char *key, ast_aes_decrypt_key *ctx)
Set a decryption key.
Definition res_crypto.c:709
int AST_OPTIONAL_API_NAME() ast_aes_encrypt(const unsigned char *in, unsigned char *out, const ast_aes_encrypt_key *key)
AES encrypt data.
Definition res_crypto.c:749
#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
@ 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.
@ AST_DEVICE_UNKNOWN
Definition devicestate.h:53
@ AST_DEVICE_INVALID
Definition devicestate.h:57
@ AST_DEVICE_NOT_INUSE
Definition devicestate.h:54
@ AST_DEVICE_UNAVAILABLE
Definition devicestate.h:58
void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry)
Free a DNS manager entry.
Definition dnsmgr.c:136
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
int ast_dnsmgr_changed(struct ast_dnsmgr_entry *entry)
Check is see if a dnsmgr entry has changed.
Definition dnsmgr.c:247
int ast_dnsmgr_refresh(struct ast_dnsmgr_entry *entry)
Force a refresh of a dnsmgr entry.
Definition dnsmgr.c:239
threshold
Definition dsp.h:71
char * end
Definition eagi_proxy.c:73
char buf[BUFSIZE]
Definition eagi_proxy.c:66
@ AST_ENDPOINT_OFFLINE
Definition endpoints.h:55
@ AST_ENDPOINT_ONLINE
Definition endpoints.h:57
void ast_endpoint_set_state(struct ast_endpoint *endpoint, enum ast_endpoint_state state)
Updates the state of the given endpoint.
void ast_endpoint_shutdown(struct ast_endpoint *endpoint)
Shutsdown an ast_endpoint.
struct ast_endpoint * ast_endpoint_create(const char *tech, const char *resource)
Create an endpoint struct.
#define abs(x)
Definition f2c.h:195
int iax_firmware_get_version(const char *dev, uint16_t *version)
Definition firmware.c:263
void iax_firmware_reload(void)
Definition firmware.c:206
void iax_firmware_unload(void)
Definition firmware.c:250
int iax_firmware_append(struct iax_ie_data *ied, const char *dev, unsigned int desc)
Definition firmware.c:283
void iax_firmware_traverse(const char *filter, int(*callback)(struct ast_iax2_firmware_header *header, void *data), void *data)
Definition firmware.c:321
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition format.c:354
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition format.c:379
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
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition format.c:334
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_slin
Built-in cached signed linear 8kHz format.
struct ast_format * ast_format_none
Built-in "null" format.
#define AST_FORMAT_CAP_NAMES_LEN
Definition format_cap.h:324
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
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
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
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
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
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition format_cap.h:38
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
int ast_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if two capabilities structures are identical.
Definition format_cap.c:687
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition format_cap.h:99
#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
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
static const char name[]
Definition format_mp3.c:68
static int exists(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition func_logic.c:185
static int md5(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition func_md5.c:55
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
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:2024
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:2060
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition manager.c:1643
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition manager.c:2068
void astman_append(struct mansession *s, const char *fmt,...)
Definition manager.c:1903
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition manager.c:7698
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.
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
struct stasis_message_type * ast_endpoint_state_type(void)
Message type for endpoint state changes.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
static int iax2_prov_app(struct ast_channel *chan, const char *data)
const char * ext
Definition http.c:150
#define IAX_IE_PASSWORD
Definition iax2.h:137
#define IAX_LINGER_TIMEOUT
Definition iax2.h:126
#define IAX_IE_RR_PKTS
Definition iax2.h:179
#define IAX_DPSTATUS_CANEXIST
Definition iax2.h:218
@ IAX_COMMAND_FWDOWNL
Definition iax2.h:111
@ IAX_COMMAND_TXREL
Definition iax2.h:91
@ IAX_COMMAND_TXMEDIA
Definition iax2.h:115
@ IAX_COMMAND_AUTHREP
Definition iax2.h:60
@ IAX_COMMAND_PROVISION
Definition iax2.h:109
@ IAX_COMMAND_DPREP
Definition iax2.h:79
@ IAX_COMMAND_REGAUTH
Definition iax2.h:67
@ IAX_COMMAND_INVAL
Definition iax2.h:61
@ IAX_COMMAND_REJECT
Definition iax2.h:57
@ IAX_COMMAND_FWDATA
Definition iax2.h:113
@ IAX_COMMAND_ACK
Definition iax2.h:55
@ IAX_COMMAND_PONG
Definition iax2.h:54
@ IAX_COMMAND_LAGRQ
Definition iax2.h:62
@ IAX_COMMAND_HANGUP
Definition iax2.h:56
@ IAX_COMMAND_TXREADY
Definition iax2.h:89
@ IAX_COMMAND_TXACC
Definition iax2.h:87
@ IAX_COMMAND_QUELCH
Definition iax2.h:95
@ IAX_COMMAND_PING
Definition iax2.h:53
@ IAX_COMMAND_TRANSFER
Definition iax2.h:107
@ IAX_COMMAND_LAGRP
Definition iax2.h:63
@ IAX_COMMAND_TXCNT
Definition iax2.h:85
@ IAX_COMMAND_REGACK
Definition iax2.h:69
@ IAX_COMMAND_AUTHREQ
Definition iax2.h:59
@ IAX_COMMAND_TXREJ
Definition iax2.h:93
@ IAX_COMMAND_REGREJ
Definition iax2.h:71
@ IAX_COMMAND_REGREL
Definition iax2.h:73
@ IAX_COMMAND_CALLTOKEN
Definition iax2.h:119
@ IAX_COMMAND_DIAL
Definition iax2.h:81
@ IAX_COMMAND_ACCEPT
Definition iax2.h:58
@ IAX_COMMAND_UNSUPPORT
Definition iax2.h:105
@ IAX_COMMAND_NEW
Definition iax2.h:52
@ IAX_COMMAND_POKE
Definition iax2.h:99
@ IAX_COMMAND_REGREQ
Definition iax2.h:65
@ IAX_COMMAND_VNAK
Definition iax2.h:75
@ IAX_COMMAND_UNQUELCH
Definition iax2.h:97
@ IAX_COMMAND_TXREQ
Definition iax2.h:83
@ IAX_COMMAND_RTKEY
Definition iax2.h:117
@ IAX_COMMAND_DPREQ
Definition iax2.h:77
#define IAX_IE_RR_JITTER
Definition iax2.h:177
#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_FLAG_SC_LOG
Definition iax2.h:44
#define IAX_IE_DATETIME
Definition iax2.h:161
#define IAX_IE_CAUSE
Definition iax2.h:152
#define IAX_IE_DPSTATUS
Definition iax2.h:150
#define IAX_IE_CALLING_NUMBER
Definition iax2.h:132
#define IAX_IE_TRANSFERID
Definition iax2.h:157
#define IAX_IE_CALLTOKEN
Definition iax2.h:185
#define IAX_IE_CALLING_ANI
Definition iax2.h:133
#define IAX_DEFAULT_PORTNO
Definition iax2.h:128
#define IAX_IE_CALLINGTNS
Definition iax2.h:170
#define IAX_IE_RSA_RESULT
Definition iax2.h:147
#define IAX_IE_MSGCOUNT
Definition iax2.h:154
#define IAX_META_TRUNK_SUPERMINI
Definition iax2.h:207
#define IAX_IE_IAX_UNKNOWN
Definition iax2.h:153
int64_t iax2_format
Definition iax2.h:224
#define IAX_DPSTATUS_NONEXISTENT
Definition iax2.h:219
#define IAX_IE_FORMAT2
Definition iax2.h:188
#define IAX_DPSTATUS_IGNOREPAT
Definition iax2.h:220
#define IAX_IE_CAPABILITY2
Definition iax2.h:187
#define IAX_IE_CALLING_NAME
Definition iax2.h:134
#define IAX_DEFAULT_REG_EXPIRE
Definition iax2.h:123
#define IAX_IE_ADSICPE
Definition iax2.h:142
#define IAX_IE_VARIABLE
Definition iax2.h:183
#define IAX_AUTH_RSA
Definition iax2.h:199
#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_FLAG_FULL
Definition iax2.h:40
#define IAX_IE_RR_DROPPED
Definition iax2.h:181
#define IAX_MAX_SHIFT
Definition iax2.h:46
#define IAX_IE_FORMAT
Definition iax2.h:139
#define IAX_IE_ENCRYPTION
Definition iax2.h:173
#define IAX_ENCRYPT_AES128
Definition iax2.h:201
#define IAX_AUTH_MD5
Definition iax2.h:198
#define IAX_MAX_OSPBUFF_SIZE
Definition iax2.h:195
#define IAX_IE_FIRMWAREVER
Definition iax2.h:164
#define IAX_FLAG_RETRANS
Definition iax2.h:42
#define IAX_IE_CODEC_PREFS
Definition iax2.h:175
#define IAX_IE_CALLED_NUMBER
Definition iax2.h:131
#define IAX_IE_CAPABILITY
Definition iax2.h:138
#define IAX_DPSTATUS_MATCHMORE
Definition iax2.h:221
#define IAX_IE_PROVISIONING
Definition iax2.h:159
#define IAX_IE_MD5_RESULT
Definition iax2.h:146
#define IAX_PROTO_VERSION
Definition iax2.h:27
#define IAX_IE_AUTOANSWER
Definition iax2.h:155
#define IAX_IE_VERSION
Definition iax2.h:141
#define IAX_ENCRYPT_KEYROTATE
Definition iax2.h:202
#define IAX_IE_RR_OOO
Definition iax2.h:182
#define IAX_IE_CALLNO
Definition iax2.h:151
#define IAX_IE_APPARENT_ADDR
Definition iax2.h:148
#define IAX_AUTH_PLAINTEXT
Definition iax2.h:197
#define IAX_IE_REFRESH
Definition iax2.h:149
#define IAX_MAX_OSPBLOCK_NUM
Definition iax2.h:193
#define IAX_META_TRUNK
Definition iax2.h:204
#define IAX_META_TRUNK_MINI
Definition iax2.h:208
#define IAX_IE_CALLINGPRES
Definition iax2.h:168
#define IAX_IE_CAUSECODE
Definition iax2.h:172
#define IAX_IE_AUTHMETHODS
Definition iax2.h:144
#define IAX_IE_RR_LOSS
Definition iax2.h:178
#define IAX_MAX_CALLS
Definition iax2.h:37
#define IAX_IE_CALLED_CONTEXT
Definition iax2.h:135
#define IAX_IE_CALLINGTON
Definition iax2.h:169
#define IAX_DPSTATUS_EXISTS
Definition iax2.h:217
#define IAX_IE_USERNAME
Definition iax2.h:136
#define IAX_IE_CHALLENGE
Definition iax2.h:145
#define IAX_IE_RR_DELAY
Definition iax2.h:180
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
#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:3324
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
#define ast_variable_new(name, value, filename)
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *p_result,...)
The argument parsing routine.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition extconf.c:1287
@ CONFIG_FLAG_FILEUNCHANGED
int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *replacement)
Replace a variable in the given list with a new value.
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition extconf.c:1260
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition extconf.c:1213
uint64_t ast_format_compatibility_format2bitfield(const struct ast_format *format)
Convert a format structure to its respective bitfield.
struct ast_format * ast_format_compatibility_bitfield2format(uint64_t bitfield)
Convert a bitfield to its respective format structure.
#define ast_frame_byteswap_be(fr)
#define AST_FRAME_DTMF
#define AST_OPTION_RELAXDTMF
#define AST_OPTION_TONE_VERIFY
@ AST_FRFLAG_HAS_TIMING_INFO
#define AST_OPTION_RXGAIN
#define AST_OPTION_DIGIT_DETECT
@ AST_TRANSFER_SUCCESS
#define AST_OPTION_OPRMODE
#define ast_frfree(fr)
#define AST_OPTION_TDD
#define AST_OPTION_SECURE_MEDIA
#define AST_OPTION_FLAG_REQUEST
#define AST_OPTION_FAX_DETECT
#define AST_OPTION_TXGAIN
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
#define AST_OPTION_SECURE_SIGNALING
@ AST_FRAME_DTMF_END
@ AST_FRAME_DTMF_BEGIN
@ AST_FRAME_CONTROL
ast_control_frame_type
Internal control frame subtype field values.
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_RECORD_CANCEL
@ 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_UNHOLD
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE
@ AST_CONTROL_STREAM_REVERSE
@ AST_CONTROL_PROCEEDING
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_TAKEOFFHOOK
@ AST_CONTROL_T38_PARAMETERS
@ AST_CONTROL_READ_ACTION
@ AST_CONTROL_RECORD_STOP
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_PLAYBACK_BEGIN
@ AST_CONTROL_ANSWER
@ AST_CONTROL_RECORD_MUTE
@ AST_CONTROL_RINGING
@ AST_CONTROL_HANGUP
@ AST_CONTROL_STREAM_STOP
@ AST_CONTROL_RADIO_KEY
@ AST_CONTROL_OPTION
@ AST_CONTROL_STREAM_TOPOLOGY_CHANGED
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_END_OF_Q
@ AST_CONTROL_TRANSFER
@ AST_CONTROL_STREAM_FORWARD
@ AST_CONTROL_FLASH
@ AST_CONTROL_RECORD_SUSPEND
@ AST_CONTROL_SRCCHANGE
@ AST_CONTROL_INCOMPLETE
@ _XXX_AST_CONTROL_T38
@ AST_CONTROL_MASQUERADE_NOTIFY
@ AST_CONTROL_PVT_CAUSE_CODE
@ AST_CONTROL_UPDATE_RTP_PEER
#define AST_OPTION_AUDIO_MODE
struct ast_frame ast_null_frame
Definition main/frame.c:79
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:2258
#define ast_debug(level,...)
Log a DEBUG message.
ast_callid ast_read_threadstorage_callid(void)
extracts the callid from the thread
Definition logger.c:2268
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
Definition logger.c:2290
#define AST_CALLID_BUFFER_LENGTH
ast_callid ast_create_callid(void)
factory function to create a new uniquely identifying callid.
Definition logger.c:2263
unsigned int ast_callid
#define VERBOSE_PREFIX_4
int ast_callid_threadassoc_remove(void)
Removes callid from thread storage of the calling thread.
Definition logger.c:2309
#define LOG_ERROR
#define ast_verb(level,...)
#define LOG_NOTICE
#define LOG_WARNING
#define ast_verbose(...)
#define AST_IO_IN
Definition io.h:34
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
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
void io_context_destroy(struct io_context *ioc)
Destroys a context.
Definition io.c:107
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
Definition io.c:278
void jb_destroy(jitterbuf *jb)
destroy jitterbuf
Definition jitterbuf.c:99
void jb_reset(jitterbuf *jb)
reset jitterbuf
Definition jitterbuf.c:72
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
jitterbuf * jb_new(void)
new jitterbuf
Definition jitterbuf.c:86
void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg)
Definition jitterbuf.c:55
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
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_TYPE_CONTROL
Definition jitterbuf.h:61
@ JB_TYPE_SILENCE
Definition jitterbuf.h:64
@ JB_TYPE_VOICE
Definition jitterbuf.h:62
enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf)
set jitterbuf conf
Definition jitterbuf.c:825
enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout)
unconditionally get frames from jitterbuf until empty
Definition jitterbuf.c:801
@ JB_EMPTY
Definition jitterbuf.h:52
@ JB_SCHED
Definition jitterbuf.h:56
@ JB_DROP
Definition jitterbuf.h:55
@ JB_NOFRAME
Definition jitterbuf.h:53
@ JB_INTERP
Definition jitterbuf.h:54
@ JB_OK
Definition jitterbuf.h:51
enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats)
get jitterbuf info: only "statistics" may be valid
Definition jitterbuf.c:815
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
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_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list entry before the current entry during a traversal.
#define AST_LIST_LOCK(head)
Locks a list.
Definition linkedlists.h:40
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
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
#define ast_cond_destroy(cond)
Definition lock.h:209
#define ast_cond_wait(cond, mutex)
Definition lock.h:212
#define AST_PTHREADT_NULL
Definition lock.h:73
#define ast_cond_init(cond, attr)
Definition lock.h:208
#define ast_cond_timedwait(cond, mutex, time)
Definition lock.h:213
#define ast_mutex_init(pmutex)
Definition lock.h:193
#define DEADLOCK_AVOIDANCE(lock)
Definition lock.h:486
#define ast_mutex_unlock(a)
Definition lock.h:197
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
#define ast_mutex_trylock(a)
Definition lock.h:198
pthread_cond_t ast_cond_t
Definition lock.h:185
#define ast_mutex_destroy(a)
Definition lock.h:195
#define ast_mutex_lock(a)
Definition lock.h:196
#define AST_MUTEX_DEFINE_STATIC(mutex)
Definition lock.h:527
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
#define ast_cond_signal(cond)
Definition lock.h:210
static char hostname[MAXHOSTNAMELEN]
Definition logger.c:116
int errno
#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
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
@ AST_MODFLAG_LOAD_ORDER
Definition module.h:331
#define ast_module_unref(mod)
Release a reference to the module.
Definition module.h:483
#define ast_module_ref(mod)
Hold a reference to the module.
Definition module.h:457
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition module.h:557
@ AST_MODPRI_CHANNEL_DRIVER
Definition module.h:341
@ AST_MODULE_SUPPORT_CORE
Definition module.h:121
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition module.h:46
int ast_unregister_application(const char *app)
Unregister an application.
Definition pbx_app.c:392
@ 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
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:7778
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition channel.c:7788
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
void * ast_mwi_unsubscribe(struct ast_mwi_subscriber *sub)
Unsubscribe from the stasis topic and MWI.
Definition mwi.c:254
struct stasis_cache * ast_mwi_state_cache(void)
Backend cache for ast_mwi_topic_cached().
Definition mwi.c:94
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
meta
below block is needed for mssql
Definition env.py:22
@ AST_AF_UNSPEC
Definition netsock2.h:54
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition netsock2.h:256
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition netsock2.h:517
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
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition netsock2.c:524
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition netsock2.c:590
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
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
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
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
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_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition netsock2.c:230
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
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
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition netsock2.c:388
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
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition netsock2.h:532
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
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition netsock2.h:138
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
Definition netsock2.c:507
int ast_sockaddr_hash(const struct ast_sockaddr *addr)
Computes a hash value from the address. The port is ignored.
Definition netsock2.c:548
int ast_netsock_release(struct ast_netsock_list *list)
Definition netsock.c:85
struct ast_netsock_list * ast_netsock_list_alloc(void)
Definition netsock.c:72
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 ast_netsock_init(struct ast_netsock_list *list)
Definition netsock.c:77
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
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition utils.c:964
int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
Definition parser.c:795
int iax_get_iframes(void)
Definition parser.c:1351
#define DIRECTION_OUTGRESS
Definition parser.h:89
int iax_ie_append_addr(struct iax_ie_data *ied, unsigned char ie, const struct ast_sockaddr *addr)
Definition parser.c:741
void iax_frame_subclass2str(enum iax_frame_subclass subclass, char *str, size_t len)
Definition parser.c:463
int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigned char dat)
Definition parser.c:775
void iax_frame_free(struct iax_frame *fr)
Definition parser.c:1296
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
struct iax_frame * iax_frame_new(int direction, int datalen, unsigned int cacheable)
Definition parser.c:1229
int iax_ie_append_raw(struct iax_ie_data *ied, unsigned char ie, const void *data, int datalen)
Definition parser.c:726
int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value)
Definition parser.c:756
void iax_set_output(void(*output)(const char *data))
int iax_get_oframes(void)
Definition parser.c:1352
#define DIRECTION_INGRESS
Definition parser.h:88
void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
Definition parser.c:1196
int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsigned short value)
Definition parser.c:763
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
int iax_ie_append_str(struct iax_ie_data *ied, unsigned char ie, const char *str)
Definition parser.c:770
int iax_get_frames(void)
Definition parser.c:1350
void iax_set_error(void(*output)(const char *data))
const char * ast_config_AST_SYSTEM_NAME
Definition options.c:171
static int totalcalls
Definition pbx.c:794
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:6953
int ast_context_destroy_by_name(const char *context, const char *registrar)
Destroy a context by name.
Definition pbx.c:8234
void ast_unregister_switch(struct ast_switch *sw)
Unregister an alternative switch.
Definition pbx_switch.c:76
int ast_register_switch(struct ast_switch *sw)
Register an alternative dialplan switch.
Definition pbx_switch.c:58
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
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:4196
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:6170
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition pbx_app.c:471
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.
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition pbx.c:4969
#define ast_custom_function_register(acf)
Register a custom function.
Definition pbx.h:1562
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:4211
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition pbx.c:4729
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
Definition pbx.c:6904
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:4216
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition ael_main.c:165
static int netsocket
Definition pbx_dundi.c:195
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
#define ast_poll(a, b, c)
Definition poll-compat.h:88
int iax_provision_reload(int reload)
Definition provision.c:526
int iax_provision_build(struct iax_ie_data *provdata, unsigned int *signature, const char *template, int force)
Definition provision.c:209
int iax_provision_unload(void)
Definition provision.c:517
char * iax_prov_complete_template(const char *line, const char *word, int pos, int state)
Definition provision.c:179
int iax_provision_version(unsigned int *signature, const char *template, int force)
Definition provision.c:258
static int total
Definition res_adsi.c:970
static struct stasis_subscription * sub
Statsd channel stats. Exmaple of how to subscribe to Stasis events.
static struct @487 methods[]
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.
static void cleanup(void)
Clean up any old apps that we don't need any more.
Definition res_stasis.c:327
static struct @519 args
unsigned int refresh
#define NULL
Definition resample.c:96
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition sched.h:46
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
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
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
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition sched.c:271
int ast_sched_start_thread(struct ast_sched_context *con)
Start a thread for processing scheduler entries.
Definition sched.c:197
int(* ast_sched_cb)(const void *data)
scheduler callback
Definition sched.h:178
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition sched.c:238
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:1090
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:1144
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:876
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition stasis.c:1201
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.
#define stasis_subscribe(topic, callback, data)
Definition stasis.h:649
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.
struct stasis_topic * ast_system_topic(void)
A Stasis Message Bus API topic which publishes messages regarding system changes.
struct stasis_message_type * ast_network_change_type(void)
A stasis_message_type for network changes.
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
#define AST_STRING_FIELD(name)
Declare a string field.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
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
size_t attribute_pure ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition strings.h:730
#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
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition strings.h:1259
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:2235
#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
int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
Parse a time (integer) string.
Definition utils.c:2482
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
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:2252
#define ast_str_alloca(init_len)
Definition strings.h:848
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:1854
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
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition strings.h:425
struct ast_ha ha
Definition chan_iax2.c:1067
unsigned char delme
Definition chan_iax2.c:1071
uint16_t limit
Definition chan_iax2.c:1069
unsigned char raw[AST_CRYPTO_AES_BLOCKSIZE/8]
Definition crypto.h:40
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition astobj2.h:1821
Wrapper for an ast_acl linked list.
Definition acl.h:76
ast_app: A registered application
Definition pbx_app.c:45
Structure to pass both assignedid values to channel drivers.
Definition channel.h:606
Structure to describe a channel "technology", ie a channel driver See for examples:
Definition channel.h:648
struct ast_format_cap * capabilities
Definition channel.h:652
const char *const type
Definition channel.h:649
Main Channel structure associated with a channel.
const char * data
char context[AST_MAX_CONTEXT]
descriptor for a cli entry.
Definition cli.h:171
int args
This gets set in ast_cli_register()
Definition cli.h:185
char * command
Definition cli.h:186
const char * usage
Definition cli.h:177
Data structure associated with a custom dialplan function.
Definition pbx.h:118
const char * name
Definition pbx.h:119
Structure for a data store type.
Definition datastore.h:31
const char * type
Definition datastore.h:32
Structure for a data store object.
Definition datastore.h:64
void * data
Definition datastore.h:66
unsigned int inheritance
Definition datastore.h:69
Definition dnsmgr.c:66
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition utils.h:225
Structure used to handle boolean flags.
Definition utils.h:220
Format capabilities structure, holds formats + preference order + etc.
Definition format_cap.c:54
Definition of a media format.
Definition format.c:43
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
struct timeval delivery
enum ast_frame_type frametype
struct ast_frame * next
union ast_frame::@239 data
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
struct ast_sockaddr netmask
Definition acl.h:54
unsigned char encdata[0]
Definition iax2.h:245
unsigned short dcallno
Definition iax2.h:232
unsigned short scallno
Definition iax2.h:231
unsigned int ts
Definition iax2.h:233
unsigned char iseqno
Definition iax2.h:235
unsigned char csub
Definition iax2.h:237
unsigned char oseqno
Definition iax2.h:234
unsigned char type
Definition iax2.h:236
Definition iax2.h:282
unsigned short callno
Definition iax2.h:283
unsigned short len
Definition iax2.h:284
unsigned int ts
Definition iax2.h:278
unsigned char data[0]
Definition iax2.h:279
unsigned short len
Definition iax2.h:289
struct ast_iax2_mini_hdr mini
Definition iax2.h:290
unsigned short callno
Definition iax2.h:259
unsigned char encdata[0]
Definition iax2.h:260
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
Abstract JSON element (object, array, string, int, ...).
struct ast_module * self
Definition module.h:356
Structure for mutex and tracking information.
Definition lock.h:142
The structure that contains MWI state.
Definition mwi.h:455
int old_msgs
Definition mwi.h:460
int new_msgs
Definition mwi.h:459
int sockfd
Definition netsock.c:54
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
Connected Line/Party information.
Definition channel.h:458
struct ast_party_id id
Connected party ID.
Definition channel.h:460
char * str
Subscriber phone number (Malloced)
Definition channel.h:388
struct ast_party_dialed::@221 number
Dialed/Called number.
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
unsigned char valid
TRUE if the name information is valid/present.
Definition channel.h:281
char * str
Subscriber name (Malloced)
Definition channel.h:266
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
Socket address structure.
Definition netsock2.h:97
struct sockaddr_storage ss
Definition netsock2.h:98
Support for dynamic strings.
Definition strings.h:623
const char * name
Definition pbx.h:163
A ast_taskprocessor structure is a singleton by name.
struct ast_var_t::@224 entries
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
callno_entry numbers[IAX_MAX_CALLS/2+1]
Definition chan_iax2.c:985
unsigned char semirand[32]
Definition chan_iax2.c:905
const ast_string_field mohinterpret
Definition chan_iax2.c:886
int first_iax_message
Definition chan_iax2.c:790
struct ast_sockaddr addr
Definition chan_iax2.c:800
struct ast_variable * vars
Definition chan_iax2.c:944
const ast_string_field language
Definition chan_iax2.c:886
int frames_received
Definition chan_iax2.c:954
const ast_string_field cid_num
Definition chan_iax2.c:886
struct chan_iax2_pvt::signaling_queue signaling_queue
iax2_format svideoformat
Definition chan_iax2.c:778
unsigned int lastsent
Definition chan_iax2.c:784
const ast_string_field inkeys
Definition chan_iax2.c:886
const ast_string_field outkey
Definition chan_iax2.c:886
unsigned int nextpred
Definition chan_iax2.c:788
iax2_format capability
Definition chan_iax2.c:780
int destroy_initiated
Definition chan_iax2.c:956
unsigned int pingtime
Definition chan_iax2.c:796
const ast_string_field dproot
Definition chan_iax2.c:886
const ast_string_field mohsuggest
Definition chan_iax2.c:886
unsigned short bridgecallno
Definition chan_iax2.c:929
const ast_string_field accountcode
Definition chan_iax2.c:886
const ast_string_field username
Definition chan_iax2.c:886
iax2_format peercapability
Definition chan_iax2.c:819
struct ast_variable * iaxvars
Definition chan_iax2.c:946
struct ast_flags state
Definition chan_iax2.c:835
unsigned int notsilenttx
Definition chan_iax2.c:794
unsigned int lastvsent
Definition chan_iax2.c:786
ast_callid callid
Definition chan_iax2.c:770
unsigned char iseqno
Definition chan_iax2.c:843
char hold_signaling
Definition chan_iax2.c:960
struct timeval rxcore
Definition chan_iax2.c:823
struct ast_sockaddr transfer
Definition chan_iax2.c:919
iax2_format voiceformat
Definition chan_iax2.c:772
const ast_string_field context
Definition chan_iax2.c:886
unsigned short peercallno
Definition chan_iax2.c:810
struct iax2_codec_pref prefs
Definition chan_iax2.c:802
unsigned short callno
Definition chan_iax2.c:806
unsigned char calltoken_ie_len
Definition chan_iax2.c:958
const ast_string_field parkinglot
Definition chan_iax2.c:886
iax2_format videoformat
Definition chan_iax2.c:774
unsigned char rseqno
Definition chan_iax2.c:841
const ast_string_field host
Definition chan_iax2.c:886
callno_entry callno_entry
Definition chan_iax2.c:808
uint64_t flags
Definition chan_iax2.c:911
unsigned short transfercallno
Definition chan_iax2.c:921
struct ast_channel * owner
Definition chan_iax2.c:833
const ast_string_field rdnis
Definition chan_iax2.c:886
unsigned char oseqno
Definition chan_iax2.c:839
struct timeval offset
Definition chan_iax2.c:821
unsigned char aseqno
Definition chan_iax2.c:845
iax2_format svoiceformat
Definition chan_iax2.c:776
const ast_string_field challenge
Definition chan_iax2.c:886
const ast_string_field exten
Definition chan_iax2.c:886
ast_aes_decrypt_key dcx
Definition chan_iax2.c:900
struct iax_rr remote_rr
Definition chan_iax2.c:948
unsigned int last
Definition chan_iax2.c:782
ast_aes_encrypt_key tdcx
Definition chan_iax2.c:923
const ast_string_field ani
Definition chan_iax2.c:886
iax2_format peerformat
Definition chan_iax2.c:817
struct iax2_codec_pref rprefs
Definition chan_iax2.c:804
jitterbuf * jb
Definition chan_iax2.c:825
struct iax2_registry * reg
Definition chan_iax2.c:907
ast_aes_decrypt_key mydcx
Definition chan_iax2.c:898
const ast_string_field cid_name
Definition chan_iax2.c:886
enum iax_transfer_state transferring
Definition chan_iax2.c:915
int last_iax_message
Definition chan_iax2.c:792
int eff_auth_method
Definition chan_iax2.c:892
const ast_string_field secret
Definition chan_iax2.c:886
ast_aes_encrypt_key ecx
Definition chan_iax2.c:896
struct chan_iax2_pvt::@128 dpentries
const ast_string_field dnid
Definition chan_iax2.c:886
const ast_string_field osptoken
Definition chan_iax2.c:886
struct iax2_peer * peerpoke
Definition chan_iax2.c:909
const ast_string_field peer
Definition chan_iax2.c:886
iax2_format chosenformat
Definition chan_iax2.c:815
iax2_format capability
Definition chan_iax2.c:4685
char username[80]
Definition chan_iax2.c:4694
struct iax2_codec_pref prefs
Definition chan_iax2.c:4687
char timezone[80]
Definition chan_iax2.c:4697
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
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
Definition file.c:70
char order[IAX2_CODEC_PREF_SIZE]
Definition codec_pref.h:36
char context[AST_MAX_CONTEXT]
Definition chan_iax2.c:517
struct iax2_context * next
Definition chan_iax2.c:518
struct iax2_dpcache::@130 cache_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 iax2_dpcache::@131 peer_list
struct timeval orig
Definition chan_iax2.c:1096
char peercontext[AST_MAX_CONTEXT]
Definition chan_iax2.c:1094
const ast_string_field peercontext
Definition chan_iax2.c:623
const ast_string_field mohinterpret
Definition chan_iax2.c:623
int pokefreqok
Definition chan_iax2.c:648
struct ast_sockaddr addr
Definition chan_iax2.c:626
struct ast_dnsmgr_entry * dnsmgr
Definition chan_iax2.c:625
const ast_string_field cid_num
Definition chan_iax2.c:623
const ast_string_field inkeys
Definition chan_iax2.c:623
const ast_string_field outkey
Definition chan_iax2.c:623
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 pokefreqnotok
Definition chan_iax2.c:649
int historicms
Definition chan_iax2.c:650
int authmethods
Definition chan_iax2.c:635
const ast_string_field regexten
Definition chan_iax2.c:623
const ast_string_field mohsuggest
Definition chan_iax2.c:623
const ast_string_field username
Definition chan_iax2.c:623
const ast_string_field zonetag
Definition chan_iax2.c:623
struct ast_sockaddr defaddr
Definition chan_iax2.c:634
uint16_t maxcallno
Definition chan_iax2.c:652
const ast_string_field description
Definition chan_iax2.c:623
const ast_string_field context
Definition chan_iax2.c:623
struct iax2_codec_pref prefs
Definition chan_iax2.c:624
const ast_string_field parkinglot
Definition chan_iax2.c:623
uint64_t flags
Definition chan_iax2.c:631
const ast_string_field dbsecret
Definition chan_iax2.c:623
struct ast_sockaddr mask
Definition chan_iax2.c:629
int encmethods
Definition chan_iax2.c:636
struct ast_endpoint * endpoint
Definition chan_iax2.c:659
int pokeexpire
Definition chan_iax2.c:644
int formats
Definition chan_iax2.c:627
struct ast_acl_list * acl
Definition chan_iax2.c:656
const ast_string_field name
Definition chan_iax2.c:623
const ast_string_field cid_name
Definition chan_iax2.c:623
int smoothing
Definition chan_iax2.c:651
const ast_string_field secret
Definition chan_iax2.c:623
const ast_string_field mailbox
Definition chan_iax2.c:623
unsigned char buf[1]
Definition chan_iax2.c:1130
struct iax2_pkt_buf::@132 entry
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
enum iax_reg_state regstate
Definition chan_iax2.c:715
struct iax2_registry::@127 entry
char username[80]
Definition chan_iax2.c:711
char secret[80]
Definition chan_iax2.c:712
struct ast_sockaddr us
Definition chan_iax2.c:718
struct ast_sockaddr addr
Definition chan_iax2.c:1164
unsigned char readbuf[4096]
Definition chan_iax2.c:1148
ast_cond_t cond
Definition chan_iax2.c:1155
struct iax2_thread::@133 list
ast_cond_t init_cond
Definition chan_iax2.c:1157
time_t checktime
Definition chan_iax2.c:1153
unsigned char stop
Definition chan_iax2.c:1172
struct iax2_thread::@134 ffinfo
unsigned char csub
Definition chan_iax2.c:1166
pthread_t threadid
Definition chan_iax2.c:1145
unsigned short callno
Definition chan_iax2.c:1163
struct ast_sockaddr ioaddr
Definition chan_iax2.c:1147
ast_mutex_t init_lock
Definition chan_iax2.c:1156
struct iax2_thread::@135 full_frames
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
const void * scheddata
Definition chan_iax2.c:1139
size_t buf_size
Definition chan_iax2.c:1151
enum iax2_thread_type type
Definition chan_iax2.c:1135
void(* schedfunc)(const void *)
Definition chan_iax2.c:1138
char curfunc[80]
Definition chan_iax2.c:1142
ssize_t buf_len
Definition chan_iax2.c:1150
struct ast_sockaddr addr
Definition chan_iax2.c:667
struct timeval lasttxtime
Definition chan_iax2.c:670
unsigned int lastsent
Definition chan_iax2.c:672
struct timeval rxtrunktime
Definition chan_iax2.c:669
unsigned int trunkdataalloc
Definition chan_iax2.c:676
struct iax2_trunk_peer::@126 list
unsigned int trunkdatalen
Definition chan_iax2.c:675
unsigned char * trunkdata
Definition chan_iax2.c:674
struct timeval trunkact
Definition chan_iax2.c:671
ast_mutex_t lock
Definition chan_iax2.c:665
struct timeval txtrunktime
Definition chan_iax2.c:668
const ast_string_field mohinterpret
Definition chan_iax2.c:585
struct ast_variable * vars
Definition chan_iax2.c:598
const ast_string_field language
Definition chan_iax2.c:585
const ast_string_field cid_num
Definition chan_iax2.c:585
const ast_string_field inkeys
Definition chan_iax2.c:585
struct iax2_context * contexts
Definition chan_iax2.c:597
enum calltoken_peer_enum calltoken_required
Definition chan_iax2.c:599
iax2_format capability
Definition chan_iax2.c:592
int authmethods
Definition chan_iax2.c:587
const ast_string_field mohsuggest
Definition chan_iax2.c:585
const ast_string_field accountcode
Definition chan_iax2.c:585
struct iax2_codec_pref prefs
Definition chan_iax2.c:595
const ast_string_field parkinglot
Definition chan_iax2.c:585
uint64_t flags
Definition chan_iax2.c:591
const ast_string_field dbsecret
Definition chan_iax2.c:585
int encmethods
Definition chan_iax2.c:588
int maxauthreq
Definition chan_iax2.c:593
int curauthreq
Definition chan_iax2.c:594
struct ast_acl_list * acl
Definition chan_iax2.c:596
const ast_string_field name
Definition chan_iax2.c:585
const ast_string_field cid_name
Definition chan_iax2.c:585
int amaflags
Definition chan_iax2.c:589
const ast_string_field secret
Definition chan_iax2.c:585
unsigned char semirand[32]
Definition parser.h:138
struct iax_frame::@148 list
unsigned short dcallno
Definition parser.h:102
unsigned int final
Definition parser.h:120
unsigned int sentyet
Definition parser.h:116
int retrans
Definition parser.h:130
unsigned int ts
Definition parser.h:110
unsigned char afdata[0]
Definition parser.h:146
unsigned int outoforder
Definition parser.h:114
void * data
Definition parser.h:104
unsigned short callno
Definition parser.h:100
int retries
Definition parser.h:108
int encmethods
Definition parser.h:132
int iseqno
Definition parser.h:128
size_t afdatalen
Definition parser.h:144
unsigned int direction
Definition parser.h:122
ast_aes_decrypt_key mydcx
Definition parser.h:136
struct iax_frame * next
Definition parser.h:140
int datalen
Definition parser.h:106
int retrytime
Definition parser.h:112
unsigned int transfer
Definition parser.h:118
ast_aes_encrypt_key ecx
Definition parser.h:134
struct ast_frame af
Definition parser.h:142
unsigned int cacheable
Definition parser.h:124
int oseqno
Definition parser.h:126
unsigned char buf[1024]
Definition parser.h:150
struct ast_sockaddr apparent_addr
Definition parser.h:52
unsigned short adsicpe
Definition parser.h:44
unsigned int rr_jitter
Definition parser.h:75
unsigned int provver
Definition parser.h:72
unsigned char * calltokendata
Definition parser.h:85
unsigned int rr_pkts
Definition parser.h:77
struct ast_variable * vars
Definition parser.h:81
unsigned char calltoken
Definition parser.h:84
unsigned char iax_unknown
Definition parser.h:58
int calling_ani2
Definition parser.h:35
unsigned int rr_loss
Definition parser.h:76
unsigned int authmethods
Definition parser.h:47
char * challenge
Definition parser.h:49
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
unsigned int fwdesc
Definition parser.h:67
char * calling_ani
Definition parser.h:30
int calling_ton
Definition parser.h:32
char * password
Definition parser.h:38
unsigned int transferid
Definition parser.h:62
unsigned int rr_dropped
Definition parser.h:79
unsigned char causecode
Definition parser.h:57
unsigned int ospblocklength[IAX_MAX_OSPBLOCK_NUM]
Definition parser.h:83
int msgcount
Definition parser.h:59
int calling_tns
Definition parser.h:33
char * called_number
Definition parser.h:28
unsigned short callno
Definition parser.h:55
char * md5_result
Definition parser.h:50
int provverpres
Definition parser.h:74
char * language
Definition parser.h:42
char * codec_prefs
Definition parser.h:41
iax2_format format
Definition parser.h:40
unsigned int encmethods
Definition parser.h:48
unsigned short dpstatus
Definition parser.h:54
char * username
Definition parser.h:37
char * rsa_result
Definition parser.h:51
int calling_pres
Definition parser.h:34
int version
Definition parser.h:43
char * cause
Definition parser.h:56
int musiconhold
Definition parser.h:61
unsigned short refresh
Definition parser.h:53
char * serviceident
Definition parser.h:65
unsigned int rr_ooo
Definition parser.h:80
char * devicetype
Definition parser.h:64
char * rdnis
Definition parser.h:46
unsigned short rr_delay
Definition parser.h:78
char * osptokenblock[IAX_MAX_OSPBLOCK_NUM]
Definition parser.h:82
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 jitter
Definition chan_iax2.c:751
int packets
Definition chan_iax2.c:754
Global IO variables are now in a struct in order to be made threadsafe.
Definition io.c:71
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
long ms
Definition jitterbuf.h:104
void * data
Definition jitterbuf.h:102
long min
Definition jitterbuf.h:87
long current
Definition jitterbuf.h:88
long frames_in
Definition jitterbuf.h:79
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
In case you didn't read that giant block of text above the mansession_session struct,...
Definition manager.c:323
Number structure.
struct ast_sockaddr addr
Definition chan_iax2.c:1054
unsigned char reg
Definition chan_iax2.c:1061
uint16_t limit
Definition chan_iax2.c:1058
uint16_t cur
Definition chan_iax2.c:1056
Scheduler ID holder.
Definition sched.c:70
Definition sched.c:76
Definition chan_iax2.c:965
struct ast_frame f
Definition chan_iax2.c:966
struct signaling_queue_entry * next
Definition chan_iax2.c:967
structure to hold users read from phoneprov_users.conf
list of users found in the config file
int value
Definition syslog.c:37
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.
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
@ TPS_REF_DEFAULT
return a reference to a taskprocessor, create one if it does not exist
#define ast_taskprocessor_push(tps, task_exe, datap)
int done
static struct test_val a
static struct test_val c
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
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition time.h:117
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
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition extconf.c:2280
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition extconf.c:2295
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
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition time.h:235
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
Definition timing.c:154
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
Definition timing.c:171
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
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
Definition timing.c:161
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
int error(const char *format,...)
#define ast_test_flag(p, flag)
Definition utils.h:64
#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:981
#define ast_set2_flag64(p, value, flag)
Definition utils.h:171
#define ast_test_flag64(p, flag)
Definition utils.h:140
#define ast_assert(a)
Definition utils.h:779
#define ast_set_flags_to64(p, flag, value)
Definition utils.h:181
#define ast_clear_flag64(p, flag)
Definition utils.h:154
#define MIN(a, b)
Definition utils.h:252
#define ast_pthread_create_background(a, b, c, d)
Definition utils.h:632
#define ast_assert_return(a,...)
Definition utils.h:780
#define ast_clear_flag(p, flag)
Definition utils.h:78
long int ast_random(void)
Definition utils.c:2348
#define ast_pthread_create_detached(a, b, c, d)
Definition utils.h:628
#define ast_copy_flags64(dest, src, flagz)
Definition utils.h:161
#define ast_set_flag64(p, flag)
Definition utils.h:147
#define ast_set_flag(p, flag)
Definition utils.h:71
#define ARRAY_LEN(a)
Definition utils.h:706
void ast_sha1_hash(char *output, const char *input)
Produces SHA1 hash based on input string.
Definition utils.c:266

◆ 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)

Definition at line 409 of file chan_iax2.c.

◆ IAX_CAPABILITY_LOWFREE

#define IAX_CAPABILITY_LOWFREE
Value:
~AST_FORMAT_G723)

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.

467 { \
468 int idx; \
469 char digest[33] = ""; \
470 \
471 if (!iaxdebug) \
472 break; \
473 \
474 for (idx = 0; idx < 16; idx++) \
475 sprintf(digest + (idx << 1), "%02hhx", (unsigned char) key[idx]); \
476 \
477 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
478 } while(0)

◆ 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};

◆ 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};

◆ callno_type

Enumerator
CALLNO_TYPE_NORMAL 
CALLNO_TYPE_TRUNK 

Definition at line 970 of file chan_iax2.c.

970 {
973};

◆ 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};

◆ 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};

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

◆ iax2_thread_type

Enumerator
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 1122 of file chan_iax2.c.

1122 {
1125};

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

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

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}

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, ast_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, ast_frame::uint32, 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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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 15109 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}

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}

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}

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}

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

14737{
14738 int x;
14739
14742
14743 ast_manager_unregister("IAXpeers");
14744 ast_manager_unregister("IAXpeerlist");
14745 ast_manager_unregister("IAXnetstats");
14746 ast_manager_unregister("IAXregistry");
14751
14753 pthread_cancel(netthreadid);
14754 pthread_kill(netthreadid, SIGURG);
14755 pthread_join(netthreadid, NULL);
14756 }
14757
14758 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14759 if (iaxs[x]) {
14760 iax2_destroy(x);
14761 }
14762 }
14763
14764 /* Call for all threads to halt */
14768
14771 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14772 if (iaxs[x]) {
14773 iax2_destroy(x);
14774 }
14775 }
14776 ast_manager_unregister( "IAXpeers" );
14777 ast_manager_unregister( "IAXpeerlist" );
14778 ast_manager_unregister( "IAXnetstats" );
14779 ast_manager_unregister( "IAXregistry" );
14784 delete_users();
14787
14788 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14790 }
14791
14792 ao2_ref(peers, -1);
14793 ao2_ref(users, -1);
14798 if (timer) {
14800 timer = NULL;
14801 }
14803
14806 sched = NULL;
14807 ao2_ref(peercnts, -1);
14808
14810 ast_unload_realtime("iaxpeers");
14811
14814 return 0;
14815}

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 15109 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}

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

14603{
14604 struct chan_iax2_pvt *pvt;
14605 unsigned int callno;
14606 int res = 0;
14607
14608 if (!chan || ast_channel_tech(chan) != &iax2_tech) {
14609 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
14610 return -1;
14611 }
14612
14615 if (!(pvt = iaxs[callno])) {
14617 return -1;
14618 }
14619
14620 if (!strcasecmp(args, "osptoken")) {
14621 ast_copy_string(buf, pvt->osptoken, buflen);
14622 } else if (!strcasecmp(args, "peerip")) {
14624 } else if (!strcasecmp(args, "peername")) {
14625 ast_copy_string(buf, pvt->username, buflen);
14626 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
14627 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
14628 } else {
14629 res = -1;
14630 }
14631
14633
14634 return res;
14635}

References chan_iax2_pvt::addr, args, 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}

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}

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}

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

Referenced by acl_change_stasis_subscribe(), and rtp_reload().

◆ acl_change_stasis_subscribe()

static void acl_change_stasis_subscribe ( void  )
static

◆ acl_change_stasis_unsubscribe()

static void acl_change_stasis_unsubscribe ( void  )
static

Definition at line 1552 of file chan_iax2.c.

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}

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}

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}

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}

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}

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}

References iax2_context::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,
7662 iaxs[x]->remote_rr.losscnt,
7663 iaxs[x]->remote_rr.losspct,
7664 iaxs[x]->remote_rr.dropped,
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,
7684 iaxs[x]->remote_rr.losscnt,
7685 iaxs[x]->remote_rr.losspct,
7686 iaxs[x]->remote_rr.dropped,
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}

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, chan_iax2_pvt::frames_received, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, chan_iax2_pvt::last_iax_message, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, MARK_IAX_SUBCLASS_TX, jb_info::min, iax_rr::ooo, chan_iax2_pvt::owner, iax_rr::packets, chan_iax2_pvt::pingtime, and chan_iax2_pvt::remote_rr.

Referenced by handle_cli_iax2_show_netstats(), and manager_iax2_show_netstats().

◆ 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}

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 15109 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}

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}

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}

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}

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}

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}

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}

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_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}

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_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}

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}

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}

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(), and iax2_context::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}

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}

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);
13068 ast_string_field_set(peer,context,"");
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")) {
13085 ast_string_field_set(peer, mailbox, v->value);
13086 } else if (!strcasecmp(v->name, "mohinterpret")) {
13088 } else if (!strcasecmp(v->name, "mohsuggest")) {
13090 } else if (!strcasecmp(v->name, "dbsecret")) {
13091 ast_string_field_set(peer, dbsecret, v->value);
13092 } else if (!strcasecmp(v->name, "description")) {
13093 ast_string_field_set(peer, description, v->value);
13094 } else if (!strcasecmp(v->name, "trunk")) {
13096 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
13097 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
13099 }
13100 } else if (!strcasecmp(v->name, "auth")) {
13102 if (peer->authmethods & IAX_AUTH_PLAINTEXT) {
13103 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);
13104 }
13105 } else if (!strcasecmp(v->name, "encryption")) {
13107 if (!peer->encmethods) {
13109 }
13110 } else if (!strcasecmp(v->name, "forceencryption")) {
13111 if (ast_false(v->value)) {
13113 } else {
13115 if (peer->encmethods) {
13117 }
13118 }
13119 } else if (!strcasecmp(v->name, "transfer")) {
13120 if (!strcasecmp(v->value, "mediaonly")) {
13122 } else if (ast_true(v->value)) {
13124 } else
13126 } else if (!strcasecmp(v->name, "jitterbuffer")) {
13128 } else if (!strcasecmp(v->name, "host")) {
13129 if (!strcasecmp(v->value, "dynamic")) {
13130 /* They'll register with us */
13132 if (!found) {
13133 int peer_port = ast_sockaddr_port(&peer->addr);
13134 if (peer_port) {
13135 ast_sockaddr_set_port(&peer->defaddr, peer_port);
13136 }
13137 ast_sockaddr_setnull(&peer->addr);
13138 }
13139 } else {
13140 /* Non-dynamic. Make sure we become that way if we're not */
13141 AST_SCHED_DEL(sched, peer->expire);
13143 if (peer->dnsmgr) {
13144 // Make sure we refresh dnsmgr if we're using it
13146 } else {
13147 // Or just invalidate the address
13148 peer->addr.ss.ss_family = AST_AF_UNSPEC;
13149 }
13150 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) {
13151 return peer_unref(peer);
13152 }
13153 if (!ast_sockaddr_port(&peer->addr)) {
13155 }
13156 }
13157 } else if (!strcasecmp(v->name, "defaultip")) {
13158 struct ast_sockaddr peer_defaddr_tmp;
13159 peer_defaddr_tmp.ss.ss_family = AF_UNSPEC;
13160 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
13161 return peer_unref(peer);
13162 }
13163 ast_sockaddr_set_port(&peer_defaddr_tmp, ast_sockaddr_port(&peer->defaddr));
13164 ast_sockaddr_copy(&peer->defaddr, &peer_defaddr_tmp);
13165 } else if (!strcasecmp(v->name, "sourceaddress")) {
13166 peer_set_srcaddr(peer, v->value);
13167 } else if (!strcasecmp(v->name, "permit") ||
13168 !strcasecmp(v->name, "deny") ||
13169 !strcasecmp(v->name, "acl")) {
13170 ast_append_acl(v->name, v->value, &peer->acl, NULL, &subscribe_acl_change);
13171 } else if (!strcasecmp(v->name, "mask")) {
13172 maskfound++;
13173 ast_sockaddr_parse(&peer->mask, v->value, 0);
13174 } else if (!strcasecmp(v->name, "context")) {
13175 ast_string_field_set(peer, context, v->value);
13176 } else if (!strcasecmp(v->name, "regexten")) {
13177 ast_string_field_set(peer, regexten, v->value);
13178 } else if (!strcasecmp(v->name, "peercontext")) {
13179 ast_string_field_set(peer, peercontext, v->value);
13180 } else if (!strcasecmp(v->name, "port")) {
13181 int bindport;
13182 if (ast_parse_arg(v->value, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535)) {
13183 bindport = IAX_DEFAULT_PORTNO;
13184 }
13185 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
13186 ast_sockaddr_set_port(&peer->defaddr, bindport);
13187 } else {
13188 ast_sockaddr_set_port(&peer->addr, bindport);
13189 }
13190 } else if (!strcasecmp(v->name, "username")) {
13191 ast_string_field_set(peer, username, v->value);
13192 } else if (!strcasecmp(v->name, "allow")) {
13193 iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
13194 } else if (!strcasecmp(v->name, "disallow")) {
13195 iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
13196 } else if (!strcasecmp(v->name, "callerid")) {
13197 if (!ast_strlen_zero(v->value)) {
13198 char name2[80];
13199 char num2[80];
13200 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
13201 ast_string_field_set(peer, cid_name, name2);
13202 ast_string_field_set(peer, cid_num, num2);
13203 } else {
13204 ast_string_field_set(peer, cid_name, "");
13205 ast_string_field_set(peer, cid_num, "");
13206 }
13208 } else if (!strcasecmp(v->name, "fullname")) {
13209 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
13211 } else if (!strcasecmp(v->name, "cid_number")) {
13212 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
13214 } else if (!strcasecmp(v->name, "sendani")) {
13216 } else if (!strcasecmp(v->name, "inkeys")) {
13217 ast_string_field_set(peer, inkeys, v->value);
13218 } else if (!strcasecmp(v->name, "outkey")) {
13219 ast_string_field_set(peer, outkey, v->value);
13220 } else if (!strcasecmp(v->name, "qualify")) {
13221 if (!strcasecmp(v->value, "no")) {
13222 peer->maxms = 0;
13223 } else if (!strcasecmp(v->value, "yes")) {
13224 peer->maxms = DEFAULT_MAXMS;
13225 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
13226 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);
13227 peer->maxms = 0;
13228 }
13229 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
13230 peer->smoothing = ast_true(v->value);
13231 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
13232 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
13233 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);
13234 }
13235 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
13236 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
13237 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);
13238 }
13239 } else if (!strcasecmp(v->name, "timezone")) {
13241 } else if (!strcasecmp(v->name, "adsi")) {
13242 peer->adsi = ast_true(v->value);
13243 } else if (!strcasecmp(v->name, "connectedline")) {
13244 if (ast_true(v->value)) {
13246 } else if (!strcasecmp(v->value, "send")) {
13249 } else if (!strcasecmp(v->value, "receive")) {
13252 } else {
13254 }
13255 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13256 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
13257 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
13258 } else {
13259 peercnt_modify((unsigned char) 1, peer->maxcallno, &peer->addr);
13260 }
13261 } else if (!strcasecmp(v->name, "requirecalltoken")) {
13262 /* default is required unless in optional ip list */
13263 if (ast_false(v->value)) {
13265 } else if (!strcasecmp(v->value, "auto")) {
13267 } else if (ast_true(v->value)) {
13269 } else {
13270 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13271 }
13272 } /* else if (strcasecmp(v->name,"type")) */
13273 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13274 v = v->next;
13275 if (!v) {
13276 v = alt;
13277 alt = NULL;
13278 }
13279 }
13280 if (!peer->authmethods)
13281 peer->authmethods = IAX_AUTH_MD5;
13283 }
13284
13285 if (!maskfound && !ast_sockaddr_isnull(&peer->addr)) {
13286 if (ast_sockaddr_is_ipv4_mapped(&peer->addr)) {
13287 ast_sockaddr_parse(&peer->mask, "::ffff:ffff:ffff", 0);
13288 } else if (ast_sockaddr_is_ipv6(&peer->addr)) {
13289 ast_sockaddr_parse(&peer->mask, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0);
13290 } else {
13291 ast_sockaddr_parse(&peer->mask, "255.255.255.255", 0);
13292 }
13293 }
13294
13295 if (oldacl) {
13296 ast_free_acl_list(oldacl);
13297 }
13298
13299 if (!ast_strlen_zero(peer->mailbox) && !peer->mwi_event_sub) {
13300 /* The MWI subscriptions exist just so the core knows we care about those
13301 * mailboxes. However, we just grab the events out of the cache when it
13302 * is time to send MWI, since it is only sent with a REGACK. */
13304 }
13305
13306 if (subscribe_acl_change) {
13308 }
13309
13310 return peer;
13311}

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

13328{
13329 struct iax2_user *user = NULL;
13330 struct iax2_context *con, *conl = NULL;
13331 struct ast_acl_list *oldacl = NULL;
13332 struct iax2_context *oldcon = NULL;
13333 int format;
13334 int firstpass=1;
13335 int oldcurauthreq = 0;
13336 int subscribe_acl_change = 0;
13337 char *varname = NULL, *varval = NULL;
13338 struct ast_variable *tmpvar = NULL;
13339
13340 if (!temponly) {
13343 firstpass = 0;
13344 }
13345
13346 if (user) {
13347 if (firstpass) {
13348 oldcurauthreq = user->curauthreq;
13349 oldacl = user->acl;
13350 oldcon = user->contexts;
13351 user->acl = NULL;
13352 user->contexts = NULL;
13353 }
13354 /* Already in the list, remove it and it will be added back (or FREE'd) */
13356 } else {
13357 user = ao2_alloc(sizeof(*user), user_destructor);
13358 }
13359
13360 if (user) {
13361 if (firstpass) {
13363 memset(user, 0, sizeof(struct iax2_user));
13364 if (ast_string_field_init(user, 32)) {
13365 user = user_unref(user);
13366 goto cleanup;
13367 }
13368 user->maxauthreq = maxauthreq;
13369 user->curauthreq = oldcurauthreq;
13370 user->prefs = prefs_global;
13371 user->capability = iax2_capability;
13372 user->encmethods = iax2_encryption;
13373 user->authmethods = iax2_authmethods;
13374 user->adsi = adsi;
13375 user->calltoken_required = CALLTOKEN_DEFAULT;
13380 ast_string_field_set(user, cid_name, "");
13381 ast_string_field_set(user, cid_num, "");
13385 }
13386 if (!v) {
13387 v = alt;
13388 alt = NULL;
13389 }
13390 while(v) {
13391 if (!strcasecmp(v->name, "context")) {
13392 con = build_context(v->value);
13393 if (con) {
13394 if (conl)
13395 conl->next = con;
13396 else
13397 user->contexts = con;
13398 conl = con;
13399 }
13400 } else if (!strcasecmp(v->name, "permit") ||
13401 !strcasecmp(v->name, "deny") ||
13402 !strcasecmp(v->name, "acl")) {
13403 ast_append_acl(v->name, v->value, &user->acl, NULL, &subscribe_acl_change);
13404 } else if (!strcasecmp(v->name, "setvar")) {
13405 varname = ast_strdupa(v->value);
13406 if ((varval = strchr(varname, '='))) {
13407 *varval = '\0';
13408 varval++;
13409 if ((tmpvar = ast_variable_new(varname, varval, ""))) {
13410 if (ast_variable_list_replace(&user->vars, tmpvar)) {
13411 tmpvar->next = user->vars;
13412 user->vars = tmpvar;
13413 }
13414 }
13415 }
13416 } else if (!strcasecmp(v->name, "allow")) {
13417 iax2_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
13418 } else if (!strcasecmp(v->name, "disallow")) {
13419 iax2_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
13420 } else if (!strcasecmp(v->name, "trunk")) {
13422 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
13423 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
13425 }
13426 } else if (!strcasecmp(v->name, "auth")) {
13427 user->authmethods = get_auth_methods(v->value);
13428 if (user->authmethods & IAX_AUTH_PLAINTEXT) {
13429 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);
13430 }
13431 } else if (!strcasecmp(v->name, "encryption")) {
13432 user->encmethods |= get_encrypt_methods(v->value);
13433 if (!user->encmethods) {
13435 }
13436 } else if (!strcasecmp(v->name, "forceencryption")) {
13437 if (ast_false(v->value)) {
13439 } else {
13440 user->encmethods |= get_encrypt_methods(v->value);
13441 if (user->encmethods) {
13443 }
13444 }
13445 } else if (!strcasecmp(v->name, "transfer")) {
13446 if (!strcasecmp(v->value, "mediaonly")) {
13448 } else if (ast_true(v->value)) {
13450 } else
13452 } else if (!strcasecmp(v->name, "codecpriority")) {
13453 if(!strcasecmp(v->value, "caller"))
13455 else if(!strcasecmp(v->value, "disabled"))
13457 else if(!strcasecmp(v->value, "reqonly")) {
13460 }
13461 } else if (!strcasecmp(v->name, "immediate")) {
13463 } else if (!strcasecmp(v->name, "jitterbuffer")) {
13465 } else if (!strcasecmp(v->name, "dbsecret")) {
13466 ast_string_field_set(user, dbsecret, v->value);
13467 } else if (!strcasecmp(v->name, "secret")) {
13468 if (!ast_strlen_zero(user->secret)) {
13469 char *old = ast_strdupa(user->secret);
13470
13471 ast_string_field_build(user, secret, "%s;%s", old, v->value);
13472 } else
13473 ast_string_field_set(user, secret, v->value);
13474 } else if (!strcasecmp(v->name, "callerid")) {
13475 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
13476 char name2[80];
13477 char num2[80];
13478 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
13479 ast_string_field_set(user, cid_name, name2);
13480 ast_string_field_set(user, cid_num, num2);
13482 } else {
13484 ast_string_field_set(user, cid_name, "");
13485 ast_string_field_set(user, cid_num, "");
13486 }
13487 } else if (!strcasecmp(v->name, "fullname")) {
13488 if (!ast_strlen_zero(v->value)) {
13489 ast_string_field_set(user, cid_name, v->value);
13491 } else {
13492 ast_string_field_set(user, cid_name, "");
13493 if (ast_strlen_zero(user->cid_num))
13495 }
13496 } else if (!strcasecmp(v->name, "cid_number")) {
13497 if (!ast_strlen_zero(v->value)) {
13498 ast_string_field_set(user, cid_num, v->value);
13500 } else {
13501 ast_string_field_set(user, cid_num, "");
13502 if (ast_strlen_zero(user->cid_name))
13504 }
13505 } else if (!strcasecmp(v->name, "accountcode")) {
13507 } else if (!strcasecmp(v->name, "mohinterpret")) {
13509 } else if (!strcasecmp(v->name, "mohsuggest")) {
13511 } else if (!strcasecmp(v->name, "parkinglot")) {
13512 ast_string_field_set(user, parkinglot, v->value);
13513 } else if (!strcasecmp(v->name, "language")) {
13515 } else if (!strcasecmp(v->name, "amaflags")) {
13516 format = ast_channel_string2amaflag(v->value);
13517 if (format < 0) {
13518 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13519 } else {
13520 user->amaflags = format;
13521 }
13522 } else if (!strcasecmp(v->name, "inkeys")) {
13523 ast_string_field_set(user, inkeys, v->value);
13524 } else if (!strcasecmp(v->name, "maxauthreq")) {
13525 user->maxauthreq = atoi(v->value);
13526 if (user->maxauthreq < 0)
13527 user->maxauthreq = 0;
13528 } else if (!strcasecmp(v->name, "adsi")) {
13529 user->adsi = ast_true(v->value);
13530 } else if (!strcasecmp(v->name, "connectedline")) {
13531 if (ast_true(v->value)) {
13533 } else if (!strcasecmp(v->value, "send")) {
13536 } else if (!strcasecmp(v->value, "receive")) {
13539 } else {
13541 }
13542 } else if (!strcasecmp(v->name, "requirecalltoken")) {
13543 /* default is required unless in optional ip list */
13544 if (ast_false(v->value)) {
13545 user->calltoken_required = CALLTOKEN_NO;
13546 } else if (!strcasecmp(v->value, "auto")) {
13547 user->calltoken_required = CALLTOKEN_AUTO;
13548 } else if (ast_true(v->value)) {
13549 user->calltoken_required = CALLTOKEN_YES;
13550 } else {
13551 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13552 }
13553 } /* else if (strcasecmp(v->name,"type")) */
13554 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13555 v = v->next;
13556 if (!v) {
13557 v = alt;
13558 alt = NULL;
13559 }
13560 }
13561 if (!user->authmethods) {
13562 if (!ast_strlen_zero(user->secret)) {
13563 user->authmethods = IAX_AUTH_MD5;
13564 if (!ast_strlen_zero(user->inkeys))
13565 user->authmethods |= IAX_AUTH_RSA;
13566 } else if (!ast_strlen_zero(user->inkeys)) {
13567 user->authmethods = IAX_AUTH_RSA;
13568 } else {
13569 user->authmethods = IAX_AUTH_MD5;
13570 }
13571 }
13573 }
13574cleanup:
13575 if (oldacl) {
13576 ast_free_acl_list(oldacl);
13577 }
13578 if (oldcon) {
13579 free_context(oldcon);
13580 }
13581
13582 if (subscribe_acl_change) {
13584 }
13585
13586 return user;
13587}

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

14208{
14209 struct ast_sockaddr addr;
14210 int x;
14211 int callno;
14212 struct iax_ie_data ied;
14213 struct create_addr_info cai;
14214 struct parsed_dial_string pds;
14215 char *tmpstr;
14216
14217 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14218 /* Look for an *exact match* call. Once a call is negotiated, it can only
14219 look up entries for a single context */
14220 if (!ast_mutex_trylock(&iaxsl[x])) {
14221 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
14222 return x;
14224 }
14225 }
14226
14227 /* No match found, we need to create a new one */
14228
14229 memset(&cai, 0, sizeof(cai));
14230 memset(&ied, 0, sizeof(ied));
14231 memset(&pds, 0, sizeof(pds));
14232
14233 tmpstr = ast_strdupa(data);
14234 parse_dial_string(tmpstr, &pds);
14235
14236 if (ast_strlen_zero(pds.peer)) {
14237 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
14238 return -1;
14239 }
14240
14241 /* Populate our address from the given */
14242 if (create_addr(pds.peer, NULL, &addr, &cai))
14243 return -1;
14244
14245 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
14246 pds.peer, pds.username, pds.password, pds.context);
14247
14248 callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
14249 if (callno < 1) {
14250 ast_log(LOG_WARNING, "Unable to create call\n");
14251 return -1;
14252 }
14253
14254 ast_string_field_set(iaxs[callno], dproot, data);
14256
14259 /* the string format is slightly different from a standard dial string,
14260 because the context appears in the 'exten' position
14261 */
14262 if (pds.exten)
14263 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
14264 if (pds.username)
14265 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
14268 /* Keep password handy */
14269 if (pds.password)
14270 ast_string_field_set(iaxs[callno], secret, pds.password);
14271 if (pds.key)
14272 ast_string_field_set(iaxs[callno], outkey, pds.key);
14273 /* Start the call going */
14274 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
14275 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
14276
14277 return callno;
14278}

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}

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}

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}

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}

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)
7957 ast_string_field_set(iaxs[callno], context, 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
8094 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
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}

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, 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_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}

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}

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

14717{
14718 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14719 struct iax2_thread_list *list_head = head;
14720 struct iax2_thread *thread;
14721
14722 AST_LIST_LOCK(list_head);
14723 while ((thread = AST_LIST_REMOVE_HEAD(list_head, list))) {
14724 pthread_t thread_id = thread->threadid;
14725
14726 thread->stop = 1;
14727 signal_condition(&thread->lock, &thread->cond);
14728
14729 AST_LIST_UNLOCK(list_head);
14730 pthread_join(thread_id, NULL);
14731 AST_LIST_LOCK(list_head);
14732 }
14733 AST_LIST_UNLOCK(list_head);
14734}

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}

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}

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}

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}

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}

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

◆ 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}

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}

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}

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}

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}

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, 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

◆ 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}

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, 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}

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}

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}

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}

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

14281{
14282 struct iax2_dpcache *dp = NULL;
14283 struct timeval now = ast_tvnow();
14284 int x, com[2], timeout, doabort, callno;
14285
14286 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
14287 if (ast_tvcmp(now, dp->expiry) > 0) {
14288 AST_LIST_REMOVE_CURRENT(cache_list);
14289 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
14290 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
14291 else
14292 ast_free(dp);
14293 continue;
14294 }
14295 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
14296 break;
14297 }
14299
14300 if (!dp) {
14301 /* No matching entry. Create a new one. */
14302 /* First, can we make a callno? */
14303 if ((callno = cache_get_callno_locked(data)) < 0) {
14304 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
14305 return NULL;
14306 }
14307 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
14308 ast_mutex_unlock(&iaxsl[callno]);
14309 return NULL;
14310 }
14311 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
14312 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
14313 dp->expiry = ast_tvnow();
14314 dp->orig = dp->expiry;
14315 /* Expires in 30 mins by default */
14316 dp->expiry.tv_sec += iaxdefaultdpcache;
14318 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
14319 dp->waiters[x] = -1;
14320 /* Insert into the lists */
14321 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
14322 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
14323 /* Send the request if we're already up */
14324 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
14325 iax2_dprequest(dp, callno);
14326 ast_mutex_unlock(&iaxsl[callno]);
14327 }
14328
14329 /* By here we must have a dp */
14330 if (dp->flags & CACHE_FLAG_PENDING) {
14331 int res;
14332 struct pollfd pfd;
14333 /* Okay, here it starts to get nasty. We need a pipe now to wait
14334 for a reply to come back so long as it's pending */
14335 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
14336 /* Find an empty slot */
14337 if (dp->waiters[x] < 0)
14338 break;
14339 }
14340 if (x >= ARRAY_LEN(dp->waiters)) {
14341 ast_log(LOG_WARNING, "No more waiter positions available\n");
14342 return NULL;
14343 }
14344 if (pipe(com)) {
14345 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
14346 return NULL;
14347 }
14348 dp->waiters[x] = com[1];
14349 /* Okay, now we wait */
14350 timeout = iaxdefaulttimeout * 1000;
14351 /* Temporarily unlock */
14353 doabort = 0;
14354
14355 /* chan is in autoservice here, so do NOT service it here! */
14356 pfd.fd = com[0];
14357 pfd.events = POLLIN;
14358 pfd.revents = 0;
14359 /* Wait for pipe activity... if the channel hangs up, we'll catch it on the way out. */
14360 res = ast_poll(&pfd, 1, timeout);
14361 if (res < 0) {
14362 ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
14363 return NULL;
14364 } else if (!pfd.revents) {
14365 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
14366 }
14367
14368 if (chan && ast_check_hangup(chan)) {
14369 doabort = 1;
14370 }
14371
14373 dp->waiters[x] = -1;
14374 close(com[1]);
14375 close(com[0]);
14376 if (doabort) {
14377 /* Don't interpret anything, just abort. */
14378 return NULL;
14379 }
14380 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
14381 /* Now to do non-independent analysis the results of our wait */
14382 if (dp->flags & CACHE_FLAG_PENDING) {
14383 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer
14384 pending. Don't let it take as long to timeout. */
14385 dp->flags &= ~CACHE_FLAG_PENDING;
14387 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded
14388 systems without leaving it unavailable once the server comes back online */
14389 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
14390 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
14391 if (dp->waiters[x] > -1) {
14392 if (write(dp->waiters[x], "asdf", 4) < 0) {
14393 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
14394 }
14395 }
14396 }
14397 }
14398 }
14399 /* Our caller will obtain the rest */
14400 }
14401 return dp;
14402}

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}

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}

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}

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}

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

14526{
14527 struct iax2_peer *peer;
14528 char *peername, *colname;
14529
14530 peername = ast_strdupa(data);
14531
14532 /* if our channel, return the IP address of the endpoint of current channel */
14533 if (!strcmp(peername,"CURRENTCHANNEL")) {
14534 unsigned short callno;
14535 if (!chan || ast_channel_tech(chan) != &iax2_tech) {
14536 return -1;
14537 }
14540 return 0;
14541 }
14542
14543 if ((colname = strchr(peername, ',')))
14544 *colname++ = '\0';
14545 else
14546 colname = "ip";
14547
14548 if (!(peer = find_peer(peername, 1)))
14549 return -1;
14550
14551 if (!strcasecmp(colname, "ip")) {
14553 } else if (!strcasecmp(colname, "status")) {
14554 peer_status(peer, buf, len);
14555 } else if (!strcasecmp(colname, "mailbox")) {
14556 ast_copy_string(buf, peer->mailbox, len);
14557 } else if (!strcasecmp(colname, "context")) {
14558 ast_copy_string(buf, peer->context, len);
14559 } else if (!strcasecmp(colname, "expire")) {
14560 snprintf(buf, len, "%d", peer->expire);
14561 } else if (!strcasecmp(colname, "dynamic")) {
14562 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
14563 } else if (!strcasecmp(colname, "callerid_name")) {
14565 } else if (!strcasecmp(colname, "callerid_num")) {
14566 ast_copy_string(buf, peer->cid_num, len);
14567 } else if (!strcasecmp(colname, "codecs")) {
14568 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
14569
14570 iax2_getformatname_multiple(peer->capability, &codec_buf);
14571 ast_copy_string(buf, ast_str_buffer(codec_buf), len);
14572 } else if (!strncasecmp(colname, "codec[", 6)) {
14573 char *codecnum, *ptr;
14574 struct ast_format *tmpfmt;
14575
14576 /* skip over "codec" to the '[' */
14577 codecnum = colname + 5;
14578 *codecnum = '\0';
14579 codecnum++;
14580 if ((ptr = strchr(codecnum, ']'))) {
14581 *ptr = '\0';
14582 }
14583 if((iax2_codec_pref_index(&peer->prefs, atoi(codecnum), &tmpfmt))) {
14585 } else {
14586 buf[0] = '\0';
14587 }
14588 } else {
14589 buf[0] = '\0';
14590 }
14591
14592 peer_unref(peer);
14593
14594 return 0;
14595}

References iax2_peer::addr, 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}

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}

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}

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}

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}

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}

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

14185{
14186 switch (cmd) {
14187 case CLI_INIT:
14188 e->command = "iax2 reload";
14189 e->usage =
14190 "Usage: iax2 reload\n"
14191 " Reloads IAX configuration from iax.conf\n";
14192 return NULL;
14193 case CLI_GENERATE:
14194 return NULL;
14195 }
14196
14197 reload_config(0);
14198
14199 return CLI_SUCCESS;
14200}

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}

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}

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}

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}

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}

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}

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, chan_iax2_pvt::callno, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, jb_info::current, iax_rr::delay, chan_iax2_pvt::first_iax_message, FORMAT, FORMAT2, iax2_getformatname(), iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::iseqno, jb_getinfo(), jb_info::jitter, chan_iax2_pvt::last_iax_message, MARK_IAX_SUBCLASS_TX, jb_info::min, NULL, chan_iax2_pvt::oseqno, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, 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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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
5332 ast_string_field_set(iaxs[callno], context, ast_channel_context(c));
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
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}

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

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

References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, CACHE_FLAG_CANEXIST, 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}

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}

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}

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}

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}

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

14639{
14640 struct parsed_dial_string pds;
14641 char *tmp = ast_strdupa(data);
14642 struct iax2_peer *p;
14643 int res = AST_DEVICE_INVALID;
14644
14645 memset(&pds, 0, sizeof(pds));
14646 parse_dial_string(tmp, &pds);
14647
14648 if (ast_strlen_zero(pds.peer)) {
14649 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
14650 return res;
14651 }
14652
14653 ast_debug(3, "Checking device state for device %s\n", pds.peer);
14654
14655 /* SLD: FIXME: second call to find_peer during registration */
14656 if (!(p = find_peer(pds.peer, 1)))
14657 return res;
14658
14660
14661 ast_debug(3, "Found peer. What's device state of %s? addr=%s, defaddr=%s maxms=%d, lastms=%d\n",
14663
14664 if (((!ast_sockaddr_isnull(&p->addr)) || (!ast_sockaddr_isnull(&p->defaddr))) &&
14665 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
14666 /* Peer is registered, or have default IP address
14667 and a valid registration */
14668 if (p->historicms == 0 || p->historicms <= p->maxms)
14669 /* let the core figure out whether it is in use or not */
14670 res = AST_DEVICE_UNKNOWN;
14671 }
14672
14673 peer_unref(p);
14674
14675 return res;
14676}

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}

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}

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}

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

14475{
14476 char odata[256];
14477 char req[sizeof(odata) + AST_MAX_CONTEXT + AST_MAX_EXTENSION + sizeof("IAX2//@")];
14478 char *ncontext;
14479 struct iax2_dpcache *dp = NULL;
14480 struct ast_app *dial = NULL;
14481#if 0
14482 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);
14483#endif
14484 if (priority == 2) {
14485 /* Indicate status, can be overridden in dialplan */
14486 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
14487 if (dialstatus) {
14488 dial = pbx_findapp(dialstatus);
14489 if (dial)
14490 pbx_exec(chan, dial, "");
14491 }
14492 return -1;
14493 } else if (priority != 1)
14494 return -1;
14495
14497 if ((dp = find_cache(chan, data, context, exten, priority))) {
14498 if (dp->flags & CACHE_FLAG_EXISTS) {
14499 ast_copy_string(odata, data, sizeof(odata));
14500 ncontext = strchr(odata, '/');
14501 if (ncontext) {
14502 *ncontext = '\0';
14503 ncontext++;
14504 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
14505 } else {
14506 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
14507 }
14508 ast_verb(3, "Executing Dial('%s')\n", req);
14509 } else {
14511 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
14512 return -1;
14513 }
14514 }
14516
14517 if ((dial = pbx_findapp("Dial")))
14518 return pbx_exec(chan, dial, req);
14519 else
14520 ast_log(LOG_WARNING, "No dial application registered\n");
14521
14522 return -1;
14523}

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_verb, CACHE_FLAG_EXISTS, 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 14405 of file chan_iax2.c.

14406{
14407 int res = 0;
14408 struct iax2_dpcache *dp = NULL;
14409#if 0
14410 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14411#endif
14412 if ((priority != 1) && (priority != 2))
14413 return 0;
14414
14416 if ((dp = find_cache(chan, data, context, exten, priority))) {
14417 if (dp->flags & CACHE_FLAG_EXISTS)
14418 res = 1;
14419 } else {
14420 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14421 }
14423
14424 return res;
14425}

References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, CACHE_FLAG_EXISTS, 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

◆ 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}

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}

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}

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}

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}

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}

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

14452{
14453 int res = 0;
14454 struct iax2_dpcache *dp = NULL;
14455#if 0
14456 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14457#endif
14458 if ((priority != 1) && (priority != 2))
14459 return 0;
14460
14462 if ((dp = find_cache(chan, data, context, exten, priority))) {
14463 if (dp->flags & CACHE_FLAG_MATCHMORE)
14464 res = 1;
14465 } else {
14466 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14467 }
14469
14470 return res;
14471}

References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, CACHE_FLAG_MATCHMORE, 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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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

◆ iax2_sched_add()

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

◆ iax2_sched_replace()

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

Definition at line 1753 of file chan_iax2.c.

1755{
1756 return ast_sched_replace(id, con, when, callback, data);
1757}

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
6773 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag64(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO));
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}

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}

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}

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
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}

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, ast_option_header::flag, IAX_FORCE_ENCRYPT, iaxs, iaxsl, ast_option_header::option, 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}

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, 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}

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}

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}

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}

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}

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}

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}

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}

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}

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}

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

14964{
14965 static const char config[] = "iax.conf";
14966 int x = 0;
14967 struct iax2_registry *reg = NULL;
14968
14971 }
14973
14974 if (load_objects()) {
14978 }
14979
14980 memset(iaxs, 0, sizeof(iaxs));
14981
14982 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14983 ast_mutex_init(&iaxsl[x]);
14984 }
14985
14986 if (!(sched = ast_sched_context_create())) {
14987 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14991 }
14992
14997 sched = NULL;
14999 }
15000
15001 if (!(io = io_context_create())) {
15002 ast_log(LOG_ERROR, "Failed to create I/O context\n");
15006 sched = NULL;
15008 }
15009
15010 if (!(netsock = ast_netsock_list_alloc())) {
15011 ast_log(LOG_ERROR, "Failed to create netsock list\n");
15016 sched = NULL;
15018 }
15020
15022 if (!outsock) {
15023 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
15028 sched = NULL;
15030 }
15032
15034
15038
15039 if ((timer = ast_timer_open())) {
15041 }
15042
15043 if (set_config(config, 0, 0) == -1) {
15044 if (timer) {
15046 timer = NULL;
15047 }
15050 }
15051
15053
15055
15058
15063
15065 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
15068 }
15069
15071 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
15072 }
15073
15074 if (start_network_thread()) {
15075 ast_log(LOG_ERROR, "Unable to start network thread\n");
15078 } else {
15079 ast_verb(2, "IAX Ready and Listening\n");
15080 }
15081
15084 iax2_do_register(reg);
15086
15089
15090
15093
15094 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
15095
15097
15099}

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

14871{
14874
14877 if (!peers) {
14878 goto container_fail;
14879 }
14880
14883 if (!users) {
14884 goto container_fail;
14885 }
14886
14889 if (!iax_peercallno_pvts) {
14890 goto container_fail;
14891 }
14892
14896 goto container_fail;
14897 }
14898
14901 if (!peercnts) {
14902 goto container_fail;
14903 }
14904
14907 if (!callno_limits) {
14908 goto container_fail;
14909 }
14910
14913 if (!calltoken_ignores) {
14914 goto container_fail;
14915 }
14916
14917 if (create_callno_pools()) {
14918 goto container_fail;
14919 }
14920
14922 if (!transmit_processor) {
14923 goto container_fail;
14924 }
14925
14926 return 0;
14927
14928container_fail:
14929 if (peers) {
14930 ao2_ref(peers, -1);
14931 }
14932 if (users) {
14933 ao2_ref(users, -1);
14934 }
14935 if (iax_peercallno_pvts) {
14937 }
14940 }
14941 if (peercnts) {
14942 ao2_ref(peercnts, -1);
14943 }
14944 if (callno_limits) {
14946 }
14947 if (calltoken_ignores) {
14949 }
14950 return -1;
14951}

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}

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}

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(), 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}

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}

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}

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}

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

Referenced by network_change_stasis_subscribe().

◆ network_change_stasis_subscribe()

static void network_change_stasis_subscribe ( void  )
static

◆ 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}

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}

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}

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}

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

13590{
13591 struct iax2_peer *peer = obj;
13592
13594
13595 return 0;
13596}

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}

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}

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

14825{
14826 struct iax2_peer *peer = obj;
14827
14828 if (peer->sockfd < 0)
14829 peer->sockfd = defaultsockfd;
14830
14831 return 0;
14832}

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}

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}

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}

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}

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

14142{
14143 struct ao2_iterator i;
14144 struct iax2_peer *peer;
14145
14146 i = ao2_iterator_init(peers, 0);
14147 while ((peer = ao2_iterator_next(&i))) {
14148 iax2_poke_peer(peer, 0);
14149 peer_unref(peer);
14150 }
14152}

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

13653{
13654 struct iax2_peer *peer;
13655 struct ao2_iterator i;
13656
13657 i = ao2_iterator_init(peers, 0);
13658 while ((peer = ao2_iterator_next(&i))) {
13660 unlink_peer(peer);
13661 }
13662 peer_unref(peer);
13663 }
13665}

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

13637{
13638 struct iax2_user *user;
13639 struct ao2_iterator i;
13640
13641 i = ao2_iterator_init(users, 0);
13642 while ((user = ao2_iterator_next(&i))) {
13645 }
13647 }
13649}

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_unlink, ast_test_flag64, IAX_DELME, IAX_RTCACHEFRIENDS, 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 14841 of file chan_iax2.c.

14842{
14843 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14844
14845 /* The frames_received field is used to hold whether we're matching
14846 * against a full frame or not ... */
14847
14848 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14849 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14850}

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}

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

14835{
14836 const struct chan_iax2_pvt *pvt = obj;
14837
14838 return pvt->peercallno;
14839}

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}

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}

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}

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}

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, 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}

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}

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}

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}

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

14203{
14204 return reload_config(0);
14205}

References reload_config().

Referenced by set_config().

◆ reload_config()

static int reload_config ( int  forced_reload)
static

◆ 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}

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}

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}

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

◆ 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}

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}

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

◆ 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}

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}

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}

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 */
9614 fr->direction = DIRECTION_OUTGRESS;
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}

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

13685{
13686 struct ast_config *cfg;
13687 iax2_format capability;
13688 struct ast_variable *v;
13689 char *cat;
13690 const char *utype;
13691 const char *tosval;
13692 int format;
13693 int portno = IAX_DEFAULT_PORTNO;
13694 int x;
13695 int mtuv;
13696 int subscribe_network_change = 1;
13697 struct iax2_user *user;
13698 struct iax2_peer *peer;
13699 struct ast_netsock *ns;
13700 struct ast_flags config_flags = { (reload && !forced) ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13701 struct ast_sockaddr bindaddr;
13702 struct iax2_codec_pref prefs_new;
13703
13704 cfg = ast_config_load(config_file, config_flags);
13705
13706 if (!cfg) {
13707 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13708 return -1;
13709 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13711 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13712 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13713 return 0;
13714 }
13715 if (!cfg) {
13716 /* should have been able to load the config here */
13717 ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file);
13718 return -1;
13719 }
13720 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13721 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13722 return 0;
13723 } else { /* iax.conf changed */
13725 }
13726
13727 if (reload) {
13729 }
13730
13731 ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0);
13732
13733 /* Setup new codec prefs */
13735
13736 /* Reset Global Flags */
13737 memset(&globalflags, 0, sizeof(globalflags));
13740
13741#ifdef SO_NO_CHECK
13742 nochecksums = 0;
13743#endif
13744 /* Reset default parking lot */
13745 default_parkinglot[0] = '\0';
13746
13752
13753 maxauthreq = 3;
13754
13755 srvlookup = 0;
13756 iax2_authmethods = 0;
13757
13758 v = ast_variable_browse(cfg, "general");
13759
13760 /* Seed initial tos value */
13761 tosval = ast_variable_retrieve(cfg, "general", "tos");
13762 if (tosval) {
13763 if (ast_str2tos(tosval, &qos.tos))
13764 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13765 }
13766 /* Seed initial cos value */
13767 tosval = ast_variable_retrieve(cfg, "general", "cos");
13768 if (tosval) {
13769 if (ast_str2cos(tosval, &qos.cos))
13770 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13771 }
13772 while(v) {
13773 if (!strcasecmp(v->name, "bindport")) {
13774 if (reload) {
13775 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13776 }
13777 else if (ast_parse_arg(v->value, PARSE_UINT32 | PARSE_IN_RANGE, &portno, 1024, 65535)) {
13778 portno = IAX_DEFAULT_PORTNO;
13779 }
13780 } else if (!strcasecmp(v->name, "pingtime")){
13781 ping_time = atoi(v->value);
13782 }
13783 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13784 if (reload) {
13785 if (atoi(v->value) != iaxthreadcount)
13786 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13787 } else {
13788 iaxthreadcount = atoi(v->value);
13789 if (iaxthreadcount < 1) {
13790 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13791 iaxthreadcount = 1;
13792 } else if (iaxthreadcount > 256) {
13793 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13794 iaxthreadcount = 256;
13795 }
13796 }
13797 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13798 if (reload) {
13800 iaxmaxthreadcount = atoi(v->value);
13802 } else {
13803 iaxmaxthreadcount = atoi(v->value);
13804 if (iaxmaxthreadcount < 0) {
13805 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13807 } else if (iaxmaxthreadcount > 256) {
13808 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13809 iaxmaxthreadcount = 256;
13810 }
13811 }
13812 } else if (!strcasecmp(v->name, "nochecksums")) {
13813#ifdef SO_NO_CHECK
13814 if (ast_true(v->value))
13815 nochecksums = 1;
13816 else
13817 nochecksums = 0;
13818#else
13819 if (ast_true(v->value))
13820 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13821#endif
13822 }
13823 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13824 maxjitterbuffer = atoi(v->value);
13825 else if (!strcasecmp(v->name, "resyncthreshold"))
13826 resyncthreshold = atoi(v->value);
13827 else if (!strcasecmp(v->name, "maxjitterinterps"))
13828 maxjitterinterps = atoi(v->value);
13829 else if (!strcasecmp(v->name, "jittertargetextra"))
13830 jittertargetextra = atoi(v->value);
13831 else if (!strcasecmp(v->name, "lagrqtime"))
13832 lagrq_time = atoi(v->value);
13833 else if (!strcasecmp(v->name, "maxregexpire"))
13834 max_reg_expire = atoi(v->value);
13835 else if (!strcasecmp(v->name, "minregexpire"))
13836 min_reg_expire = atoi(v->value);
13837 else if (!strcasecmp(v->name, "bindaddr")) {
13838 if (reload) {
13839 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13840 } else {
13841
13842 if (!ast_parse_arg(v->value, PARSE_ADDR, NULL)) {
13843
13845
13846 if (!ast_sockaddr_port(&bindaddr)) {
13848 }
13849
13850 if (!(ns = ast_netsock_bindaddr(netsock, io, &bindaddr, qos.tos, qos.cos, socket_read, NULL))) {
13851 ast_log(LOG_WARNING, "Unable to apply binding to '%s' at line %d\n", v->value, v->lineno);
13852 } else {
13853 ast_verb(2, "Binding IAX2 to address %s\n", ast_sockaddr_stringify(&bindaddr));
13854
13855 if (defaultsockfd < 0) {
13857 }
13859 }
13860
13861 } else {
13862 ast_log(LOG_WARNING, "Invalid address '%s' specified, at line %d\n", v->value, v->lineno);
13863 }
13864 }
13865 } else if (!strcasecmp(v->name, "auth")) {
13868 ast_log(LOG_WARNING, "Default auth method is set to deprecated 'plaintext' at line %d of iax.conf\n", v->lineno);
13869 }
13870 } else if (!strcasecmp(v->name, "authdebug")) {
13871 authdebug = ast_true(v->value);
13872 } else if (!strcasecmp(v->name, "encryption")) {
13874 if (!iax2_encryption) {
13876 }
13877 } else if (!strcasecmp(v->name, "forceencryption")) {
13878 if (ast_false(v->value)) {
13880 } else {
13882 if (iax2_encryption) {
13884 }
13885 }
13886 } else if (!strcasecmp(v->name, "transfer")) {
13887 if (!strcasecmp(v->value, "mediaonly")) {
13889 } else if (ast_true(v->value)) {
13891 } else
13893 } else if (!strcasecmp(v->name, "codecpriority")) {
13894 if(!strcasecmp(v->value, "caller"))
13896 else if(!strcasecmp(v->value, "disabled"))
13898 else if(!strcasecmp(v->value, "reqonly")) {
13901 }
13902 } else if (!strcasecmp(v->name, "jitterbuffer"))
13904 else if (!strcasecmp(v->name, "delayreject"))
13906 else if (!strcasecmp(v->name, "allowfwdownload"))
13908 else if (!strcasecmp(v->name, "rtcachefriends"))
13910 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13912 else if (!strcasecmp(v->name, "rtupdate"))
13914 else if (!strcasecmp(v->name, "rtsavesysname"))
13916 else if (!strcasecmp(v->name, "trunktimestamps"))
13918 else if (!strcasecmp(v->name, "rtautoclear")) {
13919 int i = atoi(v->value);
13920 if(i > 0)
13922 else
13923 i = 0;
13925 } else if (!strcasecmp(v->name, "trunkfreq")) {
13926 trunkfreq = atoi(v->value);
13927 if (trunkfreq < 10) {
13928 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n");
13929 trunkfreq = 10;
13930 } else if (trunkfreq > 1000) {
13931 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n");
13932 trunkfreq = 1000;
13933 }
13934 if (timer) {
13936 }
13937 } else if (!strcasecmp(v->name, "trunkmtu")) {
13938 mtuv = atoi(v->value);
13939 if (mtuv == 0 )
13941 else if (mtuv >= 172 && mtuv < 4000)
13942 global_max_trunk_mtu = mtuv;
13943 else
13944 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13945 mtuv, v->lineno);
13946 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13947 trunkmaxsize = atoi(v->value);
13948 if (trunkmaxsize == 0)
13950 } else if (!strcasecmp(v->name, "autokill")) {
13951 if (sscanf(v->value, "%30d", &x) == 1) {
13952 if (x >= 0)
13953 autokill = x;
13954 else
13955 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13956 } else if (ast_true(v->value)) {
13958 } else {
13959 autokill = 0;
13960 }
13961 } else if (!strcasecmp(v->name, "bandwidth")) {
13962 if (!strcasecmp(v->value, "low")) {
13963 capability = iax2_codec_pref_from_bitfield(&prefs_new,
13965 } else if (!strcasecmp(v->value, "medium")) {
13966 capability = iax2_codec_pref_from_bitfield(&prefs_new,
13968 } else if (!strcasecmp(v->value, "high")) {
13969 capability = iax2_codec_pref_from_bitfield(&prefs_new,
13971 } else {
13972 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13973 }
13974 } else if (!strcasecmp(v->name, "allow")) {
13975 iax2_parse_allow_disallow(&prefs_new, &capability, v->value, 1);
13976 } else if (!strcasecmp(v->name, "disallow")) {
13977 iax2_parse_allow_disallow(&prefs_new, &capability, v->value, 0);
13978 } else if (!strcasecmp(v->name, "register")) {
13979 iax2_register(v->value, v->lineno);
13980 } else if (!strcasecmp(v->name, "iaxcompat")) {
13981 iaxcompat = ast_true(v->value);
13982 } else if (!strcasecmp(v->name, "regcontext")) {
13984 /* Create context if it doesn't exist already */
13986 } else if (!strcasecmp(v->name, "tos")) {
13987 if (ast_str2tos(v->value, &qos.tos))
13988 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13989 } else if (!strcasecmp(v->name, "cos")) {
13990 if (ast_str2cos(v->value, &qos.cos))
13991 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13992 } else if (!strcasecmp(v->name, "parkinglot")) {
13994 } else if (!strcasecmp(v->name, "accountcode")) {
13996 } else if (!strcasecmp(v->name, "mohinterpret")) {
13998 } else if (!strcasecmp(v->name, "mohsuggest")) {
14000 } else if (!strcasecmp(v->name, "amaflags")) {
14001 format = ast_channel_string2amaflag(v->value);
14002 if (format < 0) {
14003 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
14004 } else {
14005 amaflags = format;
14006 }
14007 } else if (!strcasecmp(v->name, "language")) {
14008 ast_copy_string(language, v->value, sizeof(language));
14009 } else if (!strcasecmp(v->name, "maxauthreq")) {
14010 maxauthreq = atoi(v->value);
14011 if (maxauthreq < 0)
14012 maxauthreq = 0;
14013 } else if (!strcasecmp(v->name, "adsi")) {
14014 adsi = ast_true(v->value);
14015 } else if (!strcasecmp(v->name, "srvlookup")) {
14016 srvlookup = ast_true(v->value);
14017 } else if (!strcasecmp(v->name, "connectedline")) {
14018 if (ast_true(v->value)) {
14020 } else if (!strcasecmp(v->value, "send")) {
14023 } else if (!strcasecmp(v->value, "receive")) {
14026 } else {
14028 }
14029 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
14030 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
14031 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
14032 }
14033 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
14034 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
14035 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);
14036 }
14037 } else if (!strcasecmp(v->name, "calltokenoptional")) {
14038 if (add_calltoken_ignore(v->value)) {
14039 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
14040 return -1;
14041 }
14042 } else if (!strcasecmp(v->name, "calltokenexpiration")) {
14043 int temp = -1;
14044 sscanf(v->value, "%u", &temp);
14045 if( temp <= 0 ){
14046 ast_log(LOG_WARNING, "Invalid calltokenexpiration value %s. Should be integer greater than 0.\n", v->value);
14047 } else {
14048 max_calltoken_delay = temp;
14049 }
14050 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
14051 if (ast_true(v->value)) {
14052 subscribe_network_change = 1;
14053 } else if (ast_false(v->value)) {
14054 subscribe_network_change = 0;
14055 } else {
14056 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
14057 }
14058 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
14059 if (ast_true(v->value)) {
14061 } else if (ast_false(v->value)) {
14063 } else {
14064 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
14065 }
14066 }/*else if (strcasecmp(v->name,"type")) */
14067 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
14068 v = v->next;
14069 }
14070
14071 if (subscribe_network_change) {
14073 } else {
14075 }
14076
14077 if (defaultsockfd < 0) {
14078
14080
14081 if (!(ns = ast_netsock_bindaddr(netsock, io, &bindaddr, qos.tos, qos.cos, socket_read, NULL))) {
14082 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
14083 } else {
14084 ast_verb(2, "Binding IAX2 to default address %s\n", ast_sockaddr_stringify(&bindaddr));
14087 }
14088 }
14089 if (reload) {
14092 if (!outsock) {
14093 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14094 return -1;
14095 }
14097 }
14098
14100 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
14103 }
14104 prefs_global = prefs_new;
14105 iax2_capability = capability;
14106
14107 cat = ast_category_browse(cfg, NULL);
14108 while(cat) {
14109 if (strcasecmp(cat, "general")) {
14110 utype = ast_variable_retrieve(cfg, cat, "type");
14111 if (!strcasecmp(cat, "callnumberlimits")) {
14113 } else if (utype) {
14114 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
14115 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
14116 if (user) {
14118 user = user_unref(user);
14119 }
14120 }
14121 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
14122 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
14123 if (peer) {
14124 if (ast_test_flag64(peer, IAX_DYNAMIC))
14125 reg_source_db(peer);
14126 ao2_link(peers, peer);
14127 peer = peer_unref(peer);
14128 }
14129 } else if (strcasecmp(utype, "user")) {
14130 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
14131 }
14132 } else
14133 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
14134 }
14135 cat = ast_category_browse(cfg, cat);
14136 }
14137 ast_config_destroy(cfg);
14138 return 1;
14139}

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_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, 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_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}

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

◆ 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}

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 {
10371 f.subclass.integer = uncompress_subclass(fh->csub);
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",
11592 iax2_getformatname(iaxs[fr->callno]->peerformat),
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>",
11870 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->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>",
11883 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->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}

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, ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::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, ast_channel::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(), 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, ast_iax2_mini_hdr::ts, ast_iax2_video_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(), chan_iax2_pvt::voiceformat, and ast_iax2_video_hdr::zeros.

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}

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, 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}

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, 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}

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, 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}

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}

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

14860{
14861 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14862
14863 /* The frames_received field is used to hold whether we're matching
14864 * against a full frame or not ... */
14865
14866 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14867 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14868}

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

14853{
14854 const struct chan_iax2_pvt *pvt = obj;
14855
14856 return pvt->transfercallno;
14857}

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}

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

◆ 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}

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}

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}

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}

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

13599{
13600 struct iax2_user *user = obj;
13601
13603
13604 return 0;
13605}

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

◆ user_destructor()

static void user_destructor ( void *  obj)
static

Definition at line 13313 of file chan_iax2.c.

13314{
13315 struct iax2_user *user = obj;
13316
13317 ast_free_acl_list(user->acl);
13318 free_context(user->contexts);
13319 if(user->vars) {
13321 user->vars = NULL;
13322 }
13324}

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}

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 = ASTERISK_GPL_KEY , .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 15109 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

◆ adsi

int adsi = 0
static

◆ amaflags

int amaflags = 0
static

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

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

423 {
424 [0] = "none",
425 [IAX_AUTH_PLAINTEXT] = "plaintext",
426 [IAX_AUTH_MD5] = "MD5",
427 [IAX_AUTH_RSA] = "RSA",
428};

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 = AST_MUTEX_INIT_VALUE
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 14688 of file chan_iax2.c.

14688 {
14689 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
14690 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
14691 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
14692 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
14693 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
14694 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
14695 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
14696 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
14697 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
14698 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
14699 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
14700 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
14701 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
14702 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
14703 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
14704 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
14705 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
14706 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
14707 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
14708 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
14709#ifdef IAXTESTS
14710 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
14711 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
14712 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
14713#endif /* IAXTESTS */
14714};

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

◆ dynamic_list

◆ first

struct iax_frame* first

Definition at line 1005 of file chan_iax2.c.

◆ [struct]

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

14679{
14680 .name = "IAX2",
14681 .description = "IAX Remote Dialplan Switch",
14682 .exists = iax2_exists,
14683 .canmatch = iax2_canmatch,
14684 .exec = iax2_exec,
14685 .matchmore = iax2_matchmore,
14686};

Referenced by __unload_module(), and load_module().

◆ iax2_tech

struct ast_channel_tech iax2_tech
static

Definition at line 1366 of file chan_iax2.c.

1366 {
1367 .type = "IAX2",
1368 .description = tdesc,
1369 .properties = AST_CHAN_TP_WANTSJITTER,
1370 .requester = iax2_request,
1371 .devicestate = iax2_devicestate,
1372 .send_digit_begin = iax2_digit_begin,
1373 .send_digit_end = iax2_digit_end,
1374 .send_text = iax2_sendtext,
1375 .send_image = iax2_sendimage,
1376 .send_html = iax2_sendhtml,
1377 .call = iax2_call,
1378 .hangup = iax2_hangup,
1379 .answer = iax2_answer,
1380 .read = iax2_read,
1381 .write = iax2_write,
1382 .write_video = iax2_write,
1383 .indicate = iax2_indicate,
1384 .setoption = iax2_setoption,
1385 .queryoption = iax2_queryoption,
1386 .transfer = iax2_transfer,
1387 .fixup = iax2_fixup,
1388 .func_channel_read = acf_channel_read,
1389};

Referenced by __unload_module(), acf_channel_read(), ast_iax2_new(), function_iaxpeer(), iax2_prov_app(), and load_module().

◆ iax2_variable_datastore_info

const struct ast_datastore_info iax2_variable_datastore_info
static
Initial value:
= {
.type = "IAX2_VARIABLE",
}

Definition at line 1595 of file chan_iax2.c.

1595 {
1596 .type = "IAX2_VARIABLE",
1597 .duplicate = iax2_dup_variable_datastore,
1599};

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",
}

Definition at line 14597 of file chan_iax2.c.

14597 {
14598 .name = "IAXPEER",
14599 .read = function_iaxpeer,
14600};

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,
}

Definition at line 10238 of file chan_iax2.c.

10238 {
10239 .name = "IAXVAR",
10240 .read = acf_iaxvar_read,
10241 .write = acf_iaxvar_write,
10242};

Referenced by load_module(), and unload_module().

◆ idle_list

◆ 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]

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

◆ 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

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