Wed Apr 6 11:29:56 2011

Asterisk developer's documentation


chan_iax2.c File Reference

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

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

Go to the source code of this file.

Data Structures

struct  active_list
struct  addr_range
struct  callno_entry
struct  chan_iax2_pvt
struct  chan_iax2_pvt::signaling_queue
struct  create_addr_info
struct  dpcache
struct  dpreq_data
struct  dynamic_list
struct  firmwares
struct  iax2_context
struct  iax2_dpcache
struct  iax2_peer
struct  iax2_pkt_buf
struct  iax2_registry
struct  iax2_thread
struct  iax2_trunk_peer
struct  iax2_user
struct  iax_dual
struct  iax_firmware
struct  iax_rr
struct  idle_list
struct  parsed_dial_string
struct  peercnt
struct  registrations
struct  signaling_queue_entry
struct  tpeers

Defines

#define ACN_FORMAT1   "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
#define ACN_FORMAT2   "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
#define CALLNO_TO_PTR(a)   ((void *)(unsigned long)(a))
#define CALLTOKEN_HASH_FORMAT   "%s%d%u%d"
#define CALLTOKEN_IE_FORMAT   "%u?%s"
#define DATA_EXPORT_IAX2_PEER(MEMBER)
#define DATA_EXPORT_IAX2_USER(MEMBER)
#define DEBUG_SCHED_MULTITHREAD
#define DEBUG_SUPPORT
#define DEFAULT_CONTEXT   "default"
#define DEFAULT_DROP   3
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAX_THREAD_COUNT   100
#define DEFAULT_MAXMS   2000
#define DEFAULT_RETRY_TIME   1000
#define DEFAULT_THREAD_COUNT   10
#define DEFAULT_TRUNKDATA   640 * 10
#define DONT_RESCHEDULE   -2
#define FORMAT   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n"
#define FORMAT   "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
#define FORMAT   "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n"
#define FORMAT   "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
#define FORMAT2   "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
#define FORMAT2   "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
#define FORMAT2   "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n"
#define FORMAT2   "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
#define FORMATB   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
#define GAMMA   (0.01)
#define IAX2_TRUNK_PREFACE   (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
#define IAX_ALLOWFWDOWNLOAD   (uint64_t)(1 << 26)
#define IAX_ALREADYGONE   (uint64_t)(1 << 9)
#define IAX_CALLENCRYPTED(pvt)   (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED))
#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
#define IAX_CAPABILITY_LOWBANDWIDTH
#define IAX_CAPABILITY_LOWFREE
#define IAX_CAPABILITY_MEDBANDWIDTH
#define IAX_CODEC_NOCAP   (uint64_t)(1 << 16)
#define IAX_CODEC_NOPREFS   (uint64_t)(1 << 15)
#define IAX_CODEC_USER_FIRST   (uint64_t)(1 << 14)
#define IAX_DEBUGDIGEST(msg, key)
#define IAX_DELAYPBXSTART   (uint64_t)(1 << 25)
#define IAX_DELME   (uint64_t)(1 << 1)
#define IAX_DYNAMIC   (uint64_t)(1 << 6)
#define IAX_ENCRYPTED   (uint64_t)(1 << 12)
#define IAX_FORCE_ENCRYPT   (uint64_t)(1 << 30)
#define IAX_FORCEJITTERBUF   (uint64_t)(1 << 20)
#define IAX_HASCALLERID   (uint64_t)(1 << 0)
#define IAX_IMMEDIATE   (uint64_t)(1 << 27)
#define IAX_KEYPOPULATED   (uint64_t)(1 << 13)
#define IAX_MAXAUTHREQ   (uint64_t)(1 << 24)
#define IAX_NOTRANSFER   (uint64_t)(1 << 4)
#define IAX_PROVISION   (uint64_t)(1 << 10)
#define IAX_QUELCH   (uint64_t)(1 << 11)
#define IAX_RECVCONNECTEDLINE   (uint64_t)(1 << 29)
#define IAX_RTAUTOCLEAR   (uint64_t)(1 << 19)
#define IAX_RTCACHEFRIENDS   (uint64_t)(1 << 17)
#define IAX_RTIGNOREREGEXPIRE   (uint64_t)(1 << 21)
#define IAX_RTSAVE_SYSNAME   (uint64_t)(1 << 8)
#define IAX_RTUPDATE   (uint64_t)(1 << 18)
#define IAX_SENDANI   (uint64_t)(1 << 7)
#define IAX_SENDCONNECTEDLINE   (uint64_t)(1 << 28)
#define IAX_SHRINKCALLERID   (uint64_t)(1 << 31)
#define IAX_TEMPONLY   (uint64_t)(1 << 2)
#define IAX_TRANSFERMEDIA   (uint64_t)(1 << 23)
#define IAX_TRUNK   (uint64_t)(1 << 3)
#define IAX_TRUNKTIMESTAMPS   (uint64_t)(1 << 22)
#define IAX_USEJITTERBUF   (uint64_t)(1 << 5)
#define MARK_IAX_SUBCLASS_TX   0x8000
#define MAX_JITTER_BUFFER   50
#define MAX_PEER_BUCKETS   563
#define MAX_RETRY_TIME   10000
#define MAX_TIMESTAMP_SKEW   160
#define MAX_TRUNK_MTU   1240
 Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240.
#define MAX_TRUNKDATA   640 * 200
#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS
#define MEMORY_SIZE   100
#define MIN_JITTER_BUFFER   10
#define MIN_RETRY_TIME   100
#define MIN_REUSE_TIME   60
#define PTR_TO_CALLNO(a)   ((unsigned short)(unsigned long)(a))
#define SCHED_MULTITHREADED
#define schedule_action(func, data)   __schedule_action(func, data, __PRETTY_FUNCTION__)
#define TRUNK_CALL_START   IAX_MAX_CALLS / 2
#define TS_GAP_FOR_JB_RESYNC   5000

Enumerations

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

Functions

static void __attempt_transmit (const void *data)
static void __auth_reject (const void *nothing)
static void __auto_congest (const void *nothing)
static void __auto_hangup (const void *nothing)
static int __do_deliver (void *data)
static void __expire_registry (const void *data)
static int __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
static void __get_from_jb (const void *p)
static void __iax2_do_register_s (const void *data)
static void __iax2_poke_noanswer (const void *data)
static void __iax2_poke_peer_s (const void *data)
static int __iax2_show_peers (int 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 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 int add_calltoken_ignore (const char *addr)
static void add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
static int addr_range_cmp_cb (void *obj, void *arg, int flags)
static int addr_range_delme_cb (void *obj, void *arg, int flags)
static int addr_range_hash_cb (const void *obj, const int flags)
static int addr_range_match_address_cb (void *obj, void *arg, int flags)
static int apply_context (struct iax2_context *con, const char *context)
static int ast_cli_netstats (struct mansession *s, int fd, int limit_fmt)
 AST_DATA_STRUCTURE (iax2_user, DATA_EXPORT_IAX2_USER)
 AST_DATA_STRUCTURE (iax2_peer, DATA_EXPORT_IAX2_PEER)
static struct ast_channelast_iax2_new (int callno, int state, format_t capability, const char *linkedid)
 Create new call, interface with the PBX core.
static int attempt_transmit (const void *data)
static int auth_fail (int callno, int failcode)
static int auth_reject (const void *data)
static int authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt)
static int authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
static int authenticate_request (int call_num)
static int authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies)
static int auto_congest (const void *data)
static int auto_hangup (const void *data)
static void build_callno_limits (struct ast_variable *v)
static struct iax2_contextbuild_context (const char *context)
static void build_ecx_key (const unsigned char *digest, struct chan_iax2_pvt *pvt)
static void build_encryption_keys (const unsigned char *digest, struct chan_iax2_pvt *pvt)
static struct iax2_peerbuild_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
 Create peer structure based on configuration.
static void build_rand_pad (unsigned char *buf, ssize_t len)
static struct iax2_userbuild_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
 Create in-memory user structure from configuration.
static int cache_get_callno_locked (const char *data)
static unsigned int calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset)
static unsigned int calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
static unsigned int calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
static int callno_hash (const void *obj, const int flags)
static int calltoken_required (struct sockaddr_in *sin, const char *name, int subclass)
static int check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies)
static int check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
static int check_srcaddr (struct sockaddr *sa, socklen_t salen)
 Check if address can be used as packet source.
static void cleanup_thread_list (void *head)
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 (format_t subclass)
static void construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
static int create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
static int create_callno_pools (void)
static int decode_frame (ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static int decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static void defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here)
 Queue the last read full frame for processing by a certain thread.
static void delete_users (void)
static void destroy_firmware (struct iax_firmware *cur)
static void dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
static void * dp_lookup_thread (void *data)
static void encmethods_to_str (int e, struct ast_str *buf)
static int encrypt_frame (ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
static int expire_registry (const void *data)
static struct iax2_dpcachefind_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
static int find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame)
static int find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame)
static struct iax2_threadfind_idle_thread (void)
static struct iax2_peerfind_peer (const char *name, int realtime)
static struct iax2_trunk_peerfind_tpeer (struct sockaddr_in *sin, int fd)
static struct iax2_userfind_user (const char *name)
static unsigned int fix_peerts (struct timeval *rxtrunktime, int callno, unsigned int ts)
static void free_context (struct iax2_context *con)
static void free_signaling_queue_entry (struct signaling_queue_entry *s)
static int function_iaxpeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int get_auth_methods (const char *value)
static int get_encrypt_methods (const char *s)
static int get_from_jb (const void *p)
static struct callno_entryget_unused_callno (int trunk, int validated)
static int handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct sockaddr_in *sin, int fd)
static char * handle_cli_iax2_provision (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_debug_jb (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_debug_trunk (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_mtu (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Set trunk MTU from CLI.
static char * handle_cli_iax2_show_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_callno_limits (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_firmware (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_netstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show one peer in detail.
static char * handle_cli_iax2_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_test_losspct (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void handle_deferred_full_frames (struct iax2_thread *thread)
 Handle any deferred full frames for this thread.
static int handle_error (void)
static int iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno)
 Acknowledgment received for OUR registration.
static int attribute_pure iax2_allow_new (int frametype, int subclass, int inbound)
static void iax2_ami_channelupdate (struct chan_iax2_pvt *pvt)
 Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers.
static int iax2_answer (struct ast_channel *c)
static int iax2_append_register (const char *hostname, const char *username, const char *secret, const char *porta)
static enum ast_bridge_result iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
static int iax2_call (struct ast_channel *c, char *dest, int timeout)
static int iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 part of the IAX2 dial plan switch interface
static unsigned int iax2_datetime (const char *tz)
static void iax2_destroy (int callno)
static void iax2_destroy_helper (struct chan_iax2_pvt *pvt)
static int iax2_devicestate (void *data)
 Part of the device state notification system ---.
static int iax2_digit_begin (struct ast_channel *c, char digit)
static int iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration)
static int iax2_do_register (struct iax2_registry *reg)
static int iax2_do_register_s (const void *data)
static void iax2_dprequest (struct iax2_dpcache *dp, int callno)
static void * iax2_dup_variable_datastore (void *)
static int iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Execute IAX2 dialplan switch.
static int iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 switch interface.
static int iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan)
static void iax2_frame_free (struct iax_frame *fr)
static void iax2_free_variable_datastore (void *)
static int iax2_getpeername (struct sockaddr_in sin, char *host, int len)
static int iax2_getpeertrunk (struct sockaddr_in sin)
static int iax2_hangup (struct ast_channel *c)
static int iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen)
static int iax2_key_rotate (const void *vpvt)
static 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_poke_noanswer (const void *data)
static int iax2_poke_peer (struct iax2_peer *peer, int heldcall)
static int iax2_poke_peer_cb (void *obj, void *arg, int flags)
static int iax2_poke_peer_s (const void *data)
static int iax2_predestroy (int callno)
static void * iax2_process_thread (void *data)
static void iax2_process_thread_cleanup (void *data)
static int iax2_prov_app (struct ast_channel *chan, const char *data)
static int iax2_provision (struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
static int iax2_queryoption (struct ast_channel *c, int option, void *data, int *datalen)
static int iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen)
 Queue a control frame on the ast_channel owner.
static int iax2_queue_frame (int callno, struct ast_frame *f)
 Queue a frame to a call's owning asterisk channel.
static int iax2_queue_hangup (int callno)
 Queue a hangup frame on the ast_channel owner.
static struct ast_frameiax2_read (struct ast_channel *c)
static int iax2_register (const char *value, int lineno)
static struct ast_channeliax2_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static int iax2_sched_add (struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data)
static int iax2_sched_replace (int id, struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data)
static int iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
static int iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen)
static int iax2_sendimage (struct ast_channel *c, struct ast_frame *img)
static int iax2_sendtext (struct ast_channel *c, const char *text)
static int iax2_setoption (struct ast_channel *c, int option, void *data, int datalen)
static int iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly)
static int iax2_transfer (struct ast_channel *c, const char *dest)
static int iax2_transmit (struct iax_frame *fr)
static int iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now)
static int iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr)
static int iax2_vnak (int callno)
static int iax2_write (struct ast_channel *c, struct ast_frame *f)
static int iax_check_version (char *dev)
static void iax_debug_output (const char *data)
static void iax_error_output (const char *data)
static int iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
static void iax_outputframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
static int iax_park (struct ast_channel *chan1, struct ast_channel *chan2, const char *parkexten)
static void * iax_park_thread (void *stuff)
static struct iax_frameiaxfrdup2 (struct iax_frame *fr)
static void insert_idle_thread (struct iax2_thread *thread)
static void jb_debug_output (const char *fmt,...)
static void jb_error_output (const char *fmt,...)
static void jb_warning_output (const char *fmt,...)
static int load_module (void)
 Load IAX2 module, load configuraiton ---.
static int load_objects (void)
static void lock_both (unsigned short callno0, unsigned short callno1)
static void log_jitterstats (unsigned short callno)
static int make_trunk (unsigned short callno, int locked)
static int manager_iax2_show_netstats (struct mansession *s, const struct message *m)
static int manager_iax2_show_peer_list (struct mansession *s, const struct message *m)
 callback to display iax peers in manager format
static int manager_iax2_show_peers (struct mansession *s, const struct message *m)
 callback to display iax peers in manager
static int manager_iax2_show_registry (struct mansession *s, const struct message *m)
static int match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
static void memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
static void memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
static void merge_encryption (struct chan_iax2_pvt *p, unsigned int enc)
static void mwi_event_cb (const struct ast_event *event, void *userdata)
static void network_change_event_cb (const struct ast_event *, void *)
static int network_change_event_sched_cb (const void *data)
static void network_change_event_subscribe (void)
static void network_change_event_unsubscribe (void)
static void * network_thread (void *ignore)
static struct chan_iax2_pvtnew_iax (struct sockaddr_in *sin, const char *host)
static void parse_dial_string (char *data, struct parsed_dial_string *pds)
 Parses an IAX dial string into its component parts.
static int peer_cmp_cb (void *obj, void *arg, int flags)
static int peer_delme_cb (void *obj, void *arg, int flags)
static void peer_destructor (void *obj)
static int peer_hash_cb (const void *obj, const int flags)
static struct iax2_peerpeer_ref (struct iax2_peer *peer)
static int peer_set_sock_cb (void *obj, void *arg, int flags)
static int peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr)
 Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found.
static int peer_status (struct iax2_peer *peer, char *status, int statuslen)
 peer_status: Report Peer status in character string
static struct iax2_peerpeer_unref (struct iax2_peer *peer)
static int peercnt_add (struct sockaddr_in *sin)
static int peercnt_cmp_cb (void *obj, void *arg, int flags)
static int peercnt_hash_cb (const void *obj, const int flags)
static void peercnt_modify (unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
static void peercnt_remove (struct peercnt *peercnt)
static int peercnt_remove_by_addr (struct sockaddr_in *sin)
static int peercnt_remove_cb (const void *obj)
static int peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root)
static void poke_all_peers (void)
static int prune_addr_range_cb (void *obj, void *arg, int flags)
static void prune_peers (void)
static void prune_users (void)
static int pvt_cmp_cb (void *obj, void *arg, int flags)
static void pvt_destructor (void *obj)
static int pvt_hash_cb (const void *obj, const int flags)
static int queue_signalling (struct chan_iax2_pvt *pvt, struct ast_frame *f)
 All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.
static int raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
static struct iax2_peerrealtime_peer (const char *peername, struct sockaddr_in *sin)
static void realtime_update_peer (const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
static struct iax2_userrealtime_user (const char *username, struct sockaddr_in *sin)
static void reg_source_db (struct iax2_peer *p)
static void register_peer_exten (struct iax2_peer *peer, int onoff)
static int register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies)
 Verify inbound registration.
static int registry_authrequest (int callno)
static int registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin)
static char * regstate2str (int regstate)
static int reload (void)
static int reload_config (void)
static void reload_firmware (int unload)
static void remove_by_peercallno (struct chan_iax2_pvt *pvt)
static void remove_by_transfercallno (struct chan_iax2_pvt *pvt)
static int replace_callno (const void *obj)
static void requirecalltoken_mark_auto (const char *name, int subclass)
static void resend_with_token (int callno, struct iax_frame *f, const char *newtoken)
static void save_osptoken (struct iax_frame *fr, struct iax_ies *ies)
static void save_rr (struct iax_frame *fr, struct iax_ies *ies)
static void sched_delay_remove (struct sockaddr_in *sin, struct callno_entry *callno_entry)
static int schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
static int scheduled_destroy (const void *vid)
static int send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno, int sockfd, struct iax_ie_data *ied)
static int send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int)
static int send_lagrq (const void *data)
static int send_packet (struct iax_frame *f)
static int send_ping (const void *data)
static void send_signaling (struct chan_iax2_pvt *pvt)
 This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.
static int send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now)
static int set_config (const char *config_file, int reload)
 Load configuration.
static void set_config_destroy (void)
static void set_hangup_source_and_cause (int callno, unsigned char causecode)
static void set_peercnt_limit (struct peercnt *peercnt)
static int set_peercnt_limit_all_cb (void *obj, void *arg, int flags)
static void signal_condition (ast_mutex_t *lock, ast_cond_t *cond)
static int socket_process (struct iax2_thread *thread)
static int socket_process_meta (int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd, struct iax_frame *fr)
static int socket_read (int *id, int fd, short events, void *cbdata)
static void spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid)
static int start_network_thread (void)
static void stop_stuff (int callno)
static void store_by_peercallno (struct chan_iax2_pvt *pvt)
static void store_by_transfercallno (struct chan_iax2_pvt *pvt)
static int timing_read (int *id, int fd, short events, void *cbdata)
static int transfercallno_pvt_cmp_cb (void *obj, void *arg, int flags)
static int transfercallno_pvt_hash_cb (const void *obj, const int flags)
static int transmit_frame (void *data)
static int transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
static int try_firmware (char *s)
static int try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static format_t uncompress_subclass (unsigned char csub)
static void unlink_peer (struct iax2_peer *peer)
static int unload_module (void)
static void unlock_both (unsigned short callno0, unsigned short callno1)
static void unwrap_timestamp (struct iax_frame *fr)
static void update_jbsched (struct chan_iax2_pvt *pvt)
static void update_max_nontrunk (void)
static void update_max_trunk (void)
static int update_packet (struct iax_frame *f)
static int update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
static int user_cmp_cb (void *obj, void *arg, int flags)
static int user_delme_cb (void *obj, void *arg, int flags)
static void user_destructor (void *obj)
static int user_hash_cb (const void *obj, const int flags)
static struct iax2_useruser_ref (struct iax2_user *user)
static struct iax2_useruser_unref (struct iax2_user *user)
static int users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root)
static void vnak_retransmit (int callno, int last)
static int wait_for_peercallno (struct chan_iax2_pvt *pvt)

Variables

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


Detailed Description

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

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

Definition in file chan_iax2.c.


Define Documentation

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

Referenced by ast_cli_netstats().

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

Referenced by ast_cli_netstats().

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

Definition at line 238 of file chan_iax2.c.

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

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

Referenced by handle_call_token().

#define CALLTOKEN_IE_FORMAT   "%u?%s"

Referenced by handle_call_token().

#define DATA_EXPORT_IAX2_PEER ( MEMBER   ) 

Definition at line 14393 of file chan_iax2.c.

#define DATA_EXPORT_IAX2_USER ( MEMBER   ) 

Definition at line 14470 of file chan_iax2.c.

#define DEBUG_SCHED_MULTITHREAD

Definition at line 230 of file chan_iax2.c.

#define DEBUG_SUPPORT

Definition at line 246 of file chan_iax2.c.

#define DEFAULT_CONTEXT   "default"

Definition at line 265 of file chan_iax2.c.

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

#define DEFAULT_DROP   3

Definition at line 244 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

Definition at line 340 of file chan_iax2.c.

Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().

#define DEFAULT_FREQ_OK   60 * 1000

Definition at line 339 of file chan_iax2.c.

Referenced by build_peer().

#define DEFAULT_MAX_THREAD_COUNT   100

Definition at line 241 of file chan_iax2.c.

#define DEFAULT_MAXMS   2000

Definition at line 338 of file chan_iax2.c.

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

#define DEFAULT_RETRY_TIME   1000

Definition at line 242 of file chan_iax2.c.

Referenced by __find_callno(), and complete_transfer().

#define DEFAULT_THREAD_COUNT   10

Definition at line 240 of file chan_iax2.c.

#define DEFAULT_TRUNKDATA   640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 619 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

#define DONT_RESCHEDULE   -2

Definition at line 362 of file chan_iax2.c.

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

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

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

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

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

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

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

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

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

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

#define GAMMA   (0.01)

Definition at line 251 of file chan_iax2.c.

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

Definition at line 540 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

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

Allow the FWDOWNL command?

Definition at line 428 of file chan_iax2.c.

Referenced by set_config(), and socket_process().

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

Already disconnected

Definition at line 411 of file chan_iax2.c.

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

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

Definition at line 343 of file chan_iax2.c.

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

#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF

Definition at line 317 of file chan_iax2.c.

Referenced by cache_get_callno_locked(), and set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH

Value:

Definition at line 329 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWFREE

Value:

Definition at line 334 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH

Definition at line 319 of file chan_iax2.c.

Referenced by set_config().

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

only consider requested format and ignore capabilities

Definition at line 418 of file chan_iax2.c.

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

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

Force old behaviour by turning off prefs

Definition at line 417 of file chan_iax2.c.

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

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

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

Definition at line 416 of file chan_iax2.c.

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

#define IAX_DEBUGDIGEST ( msg,
key   ) 

Definition at line 346 of file chan_iax2.c.

Referenced by iax2_key_rotate(), and socket_process().

#define IAX_DELAYPBXSTART   (uint64_t)(1 << 25)

Don't start a PBX on the channel until the peer sends us a response, so that we've achieved a three-way handshake with them before sending voice or anything else

Definition at line 427 of file chan_iax2.c.

Referenced by socket_process().

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

Needs to be deleted

Definition at line 403 of file chan_iax2.c.

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

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

dynamic peer

Definition at line 408 of file chan_iax2.c.

Referenced by __iax2_show_peers(), build_peer(), function_iaxpeer(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), peers_data_provider_get(), register_verify(), and set_config().

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

Whether we should assume encrypted tx/rx

Definition at line 414 of file chan_iax2.c.

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

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

Forces call encryption, if encryption not possible hangup

Definition at line 432 of file chan_iax2.c.

Referenced by __find_callno(), authenticate_reply(), authenticate_verify(), build_peer(), build_user(), check_access(), create_addr(), iax2_call(), iax2_queryoption(), iax2_setoption(), set_config(), and socket_process().

#define IAX_FORCEJITTERBUF   (uint64_t)(1 << 20)

Force jitterbuffer, even when bridged to a channel that can take jitter

Definition at line 422 of file chan_iax2.c.

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

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

CallerID has been specified

Definition at line 402 of file chan_iax2.c.

Referenced by build_peer(), build_user(), check_access(), and update_registry().

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

Allow immediate off-hook to extension s

Definition at line 429 of file chan_iax2.c.

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

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

Whether we have a key populated

Definition at line 415 of file chan_iax2.c.

Referenced by authenticate_reply(), decrypt_frame(), and iax2_send().

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

Maximum outstanding AUTHREQ restriction is in place

Definition at line 426 of file chan_iax2.c.

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

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

Don't native bridge

Definition at line 406 of file chan_iax2.c.

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

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

This is a provisioning request

Definition at line 412 of file chan_iax2.c.

Referenced by iax2_provision(), and socket_process().

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

Whether or not we quelch audio

Definition at line 413 of file chan_iax2.c.

Referenced by iax2_write(), and socket_process().

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

Allow receiving of connected line updates

Definition at line 431 of file chan_iax2.c.

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

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

erase me on expire

Definition at line 421 of file chan_iax2.c.

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

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

let realtime stay till your reload

Definition at line 419 of file chan_iax2.c.

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

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

When using realtime, ignore registration expiration

Definition at line 423 of file chan_iax2.c.

Referenced by set_config().

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

Save Systname on Realtime Updates

Definition at line 410 of file chan_iax2.c.

Referenced by realtime_update_peer(), and set_config().

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

Send a realtime update

Definition at line 420 of file chan_iax2.c.

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

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

Send ANI along with CallerID

Definition at line 409 of file chan_iax2.c.

Referenced by build_peer(), create_addr(), iax2_call(), and iax2_request().

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

Allow sending of connected line updates

Definition at line 430 of file chan_iax2.c.

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

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

Turn on and off caller id shrinking

Definition at line 433 of file chan_iax2.c.

Referenced by check_access(), and set_config().

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

Temporary (realtime)

Definition at line 404 of file chan_iax2.c.

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

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

When doing IAX2 transfers, transfer media only

Definition at line 425 of file chan_iax2.c.

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

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

Treat as a trunk

Definition at line 405 of file chan_iax2.c.

Referenced by __iax2_show_peers(), build_peer(), build_user(), check_access(), create_addr(), handle_cli_iax2_show_peer(), iax2_getpeertrunk(), iax2_request(), iax2_send(), manager_iax2_show_peer_list(), peers_data_provider_get(), and socket_process().

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

Send trunk timestamps

Definition at line 424 of file chan_iax2.c.

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

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

Use jitter buffer

Definition at line 407 of file chan_iax2.c.

Referenced by __find_callno(), ast_cli_netstats(), build_peer(), build_user(), check_access(), create_addr(), handle_cli_iax2_show_channels(), iax2_request(), log_jitterstats(), schedule_delivery(), set_config(), and set_config_destroy().

#define MARK_IAX_SUBCLASS_TX   0x8000

Definition at line 627 of file chan_iax2.c.

Referenced by ast_cli_netstats(), handle_cli_iax2_show_channels(), and iax2_send().

#define MAX_JITTER_BUFFER   50

Definition at line 616 of file chan_iax2.c.

#define MAX_PEER_BUCKETS   563

This module will get much higher performance when doing a lot of user and peer lookups if the number of buckets is increased from 1. However, to maintain old behavior for Asterisk 1.4, these are set to 1 by default. When using multiple buckets, search order through these containers is considered random, so you will not be able to depend on the order the entires are specified in iax.conf for matching order.

Definition at line 878 of file chan_iax2.c.

Referenced by load_objects().

#define MAX_RETRY_TIME   10000

Definition at line 614 of file chan_iax2.c.

Referenced by __attempt_transmit(), and iax2_send().

#define MAX_TIMESTAMP_SKEW   160

maximum difference between actual and predicted ts for sending

Definition at line 621 of file chan_iax2.c.

Referenced by ast_rtp_raw_write(), calc_timestamp(), and calc_txpeerstamp().

#define MAX_TRUNK_MTU   1240

Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240.

Definition at line 260 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_mtu(), and set_config().

#define MAX_TRUNKDATA   640 * 200

40ms, uncompressed linear * 200 channels

Definition at line 284 of file chan_iax2.c.

Referenced by set_config(), and set_config_destroy().

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

Definition at line 882 of file chan_iax2.c.

Referenced by load_module(), and load_objects().

#define MEMORY_SIZE   100

Definition at line 243 of file chan_iax2.c.

#define MIN_JITTER_BUFFER   10

Definition at line 617 of file chan_iax2.c.

#define MIN_RETRY_TIME   100

Definition at line 613 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME   60

Definition at line 248 of file chan_iax2.c.

Referenced by make_trunk(), and sched_delay_remove().

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

Definition at line 237 of file chan_iax2.c.

Referenced by __auto_congest(), __get_from_jb(), acf_channel_read(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_queryoption(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), iax2_write(), and scheduled_destroy().

#define SCHED_MULTITHREADED

Definition at line 226 of file chan_iax2.c.

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

Definition at line 1487 of file chan_iax2.c.

Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().

#define TRUNK_CALL_START   IAX_MAX_CALLS / 2

Definition at line 1093 of file chan_iax2.c.

Referenced by __find_callno(), create_callno_pools(), make_trunk(), replace_callno(), update_max_nontrunk(), and update_max_trunk().

#define TS_GAP_FOR_JB_RESYNC   5000

Definition at line 624 of file chan_iax2.c.


Enumeration Type Documentation

anonymous enum

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

Definition at line 938 of file chan_iax2.c.

00938      {
00939    /*! Extension exists */
00940    CACHE_FLAG_EXISTS      = (1 << 0),
00941    /*! Extension is nonexistent */
00942    CACHE_FLAG_NONEXISTENT = (1 << 1),
00943    /*! Extension can exist */
00944    CACHE_FLAG_CANEXIST    = (1 << 2),
00945    /*! Waiting to hear back response */
00946    CACHE_FLAG_PENDING     = (1 << 3),
00947    /*! Timed out */
00948    CACHE_FLAG_TIMEOUT     = (1 << 4),
00949    /*! Request transmitted */
00950    CACHE_FLAG_TRANSMITTED = (1 << 5),
00951    /*! Timeout */
00952    CACHE_FLAG_UNKNOWN     = (1 << 6),
00953    /*! Matchmore */
00954    CACHE_FLAG_MATCHMORE   = (1 << 7),
00955 };

anonymous enum

Enumerator:
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 1972 of file chan_iax2.c.

01972      {
01973    /* do not allow a new call number, only search ones in use for match */
01974    NEW_PREVENT = 0,
01975    /* search for match first, then allow a new one to be allocated */
01976    NEW_ALLOW = 1,
01977    /* do not search for match, force a new call number */
01978    NEW_FORCE = 2,
01979    /* do not search for match, force a new call number.  Signifies call number
01980     * has been calltoken validated */
01981    NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01982 };

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

00441                          {
00442    /*! \brief Default calltoken required unless the ip is in the ignorelist */
00443    CALLTOKEN_DEFAULT = 0,
00444    /*! \brief Require call token validation. */
00445    CALLTOKEN_YES = 1,
00446    /*! \brief Require call token validation after a successful registration
00447     *         using call token validation occurs. */
00448    CALLTOKEN_AUTO = 2,
00449    /*! \brief Do not require call token validation. */
00450    CALLTOKEN_NO = 3,
00451 };

enum iax2_state

Enumerator:
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 390 of file chan_iax2.c.

00390                 {
00391    IAX_STATE_STARTED =        (1 << 0),
00392    IAX_STATE_AUTHENTICATED =  (1 << 1),
00393    IAX_STATE_TBD =            (1 << 2),
00394 };

enum iax2_thread_iostate

Enumerator:
IAX_IOSTATE_IDLE 
IAX_IOSTATE_READY 
IAX_IOSTATE_PROCESSING 
IAX_IOSTATE_SCHEDREADY 

Definition at line 979 of file chan_iax2.c.

enum iax2_thread_type

Enumerator:
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 986 of file chan_iax2.c.

00986                       {
00987    IAX_THREAD_TYPE_POOL,
00988    IAX_THREAD_TYPE_DYNAMIC,
00989 };

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

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


Function Documentation

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

Definition at line 3465 of file chan_iax2.c.

References AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_REMOVE, ast_log(), ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, chan_iax2_pvt::error, f, frame_queue, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxs, iaxsl, iax2_trunk_peer::list, LOG_WARNING, MAX_RETRY_TIME, ast_format::name, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), send_packet(), update_packet(), and iax2_registry::us.

Referenced by attempt_transmit().

03466 {
03467    /* Attempt to transmit the frame to the remote peer...
03468       Called without iaxsl held. */
03469    struct iax_frame *f = (struct iax_frame *)data;
03470    int freeme = 0;
03471    int callno = f->callno;
03472    /* Make sure this call is still active */
03473    if (callno) 
03474       ast_mutex_lock(&iaxsl[callno]);
03475    if (callno && iaxs[callno]) {
03476       if ((f->retries < 0) /* Already ACK'd */ ||
03477           (f->retries >= max_retries) /* Too many attempts */) {
03478             /* Record an error if we've transmitted too many times */
03479             if (f->retries >= max_retries) {
03480                if (f->transfer) {
03481                   /* Transfer timeout */
03482                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03483                } else if (f->final) {
03484                   iax2_destroy(callno);
03485                } else {
03486                   if (iaxs[callno]->owner)
03487                      ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass.integer, f->ts, f->oseqno);
03488                   iaxs[callno]->error = ETIMEDOUT;
03489                   if (iaxs[callno]->owner) {
03490                      struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03491                      /* Hangup the fd */
03492                      iax2_queue_frame(callno, &fr); /* XXX */
03493                      /* Remember, owner could disappear */
03494                      if (iaxs[callno] && iaxs[callno]->owner)
03495                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03496                   } else {
03497                      if (iaxs[callno]->reg) {
03498                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03499                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03500                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03501                      }
03502                      iax2_destroy(callno);
03503                   }
03504                }
03505 
03506             }
03507             freeme = 1;
03508       } else {
03509          /* Update it if it needs it */
03510          update_packet(f);
03511          /* Attempt transmission */
03512          send_packet(f);
03513          f->retries++;
03514          /* Try again later after 10 times as long */
03515          f->retrytime *= 10;
03516          if (f->retrytime > MAX_RETRY_TIME)
03517             f->retrytime = MAX_RETRY_TIME;
03518          /* Transfer messages max out at one second */
03519          if (f->transfer && (f->retrytime > 1000))
03520             f->retrytime = 1000;
03521          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03522       }
03523    } else {
03524       /* Make sure it gets freed */
03525       f->retries = -1;
03526       freeme = 1;
03527    }
03528 
03529    if (freeme) {
03530       /* Don't attempt delivery, just remove it from the queue */
03531       AST_LIST_REMOVE(&frame_queue[callno], f, list);
03532       ast_mutex_unlock(&iaxsl[callno]);
03533       f->retrans = -1; /* this is safe because this is the scheduled function */
03534       /* Free the IAX frame */
03535       iax2_frame_free(f);
03536    } else if (callno) {
03537       ast_mutex_unlock(&iaxsl[callno]);
03538    }
03539 }

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

Definition at line 8931 of file chan_iax2.c.

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

Referenced by auth_reject().

08932 {
08933    /* Called from IAX thread only, without iaxs lock */
08934    int callno = (int)(long)(nothing);
08935    struct iax_ie_data ied;
08936    ast_mutex_lock(&iaxsl[callno]);
08937    if (iaxs[callno]) {
08938       memset(&ied, 0, sizeof(ied));
08939       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08940          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08941          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08942       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08943          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08944          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08945       }
08946       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08947    }
08948    ast_mutex_unlock(&iaxsl[callno]);
08949 }

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

Definition at line 4635 of file chan_iax2.c.

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

Referenced by auto_congest().

04636 {
04637    int callno = PTR_TO_CALLNO(nothing);
04638    struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04639    ast_mutex_lock(&iaxsl[callno]);
04640    if (iaxs[callno]) {
04641       iaxs[callno]->initid = -1;
04642       iax2_queue_frame(callno, &f);
04643       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04644    }
04645    ast_mutex_unlock(&iaxsl[callno]);
04646 }

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

Definition at line 8980 of file chan_iax2.c.

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

Referenced by auto_hangup().

08981 {
08982    /* Called from IAX thread only, without iaxs lock */
08983    int callno = (int)(long)(nothing);
08984    struct iax_ie_data ied;
08985    ast_mutex_lock(&iaxsl[callno]);
08986    if (iaxs[callno]) {
08987       memset(&ied, 0, sizeof(ied));
08988       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
08989       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
08990       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
08991    }
08992    ast_mutex_unlock(&iaxsl[callno]);
08993 }

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

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

Referenced by __get_from_jb(), and schedule_delivery().

03252 {
03253    /* Just deliver the packet by using queueing.  This is called by
03254      the IAX thread with the iaxsl lock held. */
03255    struct iax_frame *fr = data;
03256    fr->retrans = -1;
03257    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03258    if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03259       iax2_queue_frame(fr->callno, &fr->af);
03260    /* Free our iax frame */
03261    iax2_frame_free(fr);
03262    /* And don't run again */
03263    return 0;
03264 }

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

Definition at line 8562 of file chan_iax2.c.

References iax2_peer::addr, ast_db_del(), ast_debug, AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_test_flag64, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, globalflags, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event, iax2_peer::name, peer_unref(), peercnt_modify(), realtime_update_peer(), register_peer_exten(), and unlink_peer().

Referenced by expire_registry().

08563 {
08564    struct iax2_peer *peer = (struct iax2_peer *) data;
08565 
08566    if (!peer)
08567       return;
08568 
08569    peer->expire = -1;
08570 
08571    ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08572    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08573       realtime_update_peer(peer->name, &peer->addr, 0);
08574    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08575    /* modify entry in peercnts table as _not_ registered */
08576    peercnt_modify(0, 0, &peer->addr);
08577    /* Reset the address */
08578    memset(&peer->addr, 0, sizeof(peer->addr));
08579    /* Reset expiry value */
08580    peer->expiry = min_reg_expire;
08581    if (!ast_test_flag64(peer, IAX_TEMPONLY))
08582       ast_db_del("IAX/Registry", peer->name);
08583    register_peer_exten(peer, 0);
08584    ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
08585    if (iax2_regfunk)
08586       iax2_regfunk(peer->name, 0);
08587 
08588    if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08589       unlink_peer(peer);
08590 
08591    peer_unref(peer);
08592 }

static int __find_callno ( unsigned short  callno,
unsigned short  dcallno,
struct sockaddr_in *  sin,
int  new,
int  sockfd,
int  return_locked,
int  check_dcallno 
) [static]

Definition at line 2754 of file chan_iax2.c.

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

Referenced by find_callno(), and find_callno_locked().

02755 {
02756    int res = 0;
02757    int x;
02758    /* this call is calltoken validated as long as it is either NEW_FORCE
02759     * or NEW_ALLOW_CALLTOKEN_VALIDATED */
02760    int validated = (new > NEW_ALLOW) ? 1 : 0;
02761    char host[80];
02762 
02763    if (new <= NEW_ALLOW) {
02764       if (callno) {
02765          struct chan_iax2_pvt *pvt;
02766          struct chan_iax2_pvt tmp_pvt = {
02767             .callno = dcallno,
02768             .peercallno = callno,
02769             .transfercallno = callno,
02770             /* hack!! */
02771             .frames_received = check_dcallno,
02772          };
02773 
02774          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02775          /* this works for finding normal call numbers not involving transfering */ 
02776          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02777             if (return_locked) {
02778                ast_mutex_lock(&iaxsl[pvt->callno]);
02779             }
02780             res = pvt->callno;
02781             ao2_ref(pvt, -1);
02782             pvt = NULL;
02783             return res;
02784          }
02785          /* this searches for transfer call numbers that might not get caught otherwise */
02786          memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02787          memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02788          if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02789             if (return_locked) {
02790                ast_mutex_lock(&iaxsl[pvt->callno]);
02791             }
02792             res = pvt->callno;
02793             ao2_ref(pvt, -1);
02794             pvt = NULL;
02795             return res;
02796          }
02797       }
02798          /* This will occur on the first response to a message that we initiated,
02799        * such as a PING. */
02800       if (dcallno) {
02801          ast_mutex_lock(&iaxsl[dcallno]);
02802       }
02803       if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02804          iaxs[dcallno]->peercallno = callno;
02805          res = dcallno;
02806          store_by_peercallno(iaxs[dcallno]);
02807          if (!res || !return_locked) {
02808             ast_mutex_unlock(&iaxsl[dcallno]);
02809          }
02810          return res;
02811       }
02812       if (dcallno) {
02813          ast_mutex_unlock(&iaxsl[dcallno]);
02814       }
02815 #ifdef IAX_OLD_FIND
02816       /* If we get here, we SHOULD NOT find a call structure for this
02817          callno; if we do, it means that there is a call structure that
02818          has a peer callno but did NOT get entered into the hash table,
02819          which is bad.
02820 
02821          If we find a call structure using this old, slow method, output a log
02822          message so we'll know about it. After a few months of leaving this in
02823          place, if we don't hear about people seeing these messages, we can
02824          remove this code for good.
02825       */
02826 
02827       for (x = 1; !res && x < maxnontrunkcall; x++) {
02828          ast_mutex_lock(&iaxsl[x]);
02829          if (iaxs[x]) {
02830             /* Look for an exact match */
02831             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02832                res = x;
02833             }
02834          }
02835          if (!res || !return_locked)
02836             ast_mutex_unlock(&iaxsl[x]);
02837       }
02838       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02839          ast_mutex_lock(&iaxsl[x]);
02840          if (iaxs[x]) {
02841             /* Look for an exact match */
02842             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02843                res = x;
02844             }
02845          }
02846          if (!res || !return_locked)
02847             ast_mutex_unlock(&iaxsl[x]);
02848       }
02849 #endif
02850    }
02851    if (!res && (new >= NEW_ALLOW)) {
02852       struct callno_entry *callno_entry;
02853       /* It may seem odd that we look through the peer list for a name for
02854        * this *incoming* call.  Well, it is weird.  However, users don't
02855        * have an IP address/port number that we can match against.  So,
02856        * this is just checking for a peer that has that IP/port and
02857        * assuming that we have a user of the same name.  This isn't always
02858        * correct, but it will be changed if needed after authentication. */
02859       if (!iax2_getpeername(*sin, host, sizeof(host)))
02860          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02861 
02862       if (peercnt_add(sin)) {
02863          /* This address has hit its callnumber limit.  When the limit
02864           * is reached, the connection is not added to the peercnts table.*/
02865          return 0;
02866       }
02867 
02868       if (!(callno_entry = get_unused_callno(0, validated))) {
02869          /* since we ran out of space, remove the peercnt
02870           * entry we added earlier */
02871          peercnt_remove_by_addr(sin);
02872          ast_log(LOG_WARNING, "No more space\n");
02873          return 0;
02874       }
02875       x = callno_entry->callno;
02876       ast_mutex_lock(&iaxsl[x]);
02877 
02878       iaxs[x] = new_iax(sin, host);
02879       update_max_nontrunk();
02880       if (iaxs[x]) {
02881          if (iaxdebug)
02882             ast_debug(1, "Creating new call structure %d\n", x);
02883          iaxs[x]->callno_entry = callno_entry;
02884          iaxs[x]->sockfd = sockfd;
02885          iaxs[x]->addr.sin_port = sin->sin_port;
02886          iaxs[x]->addr.sin_family = sin->sin_family;
02887          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02888          iaxs[x]->peercallno = callno;
02889          iaxs[x]->callno = x;
02890          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02891          iaxs[x]->expiry = min_reg_expire;
02892          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02893          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02894          iaxs[x]->amaflags = amaflags;
02895          ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
02896          ast_string_field_set(iaxs[x], accountcode, accountcode);
02897          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02898          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02899          ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02900 
02901          if (iaxs[x]->peercallno) {
02902             store_by_peercallno(iaxs[x]);
02903          }
02904       } else {
02905          ast_log(LOG_WARNING, "Out of resources\n");
02906          ast_mutex_unlock(&iaxsl[x]);
02907          replace_callno(callno_entry);
02908          return 0;
02909       }
02910       if (!return_locked)
02911          ast_mutex_unlock(&iaxsl[x]);
02912       res = x;
02913    }
02914    return res;
02915 }

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

Definition at line 4042 of file chan_iax2.c.

References __do_deliver(), ast_codec_interp_len(), ast_format_rate(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_test_flag64, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_frame_subclass::codec, jb_frame::data, ast_frame::delivery, 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, jb_frame::ms, iax2_trunk_peer::next, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.

Referenced by get_from_jb().

04043 {
04044    int callno = PTR_TO_CALLNO(p);
04045    struct chan_iax2_pvt *pvt = NULL;
04046    struct iax_frame *fr;
04047    jb_frame frame;
04048    int ret;
04049    long ms;
04050    long next;
04051    struct timeval now = ast_tvnow();
04052    
04053    /* Make sure we have a valid private structure before going on */
04054    ast_mutex_lock(&iaxsl[callno]);
04055    pvt = iaxs[callno];
04056    if (!pvt) {
04057       /* No go! */
04058       ast_mutex_unlock(&iaxsl[callno]);
04059       return;
04060    }
04061 
04062    pvt->jbid = -1;
04063    
04064    /* round up a millisecond since ast_sched_runq does; */
04065    /* prevents us from spinning while waiting for our now */
04066    /* to catch up with runq's now */
04067    now.tv_usec += 1000;
04068    
04069    ms = ast_tvdiff_ms(now, pvt->rxcore);
04070    
04071    if(ms >= (next = jb_next(pvt->jb))) {
04072       ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
04073       switch(ret) {
04074       case JB_OK:
04075          fr = frame.data;
04076          __do_deliver(fr);
04077          /* __do_deliver() can cause the call to disappear */
04078          pvt = iaxs[callno];
04079          break;
04080       case JB_INTERP:
04081       {
04082          struct ast_frame af = { 0, };
04083          
04084          /* create an interpolation frame */
04085          af.frametype = AST_FRAME_VOICE;
04086          af.subclass.codec = pvt->voiceformat;
04087          af.samples  = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
04088          af.src  = "IAX2 JB interpolation";
04089          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
04090          af.offset = AST_FRIENDLY_OFFSET;
04091          
04092          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
04093           * which we'd need to malloc, and then it would free it.  That seems like a drag */
04094          if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
04095             iax2_queue_frame(callno, &af);
04096             /* iax2_queue_frame() could cause the call to disappear */
04097             pvt = iaxs[callno];
04098          }
04099       }
04100          break;
04101       case JB_DROP:
04102          iax2_frame_free(frame.data);
04103          break;
04104       case JB_NOFRAME:
04105       case JB_EMPTY:
04106          /* do nothing */
04107          break;
04108       default:
04109          /* shouldn't happen */
04110          break;
04111       }
04112    }
04113    if (pvt)
04114       update_jbsched(pvt);
04115    ast_mutex_unlock(&iaxsl[callno]);
04116 }

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

Definition at line 8238 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

08239 {
08240    struct iax2_registry *reg = (struct iax2_registry *)data;
08241    reg->expire = -1;
08242    iax2_do_register(reg);
08243 }

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

Definition at line 11864 of file chan_iax2.c.

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

Referenced by iax2_poke_noanswer().

11865 {
11866    struct iax2_peer *peer = (struct iax2_peer *)data;
11867    int callno;
11868 
11869    if (peer->lastms > -1) {
11870       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11871       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11872       ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
11873    }
11874    if ((callno = peer->callno) > 0) {
11875       ast_mutex_lock(&iaxsl[callno]);
11876       iax2_destroy(callno);
11877       ast_mutex_unlock(&iaxsl[callno]);
11878    }
11879    peer->callno = 0;
11880    peer->lastms = -1;
11881    /* Try again quickly */
11882    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11883    if (peer->pokeexpire == -1)
11884       peer_unref(peer);
11885 }

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

Definition at line 9040 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

09041 {
09042    struct iax2_peer *peer = (struct iax2_peer *)data;
09043    iax2_poke_peer(peer, 0);
09044    peer_unref(peer);
09045 }

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

Definition at line 6603 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_to_sin, ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, astman_append(), iax2_peer::encmethods, encmethods_to_str(), FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, name, peer_status(), peer_unref(), peers, RESULT_SHOWUSAGE, RESULT_SUCCESS, status, and iax2_peer::username.

Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().

06604 {
06605    regex_t regexbuf;
06606    int havepattern = 0;
06607    int total_peers = 0;
06608    int online_peers = 0;
06609    int offline_peers = 0;
06610    int unmonitored_peers = 0;
06611    struct ao2_iterator i;
06612 
06613 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s\n"
06614 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s\n"
06615 
06616    struct iax2_peer *peer = NULL;
06617    char name[256];
06618    struct ast_str *encmethods = ast_str_alloca(256);
06619    int registeredonly=0;
06620    char idtext[256] = "";
06621    switch (argc) {
06622    case 6:
06623       if (!strcasecmp(argv[3], "registered"))
06624          registeredonly = 1;
06625       else
06626          return RESULT_SHOWUSAGE;
06627       if (!strcasecmp(argv[4], "like")) {
06628          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06629             return RESULT_SHOWUSAGE;
06630          havepattern = 1;
06631       } else
06632          return RESULT_SHOWUSAGE;
06633       break;
06634    case 5:
06635       if (!strcasecmp(argv[3], "like")) {
06636          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06637             return RESULT_SHOWUSAGE;
06638          havepattern = 1;
06639       } else
06640          return RESULT_SHOWUSAGE;
06641       break;
06642    case 4:
06643       if (!strcasecmp(argv[3], "registered"))
06644          registeredonly = 1;
06645       else
06646          return RESULT_SHOWUSAGE;
06647       break;
06648    case 3:
06649       break;
06650    default:
06651       return RESULT_SHOWUSAGE;
06652    }
06653 
06654 
06655    if (!s)
06656       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status");
06657 
06658    i = ao2_iterator_init(peers, 0);
06659    for (peer = ao2_iterator_next(&i); peer;
06660       peer_unref(peer), peer = ao2_iterator_next(&i)) {
06661       char nm[20];
06662       char status[20];
06663       int retstatus;
06664       struct sockaddr_in peer_addr;
06665 
06666       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06667 
06668       if (registeredonly && !peer_addr.sin_addr.s_addr) {
06669          continue;
06670       }
06671       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0)) {
06672          continue;
06673       }
06674 
06675       if (!ast_strlen_zero(peer->username))
06676          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06677       else
06678          ast_copy_string(name, peer->name, sizeof(name));
06679 
06680       encmethods_to_str(peer->encmethods, encmethods);
06681       retstatus = peer_status(peer, status, sizeof(status));
06682       if (retstatus > 0)
06683          online_peers++;
06684       else if (!retstatus)
06685          offline_peers++;
06686       else
06687          unmonitored_peers++;
06688 
06689       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06690 
06691       if (s) {
06692          astman_append(s,
06693             "Event: PeerEntry\r\n%s"
06694             "Channeltype: IAX2\r\n"
06695             "ObjectName: %s\r\n"
06696             "ChanObjectType: peer\r\n"
06697             "IPaddress: %s\r\n"
06698             "IPport: %d\r\n"
06699             "Dynamic: %s\r\n"
06700             "Trunk: %s\r\n"
06701             "Encryption: %s\r\n"
06702             "Status: %s\r\n\r\n",
06703             idtext,
06704             name,
06705             ast_sockaddr_stringify_addr(&peer->addr),
06706             ast_sockaddr_port(&peer->addr),
06707             ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06708             ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06709             peer->encmethods ? ast_str_buffer(encmethods) : "no",
06710             status);
06711       } else {
06712          ast_cli(fd, FORMAT, name,
06713             ast_sockaddr_stringify_addr(&peer->addr),
06714             ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06715             nm,
06716             ast_sockaddr_port(&peer->addr),
06717             ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : "   ",
06718             peer->encmethods ? "(E)" : "   ",
06719             status);
06720       }
06721       total_peers++;
06722    }
06723    ao2_iterator_destroy(&i);
06724 
06725    if (!s)
06726       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06727          total_peers, online_peers, offline_peers, unmonitored_peers);
06728 
06729    if (havepattern)
06730       regfree(&regexbuf);
06731 
06732    if (total)
06733       *total = total_peers;
06734 
06735    return RESULT_SUCCESS;
06736 #undef FORMAT
06737 #undef FORMAT2
06738 }

static void __reg_module ( void   )  [static]

Definition at line 14698 of file chan_iax2.c.

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

Definition at line 1462 of file chan_iax2.c.

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

01463 {
01464    struct iax2_thread *thread = NULL;
01465    static time_t lasterror;
01466    static time_t t;
01467 
01468    thread = find_idle_thread();
01469 
01470    if (thread != NULL) {
01471       thread->schedfunc = func;
01472       thread->scheddata = data;
01473       thread->iostate = IAX_IOSTATE_SCHEDREADY;
01474 #ifdef DEBUG_SCHED_MULTITHREAD
01475       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01476 #endif
01477       signal_condition(&thread->lock, &thread->cond);
01478       return 0;
01479    }
01480    time(&t);
01481    if (t != lasterror) 
01482       ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01483    lasterror = t;
01484 
01485    return -1;
01486 }

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

References f, iax2_send(), and queue_signalling().

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

07432 {
07433    struct ast_frame f = { 0, };
07434    int res = 0;
07435 
07436    f.frametype = type;
07437    f.subclass.integer = command;
07438    f.datalen = datalen;
07439    f.src = __FUNCTION__;
07440    f.data.ptr = (void *) data;
07441 
07442    if ((res = queue_signalling(i, &f)) <= 0) {
07443       return res;
07444    }
07445 
07446    return iax2_send(i, &f, ts, seqno, now, transfer, final);
07447 }

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

Definition at line 1573 of file chan_iax2.c.

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

Referenced by send_lagrq().

01574 {
01575    int callno = (long) data;
01576 
01577    ast_mutex_lock(&iaxsl[callno]);
01578 
01579    if (iaxs[callno]) {
01580       if (iaxs[callno]->peercallno) {
01581          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01582          if (iaxs[callno]->lagid != DONT_RESCHEDULE) {
01583             iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01584          }
01585       }
01586    } else {
01587       ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01588    }
01589 
01590    ast_mutex_unlock(&iaxsl[callno]);
01591 }

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

Definition at line 1506 of file chan_iax2.c.

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

Referenced by send_ping().

01507 {
01508    int callno = (long) data;
01509 
01510    ast_mutex_lock(&iaxsl[callno]);
01511 
01512    if (iaxs[callno]) {
01513       if (iaxs[callno]->peercallno) {
01514          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01515          if (iaxs[callno]->pingid != DONT_RESCHEDULE) {
01516             iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01517          }
01518       }
01519    } else {
01520       ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01521    }
01522 
01523    ast_mutex_unlock(&iaxsl[callno]);
01524 }

static int __unload_module ( void   )  [static]

Definition at line 14198 of file chan_iax2.c.

References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), ast_data_unregister, ast_manager_unregister(), ast_mutex_destroy, ast_netsock_release(), AST_PTHREADT_NULL, ast_sched_thread_destroy(), ast_taskprocessor_unreference(), AST_TEST_UNREGISTER, ast_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), callno_limits, calltoken_ignores, cleanup_thread_list(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, iax_peercallno_pvts, iax_provision_unload(), iax_transfercallno_pvts, iaxs, iaxsl, netsock, network_change_event_unsubscribe(), outsock, papp, peercnts, peers, reload_firmware(), sched, timer, and users.

14199 {
14200    struct ast_context *con;
14201    int x;
14202 
14203    network_change_event_unsubscribe();
14204 
14205    ast_manager_unregister("IAXpeers");
14206    ast_manager_unregister("IAXpeerlist");
14207    ast_manager_unregister("IAXnetstats");
14208    ast_manager_unregister("IAXregistry");
14209    ast_unregister_application(papp);
14210    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14211    ast_unregister_switch(&iax2_switch);
14212    ast_channel_unregister(&iax2_tech);
14213 
14214    if (netthreadid != AST_PTHREADT_NULL) {
14215       pthread_cancel(netthreadid);
14216       pthread_kill(netthreadid, SIGURG);
14217       pthread_join(netthreadid, NULL);
14218    }
14219 
14220    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14221       if (iaxs[x]) {
14222          iax2_destroy(x);
14223       }
14224    }
14225 
14226    /* Call for all threads to halt */
14227    cleanup_thread_list(&idle_list);
14228    cleanup_thread_list(&active_list);
14229    cleanup_thread_list(&dynamic_list);
14230 
14231    ast_netsock_release(netsock);
14232    ast_netsock_release(outsock);
14233    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14234       if (iaxs[x]) {
14235          iax2_destroy(x);
14236       }
14237    }
14238    ast_manager_unregister( "IAXpeers" );
14239    ast_manager_unregister( "IAXpeerlist" );
14240    ast_manager_unregister( "IAXnetstats" );
14241    ast_manager_unregister( "IAXregistry" );
14242    ast_unregister_application(papp);
14243 #ifdef TEST_FRAMEWORK
14244    AST_TEST_UNREGISTER(test_iax2_peers_get);
14245    AST_TEST_UNREGISTER(test_iax2_users_get);
14246 #endif
14247    ast_data_unregister(NULL);
14248    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14249    ast_unregister_switch(&iax2_switch);
14250    ast_channel_unregister(&iax2_tech);
14251    delete_users();
14252    iax_provision_unload();
14253    reload_firmware(1);
14254 
14255    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14256       ast_mutex_destroy(&iaxsl[x]);
14257    }
14258 
14259    ao2_ref(peers, -1);
14260    ao2_ref(users, -1);
14261    ao2_ref(iax_peercallno_pvts, -1);
14262    ao2_ref(iax_transfercallno_pvts, -1);
14263    ao2_ref(peercnts, -1);
14264    ao2_ref(callno_limits, -1);
14265    ao2_ref(calltoken_ignores, -1);
14266    ao2_ref(callno_pool, -1);
14267    ao2_ref(callno_pool_trunk, -1);
14268    if (timer) {
14269       ast_timer_close(timer);
14270    }
14271    transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14272    sched = ast_sched_thread_destroy(sched);
14273 
14274    con = ast_context_find(regcontext);
14275    if (con)
14276       ast_context_destroy(con, "IAX2");
14277    ast_unload_realtime("iaxpeers");
14278    return 0;
14279 }

static void __unreg_module ( void   )  [static]

Definition at line 14698 of file chan_iax2.c.

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

Definition at line 13838 of file chan_iax2.c.

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

13839 {
13840    struct chan_iax2_pvt *pvt;
13841    unsigned int callno;
13842    int res = 0;
13843 
13844    if (!chan || chan->tech != &iax2_tech) {
13845       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13846       return -1;
13847    }
13848 
13849    callno = PTR_TO_CALLNO(chan->tech_pvt);
13850    ast_mutex_lock(&iaxsl[callno]);
13851    if (!(pvt = iaxs[callno])) {
13852       ast_mutex_unlock(&iaxsl[callno]);
13853       return -1;
13854    }
13855 
13856    if (!strcasecmp(args, "osptoken")) {
13857       ast_copy_string(buf, pvt->osptoken, buflen);
13858    } else if (!strcasecmp(args, "peerip")) {
13859       ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13860    } else if (!strcasecmp(args, "peername")) {
13861       ast_copy_string(buf, pvt->username, buflen);
13862    } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
13863       snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
13864    } else {
13865       res = -1;
13866    }
13867 
13868    ast_mutex_unlock(&iaxsl[callno]);
13869 
13870    return res;
13871 }

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

Definition at line 9708 of file chan_iax2.c.

References ast_channel_datastore_find(), ast_copy_string(), AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_datastore::data, ast_var_t::entries, iax2_variable_datastore_info, and var.

09709 {
09710    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09711    AST_LIST_HEAD(, ast_var_t) *varlist;
09712    struct ast_var_t *var;
09713 
09714    if (!variablestore) {
09715       *buf = '\0';
09716       return 0;
09717    }
09718    varlist = variablestore->data;
09719 
09720    AST_LIST_LOCK(varlist);
09721    AST_LIST_TRAVERSE(varlist, var, entries) {
09722       if (strcmp(var->name, data) == 0) {
09723          ast_copy_string(buf, var->value, len);
09724          break;
09725       }
09726    }
09727    AST_LIST_UNLOCK(varlist);
09728    return 0;
09729 }

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

Definition at line 9731 of file chan_iax2.c.

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

09732 {
09733    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09734    AST_LIST_HEAD(, ast_var_t) *varlist;
09735    struct ast_var_t *var;
09736 
09737    if (!variablestore) {
09738       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09739       if (!variablestore) {
09740          ast_log(LOG_ERROR, "Memory allocation error\n");
09741          return -1;
09742       }
09743       varlist = ast_calloc(1, sizeof(*varlist));
09744       if (!varlist) {
09745          ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09746          return -1;
09747       }
09748 
09749       AST_LIST_HEAD_INIT(varlist);
09750       variablestore->data = varlist;
09751       variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09752       ast_channel_datastore_add(chan, variablestore);
09753    } else
09754       varlist = variablestore->data;
09755 
09756    AST_LIST_LOCK(varlist);
09757    AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09758       if (strcmp(var->name, data) == 0) {
09759          AST_LIST_REMOVE_CURRENT(entries);
09760          ast_var_delete(var);
09761          break;
09762       }
09763    }
09764    AST_LIST_TRAVERSE_SAFE_END;
09765    var = ast_var_assign(data, value);
09766    if (var)
09767       AST_LIST_INSERT_TAIL(varlist, var, entries);
09768    else
09769       ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09770    AST_LIST_UNLOCK(varlist);
09771    return 0;
09772 }

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

Definition at line 2496 of file chan_iax2.c.

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

Referenced by set_config().

02497 {
02498    struct addr_range tmp;
02499    struct addr_range *addr_range = NULL;
02500    struct ast_ha *ha = NULL;
02501    int error = 0;
02502 
02503    if (ast_strlen_zero(addr)) {
02504       ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02505       return -1;
02506    }
02507 
02508    ha = ast_append_ha("permit", addr, NULL, &error);
02509 
02510    /* check for valid config information */
02511    if (error) {
02512       ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02513       return -1;
02514    }
02515 
02516    ast_copy_ha(ha, &tmp.ha);
02517    /* find or create the addr_range */
02518    if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02519       ao2_lock(addr_range);
02520       addr_range->delme = 0;
02521       ao2_unlock(addr_range);
02522    } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02523       /* copy over config data into addr_range object */
02524       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
02525       ao2_link(calltoken_ignores, addr_range);
02526    } else {
02527       ast_free_ha(ha);
02528       return -1;
02529    }
02530 
02531    ast_free_ha(ha);
02532    ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02533 
02534    return 0;
02535 }

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

Definition at line 4709 of file chan_iax2.c.

References iax_ie_data::buf, chan_iax2_pvt::calltoken_ie_len, IAX_IE_CALLTOKEN, and iax_ie_data::pos.

Referenced by cache_get_callno_locked(), iax2_call(), iax2_do_register(), iax2_poke_peer(), and registry_rerequest().

04710 {
04711    /* first make sure their are two empty bytes left in ied->buf */
04712    if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04713       ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;  /* type */
04714       ied->buf[ied->pos++] = 0;   /* data size,  ZERO in this case */
04715       pvt->calltoken_ie_len = 2;
04716    }
04717 }

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

Definition at line 2148 of file chan_iax2.c.

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

Referenced by load_objects().

02149 {
02150    struct addr_range *lim1 = obj, *lim2 = arg;
02151    return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
02152          !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
02153          CMP_MATCH | CMP_STOP : 0;
02154 }

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

Definition at line 2133 of file chan_iax2.c.

References addr_range::delme.

Referenced by set_config_destroy().

02134 {
02135    struct addr_range *lim = obj;
02136    lim->delme = 1;
02137    return 0;
02138 }

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

Definition at line 2140 of file chan_iax2.c.

References ast_ha::addr, ast_sockaddr_to_sin, and addr_range::ha.

Referenced by load_objects().

02141 {
02142    const struct addr_range *lim = obj;
02143    struct sockaddr_in sin;
02144    ast_sockaddr_to_sin(&lim->ha.addr, &sin);
02145    return abs((int) sin.sin_addr.s_addr);
02146 }

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

Definition at line 2168 of file chan_iax2.c.

References ast_ha::addr, ast_sockaddr_to_sin, CMP_MATCH, CMP_STOP, addr_range::ha, and ast_ha::netmask.

Referenced by calltoken_required(), and set_peercnt_limit().

02169 {
02170    struct addr_range *addr_range = obj;
02171    struct sockaddr_in *sin = arg;
02172    struct sockaddr_in ha_netmask_sin;
02173    struct sockaddr_in ha_addr_sin;
02174 
02175    ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin);
02176    ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin);
02177 
02178    if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) {
02179       return CMP_MATCH | CMP_STOP;
02180    }
02181    return 0;
02182 }

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

Definition at line 7488 of file chan_iax2.c.

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

Referenced by check_access().

07489 {
07490    while(con) {
07491       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07492          return -1;
07493       con = con->next;
07494    }
07495    return 0;
07496 }

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

Definition at line 7189 of file chan_iax2.c.

References ACN_FORMAT1, ACN_FORMAT2, ARRAY_LEN, ast_cli(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, astman_append(), jb_info::current, iax_rr::delay, iax_rr::dropped, chan_iax2_pvt::first_iax_message, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, iax_frame_subclass2str(), IAX_USEJITTERBUF, 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, 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().

07190 {
07191    int x;
07192    int numchans = 0;
07193    char first_message[10] = { 0, };
07194    char last_message[10] = { 0, };
07195 #define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
07196 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07197    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07198       ast_mutex_lock(&iaxsl[x]);
07199       if (iaxs[x]) {
07200          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07201          jb_info jbinfo;
07202          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07203          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07204 
07205          if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07206             jb_getinfo(iaxs[x]->jb, &jbinfo);
07207             localjitter = jbinfo.jitter;
07208             localdelay = jbinfo.current - jbinfo.min;
07209             locallost = jbinfo.frames_lost;
07210             locallosspct = jbinfo.losspct/1000;
07211             localdropped = jbinfo.frames_dropped;
07212             localooo = jbinfo.frames_ooo;
07213          } else {
07214             localjitter = -1;
07215             localdelay = 0;
07216             locallost = -1;
07217             locallosspct = -1;
07218             localdropped = 0;
07219             localooo = -1;
07220          }
07221          if (s)
07222             astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07223                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07224                iaxs[x]->pingtime,
07225                localjitter,
07226                localdelay,
07227                locallost,
07228                locallosspct,
07229                localdropped,
07230                localooo,
07231                iaxs[x]->frames_received/1000,
07232                iaxs[x]->remote_rr.jitter,
07233                iaxs[x]->remote_rr.delay,
07234                iaxs[x]->remote_rr.losscnt,
07235                iaxs[x]->remote_rr.losspct,
07236                iaxs[x]->remote_rr.dropped,
07237                iaxs[x]->remote_rr.ooo,
07238                iaxs[x]->remote_rr.packets/1000,
07239                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07240                first_message,
07241                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07242                last_message);
07243          else
07244             ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07245                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07246                iaxs[x]->pingtime,
07247                localjitter,
07248                localdelay,
07249                locallost,
07250                locallosspct,
07251                localdropped,
07252                localooo,
07253                iaxs[x]->frames_received/1000,
07254                iaxs[x]->remote_rr.jitter,
07255                iaxs[x]->remote_rr.delay,
07256                iaxs[x]->remote_rr.losscnt,
07257                iaxs[x]->remote_rr.losspct,
07258                iaxs[x]->remote_rr.dropped,
07259                iaxs[x]->remote_rr.ooo,
07260                iaxs[x]->remote_rr.packets/1000,
07261                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07262                first_message,
07263                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07264                last_message);
07265          numchans++;
07266       }
07267       ast_mutex_unlock(&iaxsl[x]);
07268    }
07269 
07270    return numchans;
07271 }

AST_DATA_STRUCTURE ( iax2_user  ,
DATA_EXPORT_IAX2_USER   
)

AST_DATA_STRUCTURE ( iax2_peer  ,
DATA_EXPORT_IAX2_PEER   
)

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

Create new call, interface with the PBX core.

Definition at line 5682 of file chan_iax2.c.

References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, ast_party_caller::ani, chan_iax2_pvt::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_calloc, ast_channel_alloc, ast_channel_datastore_add(), ast_channel_release(), ast_copy_string(), ast_datastore_alloc, ast_datastore_free(), ast_debug, ast_free, ast_hangup(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_module_ref(), ast_mutex_lock, ast_mutex_unlock, ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_var_assign(), ast_channel::caller, 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, ast_channel::context, chan_iax2_pvt::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::dialed, chan_iax2_pvt::dnid, ast_var_t::entries, ast_channel::exten, chan_iax2_pvt::exten, ast_party_redirecting::from, chan_iax2_pvt::host, iax2_ami_channelupdate(), 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_variable::name, ast_party_id::name, ast_channel::nativeformats, ast_variable::next, ast_party_dialed::number, ast_party_id::number, chan_iax2_pvt::owner, parkinglot, chan_iax2_pvt::parkinglot, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, ast_channel::rawreadformat, ast_channel::rawwriteformat, chan_iax2_pvt::rdnis, ast_channel::readformat, ast_channel::redirecting, ast_party_dialed::str, ast_party_number::str, ast_channel::tech, ast_channel::tech_pvt, ast_party_dialed::transit_network_select, ast_party_number::valid, ast_variable::value, var, chan_iax2_pvt::vars, and ast_channel::writeformat.

Referenced by iax2_request(), and socket_process().

05683 {
05684    struct ast_channel *tmp;
05685    struct chan_iax2_pvt *i;
05686    struct ast_variable *v = NULL;
05687 
05688    if (!(i = iaxs[callno])) {
05689       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05690       return NULL;
05691    }
05692 
05693    /* Don't hold call lock */
05694    ast_mutex_unlock(&iaxsl[callno]);
05695    tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
05696    ast_mutex_lock(&iaxsl[callno]);
05697    if (i != iaxs[callno]) {
05698       if (tmp) {
05699          /* unlock and relock iaxsl[callno] to preserve locking order */
05700          ast_mutex_unlock(&iaxsl[callno]);
05701          tmp = ast_channel_release(tmp);
05702          ast_mutex_lock(&iaxsl[callno]);
05703       }
05704       return NULL;
05705    }
05706    iax2_ami_channelupdate(i);
05707    if (!tmp)
05708       return NULL;
05709    tmp->tech = &iax2_tech;
05710    /* We can support any format by default, until we get restricted */
05711    tmp->nativeformats = capability;
05712    tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05713    tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05714    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05715 
05716    if (!ast_strlen_zero(i->parkinglot))
05717       ast_string_field_set(tmp, parkinglot, i->parkinglot);
05718    /* Don't use ast_set_callerid() here because it will
05719     * generate a NewCallerID event before the NewChannel event */
05720    if (!ast_strlen_zero(i->ani)) {
05721       tmp->caller.ani.number.valid = 1;
05722       tmp->caller.ani.number.str = ast_strdup(i->ani);
05723    } else if (!ast_strlen_zero(i->cid_num)) {
05724       tmp->caller.ani.number.valid = 1;
05725       tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05726    }
05727    tmp->dialed.number.str = ast_strdup(i->dnid);
05728    tmp->redirecting.from.number.valid = 1;
05729    tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05730    tmp->caller.id.name.presentation = i->calling_pres;
05731    tmp->caller.id.number.presentation = i->calling_pres;
05732    tmp->caller.id.number.plan = i->calling_ton;
05733    tmp->dialed.transit_network_select = i->calling_tns;
05734    if (!ast_strlen_zero(i->language))
05735       ast_string_field_set(tmp, language, i->language);
05736    if (!ast_strlen_zero(i->accountcode))
05737       ast_string_field_set(tmp, accountcode, i->accountcode);
05738    if (i->amaflags)
05739       tmp->amaflags = i->amaflags;
05740    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05741    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05742    if (i->adsi)
05743       tmp->adsicpe = i->peeradsicpe;
05744    else
05745       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05746    i->owner = tmp;
05747    i->capability = capability;
05748 
05749    /* Set inherited variables */
05750    if (i->vars) {
05751       for (v = i->vars ; v ; v = v->next)
05752          pbx_builtin_setvar_helper(tmp, v->name, v->value);
05753    }
05754    if (i->iaxvars) {
05755       struct ast_datastore *variablestore;
05756       struct ast_variable *var, *prev = NULL;
05757       AST_LIST_HEAD(, ast_var_t) *varlist;
05758       ast_debug(1, "Loading up the channel with IAXVARs\n");
05759       varlist = ast_calloc(1, sizeof(*varlist));
05760       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05761       if (variablestore && varlist) {
05762          variablestore->data = varlist;
05763          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05764          AST_LIST_HEAD_INIT(varlist);
05765          for (var = i->iaxvars; var; var = var->next) {
05766             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05767             if (prev)
05768                ast_free(prev);
05769             prev = var;
05770             if (!newvar) {
05771                /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
05772                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05773             } else {
05774                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05775             }
05776          }
05777          if (prev)
05778             ast_free(prev);
05779          i->iaxvars = NULL;
05780          ast_channel_datastore_add(i->owner, variablestore);
05781       } else {
05782          if (variablestore) {
05783             ast_datastore_free(variablestore);
05784          }
05785          if (varlist) {
05786             ast_free(varlist);
05787          }
05788       }
05789    }
05790 
05791    if (state != AST_STATE_DOWN) {
05792       if (ast_pbx_start(tmp)) {
05793          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05794          ast_hangup(tmp);
05795          i->owner = NULL;
05796          return NULL;
05797       }
05798    }
05799 
05800    ast_module_ref(ast_module_info->self);
05801    return tmp;
05802 }

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

Definition at line 3541 of file chan_iax2.c.

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and transmit_frame().

03542 {
03543 #ifdef SCHED_MULTITHREADED
03544    if (schedule_action(__attempt_transmit, data))
03545 #endif      
03546       __attempt_transmit(data);
03547    return 0;
03548 }

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

Definition at line 8965 of file chan_iax2.c.

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

Referenced by socket_process().

08966 {
08967    /* Schedule sending the authentication failure in one second, to prevent
08968       guessing */
08969    if (iaxs[callno]) {
08970       iaxs[callno]->authfail = failcode;
08971       if (delayreject) {
08972          iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 
08973             sched, 1000, auth_reject, (void *)(long)callno);
08974       } else
08975          auth_reject((void *)(long)callno);
08976    }
08977    return 0;
08978 }

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

Definition at line 8951 of file chan_iax2.c.

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

Referenced by auth_fail().

08952 {
08953    int callno = (int)(long)(data);
08954    ast_mutex_lock(&iaxsl[callno]);
08955    if (iaxs[callno])
08956       iaxs[callno]->authid = -1;
08957    ast_mutex_unlock(&iaxsl[callno]);
08958 #ifdef SCHED_MULTITHREADED
08959    if (schedule_action(__auth_reject, data))
08960 #endif      
08961       __auth_reject(data);
08962    return 0;
08963 }

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

Definition at line 8060 of file chan_iax2.c.

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

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

08061 {
08062    int res = -1;
08063    int x;
08064    if (!ast_strlen_zero(keyn)) {
08065       if (!(authmethods & IAX_AUTH_RSA)) {
08066          if (ast_strlen_zero(secret)) 
08067             ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(sin->sin_addr));
08068       } else if (ast_strlen_zero(challenge)) {
08069          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08070       } else {
08071          char sig[256];
08072          struct ast_key *key;
08073          key = ast_key_get(keyn, AST_KEY_PRIVATE);
08074          if (!key) {
08075             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08076          } else {
08077             if (ast_sign(key, (char*)challenge, sig)) {
08078                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08079                res = -1;
08080             } else {
08081                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08082                res = 0;
08083             }
08084          }
08085       }
08086    } 
08087    /* Fall back */
08088    if (res && !ast_strlen_zero(secret)) {
08089       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08090          struct MD5Context md5;
08091          unsigned char digest[16];
08092          char digres[128];
08093          MD5Init(&md5);
08094          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08095          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08096          MD5Final(digest, &md5);
08097          /* If they support md5, authenticate with it.  */
08098          for (x=0;x<16;x++)
08099             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
08100          if (pvt) {
08101             build_encryption_keys(digest, pvt);
08102          }
08103          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08104          res = 0;
08105       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08106          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08107          res = 0;
08108       } else
08109          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08110    }
08111    return res;
08112 }

static int authenticate_reply ( struct chan_iax2_pvt p,
struct sockaddr_in *  sin,
struct iax_ies ies,
const char *  override,
const char *  okey 
) [static]

Note:
This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno, so do not call this function with a pvt lock held.

Definition at line 8118 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_calloc, ast_channel_datastore_add(), ast_datastore_alloc, ast_datastore_free(), AST_FRAME_IAX, ast_free, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_sockaddr_to_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_assign(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, chan_iax2_pvt::callno, iax_ies::challenge, ast_datastore::data, DATASTORE_INHERIT_FOREVER, iax_ies::encmethods, ast_var_t::entries, iax2_variable_datastore_info, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_FORCE_ENCRYPT, IAX_KEYPOPULATED, iaxs, iaxsl, ast_datastore::inheritance, LOG_ERROR, LOG_NOTICE, iax2_peer::mask, merge_encryption(), iax2_peer::name, iax2_peer::outkey, peer_unref(), peers, realtime_peer(), iax2_peer::secret, send_command(), iax2_peer::username, iax_ies::username, var, and iax_ies::vars.

Referenced by socket_process().

08119 {
08120    struct iax2_peer *peer = NULL;
08121    /* Start pessimistic */
08122    int res = -1;
08123    int authmethods = 0;
08124    struct iax_ie_data ied;
08125    uint16_t callno = p->callno;
08126 
08127    memset(&ied, 0, sizeof(ied));
08128    
08129    if (ies->username)
08130       ast_string_field_set(p, username, ies->username);
08131    if (ies->challenge)
08132       ast_string_field_set(p, challenge, ies->challenge);
08133    if (ies->authmethods)
08134       authmethods = ies->authmethods;
08135    if (authmethods & IAX_AUTH_MD5)
08136       merge_encryption(p, ies->encmethods);
08137    else
08138       p->encmethods = 0;
08139 
08140    /* Check for override RSA authentication first */
08141    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08142       /* Normal password authentication */
08143       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08144    } else {
08145       struct ao2_iterator i = ao2_iterator_init(peers, 0);
08146       while ((peer = ao2_iterator_next(&i))) {
08147          struct sockaddr_in peer_addr;
08148 
08149          ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08150 
08151          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
08152              /* No peer specified at our end, or this is the peer */
08153              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08154              /* No username specified in peer rule, or this is the right username */
08155              && (!peer_addr.sin_addr.s_addr || ((sin->sin_addr.s_addr & peer->mask.s_addr) == (peer_addr.sin_addr.s_addr & peer->mask.s_addr)))
08156              /* No specified host, or this is our host */
08157             ) {
08158             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08159             if (!res) {
08160                peer_unref(peer);
08161                break;
08162             }
08163          }
08164          peer_unref(peer);
08165       }
08166       ao2_iterator_destroy(&i);
08167       if (!peer) {
08168          /* We checked our list and didn't find one.  It's unlikely, but possible, 
08169             that we're trying to authenticate *to* a realtime peer */
08170          const char *peer_name = ast_strdupa(p->peer);
08171          ast_mutex_unlock(&iaxsl[callno]);
08172          if ((peer = realtime_peer(peer_name, NULL))) {
08173             ast_mutex_lock(&iaxsl[callno]);
08174             if (!(p = iaxs[callno])) {
08175                peer_unref(peer);
08176                return -1;
08177             }
08178             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08179             peer_unref(peer);
08180          }
08181          if (!peer) {
08182             ast_mutex_lock(&iaxsl[callno]);
08183             if (!(p = iaxs[callno]))
08184                return -1;
08185          }
08186       }
08187    }
08188 
08189    if (ies->encmethods) {
08190       ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08191    } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08192       ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
08193       return -1;             /* if force encryption is yes, and no encryption methods, then return -1 to hangup */
08194    }
08195    if (!res) {
08196       struct ast_datastore *variablestore;
08197       struct ast_variable *var, *prev = NULL;
08198       AST_LIST_HEAD(, ast_var_t) *varlist;
08199       varlist = ast_calloc(1, sizeof(*varlist));
08200       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08201       if (variablestore && varlist && p->owner) {
08202          variablestore->data = varlist;
08203          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08204          AST_LIST_HEAD_INIT(varlist);
08205          for (var = ies->vars; var; var = var->next) {
08206             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08207             if (prev)
08208                ast_free(prev);
08209             prev = var;
08210             if (!newvar) {
08211                /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */
08212                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08213             } else {
08214                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08215             }
08216          }
08217          if (prev)
08218             ast_free(prev);
08219          ies->vars = NULL;
08220          ast_channel_datastore_add(p->owner, variablestore);
08221       } else {
08222          if (p->owner)
08223             ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08224          if (variablestore)
08225             ast_datastore_free(variablestore);
08226          if (varlist)
08227             ast_free(varlist);
08228       }
08229    }
08230 
08231    if (!res)
08232       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08233    return res;
08234 }

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

References ao2_find, AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_random(), ast_set_flag64, ast_string_field_set, ast_test_flag64, chan_iax2_pvt::authmethods, chan_iax2_pvt::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_POINTER, send_command(), send_command_final(), user, user_unref(), chan_iax2_pvt::username, and users.

Referenced by socket_process().

07767 {
07768    struct iax_ie_data ied;
07769    int res = -1, authreq_restrict = 0;
07770    char challenge[10];
07771    struct chan_iax2_pvt *p = iaxs[call_num];
07772 
07773    memset(&ied, 0, sizeof(ied));
07774 
07775    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
07776    if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07777       struct iax2_user *user, tmp_user = {
07778          .name = p->username, 
07779       };
07780 
07781       user = ao2_find(users, &tmp_user, OBJ_POINTER);
07782       if (user) {
07783          if (user->curauthreq == user->maxauthreq)
07784             authreq_restrict = 1;
07785          else
07786             user->curauthreq++;
07787          user = user_unref(user);
07788       }
07789    }
07790 
07791    /* If the AUTHREQ limit test failed, send back an error */
07792    if (authreq_restrict) {
07793       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07794       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07795       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07796       return 0;
07797    }
07798 
07799    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07800    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07801       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07802       ast_string_field_set(p, challenge, challenge);
07803       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
07804       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07805    }
07806    if (p->encmethods)
07807       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07808 
07809    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07810 
07811    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07812 
07813    if (p->encmethods)
07814       ast_set_flag64(p, IAX_ENCRYPTED);
07815 
07816    return res;
07817 }

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

Definition at line 7819 of file chan_iax2.c.

References ao2_find, ast_atomic_fetchadd_int(), ast_check_signature(), ast_clear_flag64, ast_copy_string(), ast_key_get(), AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::challenge, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_FORCE_ENCRYPT, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, LOG_NOTICE, LOG_WARNING, md5(), iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), OBJ_POINTER, iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user, user_unref(), chan_iax2_pvt::username, and users.

Referenced by socket_process().

07820 {
07821    char requeststr[256];
07822    char md5secret[256] = "";
07823    char secret[256] = "";
07824    char rsasecret[256] = "";
07825    int res = -1; 
07826    int x;
07827    struct iax2_user *user, tmp_user = {
07828       .name = p->username, 
07829    };
07830 
07831    if (p->authrej) {
07832       return res;
07833    }
07834    user = ao2_find(users, &tmp_user, OBJ_POINTER);
07835    if (user) {
07836       if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07837          ast_atomic_fetchadd_int(&user->curauthreq, -1);
07838          ast_clear_flag64(p, IAX_MAXAUTHREQ);
07839       }
07840       ast_string_field_set(p, host, user->name);
07841       user = user_unref(user);
07842    }
07843    if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 
07844       ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.");
07845       return res;
07846    }
07847    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07848       return res;
07849    if (ies->password)
07850       ast_copy_string(secret, ies->password, sizeof(secret));
07851    if (ies->md5_result)
07852       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07853    if (ies->rsa_result)
07854       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07855    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07856       struct ast_key *key;
07857       char *keyn;
07858       char tmpkey[256];
07859       char *stringp=NULL;
07860       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07861       stringp=tmpkey;
07862       keyn = strsep(&stringp, ":");
07863       while(keyn) {
07864          key = ast_key_get(keyn, AST_KEY_PUBLIC);
07865          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07866             res = 0;
07867             break;
07868          } else if (!key)
07869             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07870          keyn = strsep(&stringp, ":");
07871       }
07872    } else if (p->authmethods & IAX_AUTH_MD5) {
07873       struct MD5Context md5;
07874       unsigned char digest[16];
07875       char *tmppw, *stringp;
07876       
07877       tmppw = ast_strdupa(p->secret);
07878       stringp = tmppw;
07879       while((tmppw = strsep(&stringp, ";"))) {
07880          MD5Init(&md5);
07881          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07882          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07883          MD5Final(digest, &md5);
07884          /* If they support md5, authenticate with it.  */
07885          for (x=0;x<16;x++)
07886             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
07887          if (!strcasecmp(requeststr, md5secret)) {
07888             res = 0;
07889             break;
07890          }
07891       }
07892    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07893       if (!strcmp(secret, p->secret))
07894          res = 0;
07895    }
07896    return res;
07897 }

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

Definition at line 4648 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

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

04649 {
04650 #ifdef SCHED_MULTITHREADED
04651    if (schedule_action(__auto_congest, data))
04652 #endif      
04653       __auto_congest(data);
04654    return 0;
04655 }

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

Definition at line 8995 of file chan_iax2.c.

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

08996 {
08997    int callno = (int)(long)(data);
08998    ast_mutex_lock(&iaxsl[callno]);
08999    if (iaxs[callno]) {
09000       iaxs[callno]->autoid = -1;
09001    }
09002    ast_mutex_unlock(&iaxsl[callno]);
09003 #ifdef SCHED_MULTITHREADED
09004    if (schedule_action(__auto_hangup, data))
09005 #endif      
09006       __auto_hangup(data);
09007    return 0;
09008 }

static void build_callno_limits ( struct ast_variable v  )  [static]

Definition at line 2441 of file chan_iax2.c.

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

Referenced by set_config().

02442 {
02443    struct addr_range *addr_range = NULL;
02444    struct addr_range tmp;
02445    struct ast_ha *ha;
02446    int limit;
02447    int error;
02448    int found;
02449 
02450    for (; v; v = v->next) {
02451       limit = -1;
02452       error = 0;
02453       found = 0;
02454       ha = ast_append_ha("permit", v->name, NULL, &error);
02455 
02456       /* check for valid config information */
02457       if (error) {
02458          ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02459          continue;
02460       } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02461          ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02462          ast_free_ha(ha);
02463          continue;
02464       }
02465 
02466       ast_copy_ha(ha, &tmp.ha);
02467       /* find or create the addr_range */
02468       if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02469          ao2_lock(addr_range);
02470          found = 1;
02471       } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02472          ast_free_ha(ha);
02473          return; /* out of memory */
02474       }
02475 
02476       /* copy over config data into addr_range object */
02477       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
02478       ast_free_ha(ha); /* cleanup the tmp ha */
02479       addr_range->limit = limit;
02480       addr_range->delme = 0;
02481 
02482       /* cleanup */
02483       if (found) {
02484          ao2_unlock(addr_range);
02485       } else {
02486          ao2_link(callno_limits, addr_range);
02487       }
02488       ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02489    }
02490 }

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

Definition at line 12118 of file chan_iax2.c.

References ast_calloc, and ast_copy_string().

Referenced by build_user().

12119 {
12120    struct iax2_context *con;
12121 
12122    if ((con = ast_calloc(1, sizeof(*con))))
12123       ast_copy_string(con->context, context, sizeof(con->context));
12124    
12125    return con;
12126 }

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

Definition at line 6145 of file chan_iax2.c.

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

Referenced by build_encryption_keys(), and iax2_key_rotate().

06146 {
06147    /* it is required to hold the corresponding decrypt key to our encrypt key
06148     * in the pvt struct because queued frames occasionally need to be decrypted and
06149     * re-encrypted when updated for a retransmission */
06150    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06151    ast_aes_set_encrypt_key(digest, &pvt->ecx);
06152    ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06153 }

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

Definition at line 6139 of file chan_iax2.c.

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

Referenced by authenticate(), and decrypt_frame().

06140 {
06141    build_ecx_key(digest, pvt);
06142    ast_aes_set_decrypt_key(digest, &pvt->dcx);
06143 }

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

References ao2_alloc, ao2_find, ast_append_ha(), ast_callerid_split(), ast_clear_flag64, ast_copy_flags64, ast_dnsmgr_lookup(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_false(), ast_free_ha(), ast_get_ip(), ast_log(), ast_parse_allow_disallow(), ast_sched_thread_del, ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_to_sin, ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_true(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cid_name, cid_num, context, iax2_peer::dbsecret, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, inet_aton(), ast_variable::lineno, LOG_WARNING, mailbox, mwi_event_cb(), ast_variable::name, iax2_peer::name, ast_variable::next, OBJ_POINTER, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), iax2_peer::peercontext, peers, prefs, S_OR, sched, secret, strsep(), timer, unlink_peer(), ast_variable::value, and zonetag.

12269 {
12270    struct iax2_peer *peer = NULL;
12271    struct ast_ha *oldha = NULL;
12272    int maskfound = 0;
12273    int found = 0;
12274    int firstpass = 1;
12275    struct iax2_peer tmp_peer = {
12276       .name = name,
12277    };
12278 
12279    if (!temponly) {
12280       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
12281       if (peer && !ast_test_flag64(peer, IAX_DELME))
12282          firstpass = 0;
12283    }
12284 
12285    if (peer) {
12286       found++;
12287       if (firstpass) {
12288          oldha = peer->ha;
12289          peer->ha = NULL;
12290       }
12291       unlink_peer(peer);
12292    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12293       peer->expire = -1;
12294       peer->pokeexpire = -1;
12295       peer->sockfd = defaultsockfd;
12296       if (ast_string_field_init(peer, 32))
12297          peer = peer_unref(peer);
12298    }
12299 
12300    if (peer) {
12301       if (firstpass) {
12302          ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12303          peer->encmethods = iax2_encryption;
12304          peer->adsi = adsi;
12305          ast_string_field_set(peer,secret,"");
12306          if (!found) {
12307             ast_string_field_set(peer, name, name);
12308             ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12309             peer->expiry = min_reg_expire;
12310          }
12311          peer->prefs = prefs;
12312          peer->capability = iax2_capability;
12313          peer->smoothing = 0;
12314          peer->pokefreqok = DEFAULT_FREQ_OK;
12315          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12316          peer->maxcallno = 0;
12317          peercnt_modify(0, 0, &peer->addr);
12318          peer->calltoken_required = CALLTOKEN_DEFAULT;
12319          ast_string_field_set(peer,context,"");
12320          ast_string_field_set(peer,peercontext,"");
12321          ast_clear_flag64(peer, IAX_HASCALLERID);
12322          ast_string_field_set(peer, cid_name, "");
12323          ast_string_field_set(peer, cid_num, "");
12324          ast_string_field_set(peer, mohinterpret, mohinterpret);
12325          ast_string_field_set(peer, mohsuggest, mohsuggest);
12326       }
12327 
12328       if (!v) {
12329          v = alt;
12330          alt = NULL;
12331       }
12332       while(v) {
12333          if (!strcasecmp(v->name, "secret")) {
12334             ast_string_field_set(peer, secret, v->value);
12335          } else if (!strcasecmp(v->name, "mailbox")) {
12336             ast_string_field_set(peer, mailbox, v->value);
12337          } else if (!strcasecmp(v->name, "hasvoicemail")) {
12338             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12339                ast_string_field_set(peer, mailbox, name);
12340             }
12341          } else if (!strcasecmp(v->name, "mohinterpret")) {
12342             ast_string_field_set(peer, mohinterpret, v->value);
12343          } else if (!strcasecmp(v->name, "mohsuggest")) {
12344             ast_string_field_set(peer, mohsuggest, v->value);
12345          } else if (!strcasecmp(v->name, "dbsecret")) {
12346             ast_string_field_set(peer, dbsecret, v->value);
12347          } else if (!strcasecmp(v->name, "trunk")) {
12348             ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 
12349             if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12350                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12351                ast_clear_flag64(peer, IAX_TRUNK);
12352             }
12353          } else if (!strcasecmp(v->name, "auth")) {
12354             peer->authmethods = get_auth_methods(v->value);
12355          } else if (!strcasecmp(v->name, "encryption")) {
12356             peer->encmethods |= get_encrypt_methods(v->value);
12357             if (!peer->encmethods) {
12358                ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12359             }
12360          } else if (!strcasecmp(v->name, "forceencryption")) {
12361             if (ast_false(v->value)) {
12362                ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12363             } else {
12364                peer->encmethods |= get_encrypt_methods(v->value);
12365                if (peer->encmethods) {
12366                   ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12367                }
12368             }
12369          } else if (!strcasecmp(v->name, "transfer")) {
12370             if (!strcasecmp(v->value, "mediaonly")) {
12371                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12372             } else if (ast_true(v->value)) {
12373                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12374             } else
12375                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12376          } else if (!strcasecmp(v->name, "jitterbuffer")) {
12377             ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12378          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12379             ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12380          } else if (!strcasecmp(v->name, "host")) {
12381             if (!strcasecmp(v->value, "dynamic")) {
12382                /* They'll register with us */
12383                ast_set_flag64(peer, IAX_DYNAMIC);
12384                if (!found) {
12385                   /* Initialize stuff iff we're not found, otherwise
12386                      we keep going with what we had */
12387                   if (ast_sockaddr_port(&peer->addr)) {
12388                      peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12389                   }
12390                   ast_sockaddr_setnull(&peer->addr);
12391                }
12392             } else {
12393                /* Non-dynamic.  Make sure we become that way if we're not */
12394                ast_sched_thread_del(sched, peer->expire);
12395                ast_clear_flag64(peer, IAX_DYNAMIC);
12396                if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12397                   return peer_unref(peer);
12398                if (!ast_sockaddr_port(&peer->addr)) {
12399                   ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12400                }
12401             }
12402             if (!maskfound)
12403                inet_aton("255.255.255.255", &peer->mask);
12404          } else if (!strcasecmp(v->name, "defaultip")) {
12405             struct ast_sockaddr peer_defaddr_tmp;
12406 
12407             if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12408                return peer_unref(peer);
12409             }
12410             ast_sockaddr_to_sin(&peer_defaddr_tmp,
12411                       &peer->defaddr);
12412          } else if (!strcasecmp(v->name, "sourceaddress")) {
12413             peer_set_srcaddr(peer, v->value);
12414          } else if (!strcasecmp(v->name, "permit") ||
12415                   !strcasecmp(v->name, "deny")) {
12416             peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12417          } else if (!strcasecmp(v->name, "mask")) {
12418             maskfound++;
12419             inet_aton(v->value, &peer->mask);
12420          } else if (!strcasecmp(v->name, "context")) {
12421             ast_string_field_set(peer, context, v->value);
12422          } else if (!strcasecmp(v->name, "regexten")) {
12423             ast_string_field_set(peer, regexten, v->value);
12424          } else if (!strcasecmp(v->name, "peercontext")) {
12425             ast_string_field_set(peer, peercontext, v->value);
12426          } else if (!strcasecmp(v->name, "port")) {
12427             if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12428                peer->defaddr.sin_port = htons(atoi(v->value));
12429             } else {
12430                ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12431             }
12432          } else if (!strcasecmp(v->name, "username")) {
12433             ast_string_field_set(peer, username, v->value);
12434          } else if (!strcasecmp(v->name, "allow")) {
12435             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12436          } else if (!strcasecmp(v->name, "disallow")) {
12437             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12438          } else if (!strcasecmp(v->name, "callerid")) {
12439             if (!ast_strlen_zero(v->value)) {
12440                char name2[80];
12441                char num2[80];
12442                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12443                ast_string_field_set(peer, cid_name, name2);
12444                ast_string_field_set(peer, cid_num, num2);
12445             } else {
12446                ast_string_field_set(peer, cid_name, "");
12447                ast_string_field_set(peer, cid_num, "");
12448             }
12449             ast_set_flag64(peer, IAX_HASCALLERID);
12450          } else if (!strcasecmp(v->name, "fullname")) {
12451             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12452             ast_set_flag64(peer, IAX_HASCALLERID);
12453          } else if (!strcasecmp(v->name, "cid_number")) {
12454             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12455             ast_set_flag64(peer, IAX_HASCALLERID);
12456          } else if (!strcasecmp(v->name, "sendani")) {
12457             ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12458          } else if (!strcasecmp(v->name, "inkeys")) {
12459             ast_string_field_set(peer, inkeys, v->value);
12460          } else if (!strcasecmp(v->name, "outkey")) {
12461             ast_string_field_set(peer, outkey, v->value);
12462          } else if (!strcasecmp(v->name, "qualify")) {
12463             if (!strcasecmp(v->value, "no")) {
12464                peer->maxms = 0;
12465             } else if (!strcasecmp(v->value, "yes")) {
12466                peer->maxms = DEFAULT_MAXMS;
12467             } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12468                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);
12469                peer->maxms = 0;
12470             }
12471          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12472             peer->smoothing = ast_true(v->value);
12473          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12474             if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12475                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);
12476             }
12477          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12478             if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12479                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);
12480             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
12481          } else if (!strcasecmp(v->name, "timezone")) {
12482             ast_string_field_set(peer, zonetag, v->value);
12483          } else if (!strcasecmp(v->name, "adsi")) {
12484             peer->adsi = ast_true(v->value);
12485          } else if (!strcasecmp(v->name, "connectedline")) {
12486             if (ast_true(v->value)) {
12487                ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12488             } else if (!strcasecmp(v->value, "send")) {
12489                ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12490                ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12491             } else if (!strcasecmp(v->value, "receive")) {
12492                ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12493                ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12494             } else {
12495                ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12496             }
12497          } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12498             if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12499                ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12500             } else {
12501                peercnt_modify(1, peer->maxcallno, &peer->addr);
12502             }
12503          } else if (!strcasecmp(v->name, "requirecalltoken")) {
12504             /* default is required unless in optional ip list */
12505             if (ast_false(v->value)) {
12506                peer->calltoken_required = CALLTOKEN_NO;
12507             } else if (!strcasecmp(v->value, "auto")) {
12508                peer->calltoken_required = CALLTOKEN_AUTO;
12509             } else if (ast_true(v->value)) {
12510                peer->calltoken_required = CALLTOKEN_YES;
12511             } else {
12512                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12513             }
12514          } /* else if (strcasecmp(v->name,"type")) */
12515          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
12516          v = v->next;
12517          if (!v) {
12518             v = alt;
12519             alt = NULL;
12520          }
12521       }
12522       if (!peer->authmethods)
12523          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12524       ast_clear_flag64(peer, IAX_DELME);
12525    }
12526 
12527    if (oldha)
12528       ast_free_ha(oldha);
12529 
12530    if (!ast_strlen_zero(peer->mailbox)) {
12531       char *mailbox, *context;
12532       context = mailbox = ast_strdupa(peer->mailbox);
12533       strsep(&context, "@");
12534       if (ast_strlen_zero(context))
12535          context = "default";
12536       peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12537          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12538          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12539          AST_EVENT_IE_END);
12540    }
12541 
12542    return peer;
12543 }

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

Definition at line 6129 of file chan_iax2.c.

References ast_random().

Referenced by build_ecx_key(), and update_packet().

06130 {
06131    long tmp;
06132    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06133       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06134       buf += sizeof(tmp);
06135       len -= sizeof(tmp);
06136    }
06137 }

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

References ao2_alloc, ao2_find, ao2_unlink, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag64, ast_copy_flags64, ast_false(), ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_true(), ast_variable_new(), build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cid_name, cid_num, cleanup(), iax2_user::dbsecret, format, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_IMMEDIATE, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, ast_variable::lineno, LOG_WARNING, ast_variable::name, iax2_user::name, ast_variable::next, OBJ_POINTER, parkinglot, prefs, secret, timer, user, user_destructor(), user_unref(), users, and ast_variable::value.

12560 {
12561    struct iax2_user *user = NULL;
12562    struct iax2_context *con, *conl = NULL;
12563    struct ast_ha *oldha = NULL;
12564    struct iax2_context *oldcon = NULL;
12565    int format;
12566    int firstpass=1;
12567    int oldcurauthreq = 0;
12568    char *varname = NULL, *varval = NULL;
12569    struct ast_variable *tmpvar = NULL;
12570    struct iax2_user tmp_user = {
12571       .name = name,
12572    };
12573 
12574    if (!temponly) {
12575       user = ao2_find(users, &tmp_user, OBJ_POINTER);
12576       if (user && !ast_test_flag64(user, IAX_DELME))
12577          firstpass = 0;
12578    }
12579 
12580    if (user) {
12581       if (firstpass) {
12582          oldcurauthreq = user->curauthreq;
12583          oldha = user->ha;
12584          oldcon = user->contexts;
12585          user->ha = NULL;
12586          user->contexts = NULL;
12587       }
12588       /* Already in the list, remove it and it will be added back (or FREE'd) */
12589       ao2_unlink(users, user);
12590    } else {
12591       user = ao2_alloc(sizeof(*user), user_destructor);
12592    }
12593    
12594    if (user) {
12595       if (firstpass) {
12596          ast_string_field_free_memory(user);
12597          memset(user, 0, sizeof(struct iax2_user));
12598          if (ast_string_field_init(user, 32)) {
12599             user = user_unref(user);
12600             goto cleanup;
12601          }
12602          user->maxauthreq = maxauthreq;
12603          user->curauthreq = oldcurauthreq;
12604          user->prefs = prefs;
12605          user->capability = iax2_capability;
12606          user->encmethods = iax2_encryption;
12607          user->adsi = adsi;
12608          user->calltoken_required = CALLTOKEN_DEFAULT;
12609          ast_string_field_set(user, name, name);
12610          ast_string_field_set(user, language, language);
12611          ast_copy_flags64(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12612          ast_clear_flag64(user, IAX_HASCALLERID);
12613          ast_string_field_set(user, cid_name, "");
12614          ast_string_field_set(user, cid_num, "");
12615          ast_string_field_set(user, accountcode, accountcode);
12616          ast_string_field_set(user, mohinterpret, mohinterpret);
12617          ast_string_field_set(user, mohsuggest, mohsuggest);
12618       }
12619       if (!v) {
12620          v = alt;
12621          alt = NULL;
12622       }
12623       while(v) {
12624          if (!strcasecmp(v->name, "context")) {
12625             con = build_context(v->value);
12626             if (con) {
12627                if (conl)
12628                   conl->next = con;
12629                else
12630                   user->contexts = con;
12631                conl = con;
12632             }
12633          } else if (!strcasecmp(v->name, "permit") ||
12634                   !strcasecmp(v->name, "deny")) {
12635             user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12636          } else if (!strcasecmp(v->name, "setvar")) {
12637             varname = ast_strdupa(v->value);
12638             if (varname && (varval = strchr(varname,'='))) {
12639                *varval = '\0';
12640                varval++;
12641                if((tmpvar = ast_variable_new(varname, varval, ""))) {
12642                   tmpvar->next = user->vars; 
12643                   user->vars = tmpvar;
12644                }
12645             }
12646          } else if (!strcasecmp(v->name, "allow")) {
12647             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12648          } else if (!strcasecmp(v->name, "disallow")) {
12649             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12650          } else if (!strcasecmp(v->name, "trunk")) {
12651             ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 
12652             if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
12653                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12654                ast_clear_flag64(user, IAX_TRUNK);
12655             }
12656          } else if (!strcasecmp(v->name, "auth")) {
12657             user->authmethods = get_auth_methods(v->value);
12658          } else if (!strcasecmp(v->name, "encryption")) {
12659             user->encmethods |= get_encrypt_methods(v->value);
12660             if (!user->encmethods) {
12661                ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12662             }
12663          } else if (!strcasecmp(v->name, "forceencryption")) {
12664             if (ast_false(v->value)) {
12665                ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12666             } else {
12667                user->encmethods |= get_encrypt_methods(v->value);
12668                if (user->encmethods) {
12669                   ast_set_flag64(user, IAX_FORCE_ENCRYPT);
12670                }
12671             }
12672          } else if (!strcasecmp(v->name, "transfer")) {
12673             if (!strcasecmp(v->value, "mediaonly")) {
12674                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12675             } else if (ast_true(v->value)) {
12676                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12677             } else
12678                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12679          } else if (!strcasecmp(v->name, "codecpriority")) {
12680             if(!strcasecmp(v->value, "caller"))
12681                ast_set_flag64(user, IAX_CODEC_USER_FIRST);
12682             else if(!strcasecmp(v->value, "disabled"))
12683                ast_set_flag64(user, IAX_CODEC_NOPREFS);
12684             else if(!strcasecmp(v->value, "reqonly")) {
12685                ast_set_flag64(user, IAX_CODEC_NOCAP);
12686                ast_set_flag64(user, IAX_CODEC_NOPREFS);
12687             }
12688          } else if (!strcasecmp(v->name, "immediate")) {
12689             ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
12690          } else if (!strcasecmp(v->name, "jitterbuffer")) {
12691             ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
12692          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12693             ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12694          } else if (!strcasecmp(v->name, "dbsecret")) {
12695             ast_string_field_set(user, dbsecret, v->value);
12696          } else if (!strcasecmp(v->name, "secret")) {
12697             if (!ast_strlen_zero(user->secret)) {
12698                char *old = ast_strdupa(user->secret);
12699 
12700                ast_string_field_build(user, secret, "%s;%s", old, v->value);
12701             } else
12702                ast_string_field_set(user, secret, v->value);
12703          } else if (!strcasecmp(v->name, "callerid")) {
12704             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12705                char name2[80];
12706                char num2[80];
12707                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12708                ast_string_field_set(user, cid_name, name2);
12709                ast_string_field_set(user, cid_num, num2);
12710                ast_set_flag64(user, IAX_HASCALLERID);
12711             } else {
12712                ast_clear_flag64(user, IAX_HASCALLERID);
12713                ast_string_field_set(user, cid_name, "");
12714                ast_string_field_set(user, cid_num, "");
12715             }
12716          } else if (!strcasecmp(v->name, "fullname")) {
12717             if (!ast_strlen_zero(v->value)) {
12718                ast_string_field_set(user, cid_name, v->value);
12719                ast_set_flag64(user, IAX_HASCALLERID);
12720             } else {
12721                ast_string_field_set(user, cid_name, "");
12722                if (ast_strlen_zero(user->cid_num))
12723                   ast_clear_flag64(user, IAX_HASCALLERID);
12724             }
12725          } else if (!strcasecmp(v->name, "cid_number")) {
12726             if (!ast_strlen_zero(v->value)) {
12727                ast_string_field_set(user, cid_num, v->value);
12728                ast_set_flag64(user, IAX_HASCALLERID);
12729             } else {
12730                ast_string_field_set(user, cid_num, "");
12731                if (ast_strlen_zero(user->cid_name))
12732                   ast_clear_flag64(user, IAX_HASCALLERID);
12733             }
12734          } else if (!strcasecmp(v->name, "accountcode")) {
12735             ast_string_field_set(user, accountcode, v->value);
12736          } else if (!strcasecmp(v->name, "mohinterpret")) {
12737             ast_string_field_set(user, mohinterpret, v->value);
12738          } else if (!strcasecmp(v->name, "mohsuggest")) {
12739             ast_string_field_set(user, mohsuggest, v->value);
12740          } else if (!strcasecmp(v->name, "parkinglot")) {
12741             ast_string_field_set(user, parkinglot, v->value);
12742          } else if (!strcasecmp(v->name, "language")) {
12743             ast_string_field_set(user, language, v->value);
12744          } else if (!strcasecmp(v->name, "amaflags")) {
12745             format = ast_cdr_amaflags2int(v->value);
12746             if (format < 0) {
12747                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12748             } else {
12749                user->amaflags = format;
12750             }
12751          } else if (!strcasecmp(v->name, "inkeys")) {
12752             ast_string_field_set(user, inkeys, v->value);
12753          } else if (!strcasecmp(v->name, "maxauthreq")) {
12754             user->maxauthreq = atoi(v->value);
12755             if (user->maxauthreq < 0)
12756                user->maxauthreq = 0;
12757          } else if (!strcasecmp(v->name, "adsi")) {
12758             user->adsi = ast_true(v->value);
12759          } else if (!strcasecmp(v->name, "connectedline")) {
12760             if (ast_true(v->value)) {
12761                ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12762             } else if (!strcasecmp(v->value, "send")) {
12763                ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
12764                ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
12765             } else if (!strcasecmp(v->value, "receive")) {
12766                ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
12767                ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
12768             } else {
12769                ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12770             }
12771          } else if (!strcasecmp(v->name, "requirecalltoken")) {
12772             /* default is required unless in optional ip list */
12773             if (ast_false(v->value)) {
12774                user->calltoken_required = CALLTOKEN_NO;
12775             } else if (!strcasecmp(v->value, "auto")) {
12776                user->calltoken_required = CALLTOKEN_AUTO;
12777             } else if (ast_true(v->value)) {
12778                user->calltoken_required = CALLTOKEN_YES;
12779             } else {
12780                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12781             }
12782          } /* else if (strcasecmp(v->name,"type")) */
12783          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
12784          v = v->next;
12785          if (!v) {
12786             v = alt;
12787             alt = NULL;
12788          }
12789       }
12790       if (!user->authmethods) {
12791          if (!ast_strlen_zero(user->secret)) {
12792             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12793             if (!ast_strlen_zero(user->inkeys))
12794                user->authmethods |= IAX_AUTH_RSA;
12795          } else if (!ast_strlen_zero(user->inkeys)) {
12796             user->authmethods = IAX_AUTH_RSA;
12797          } else {
12798             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12799          }
12800       }
12801       ast_clear_flag64(user, IAX_DELME);
12802    }
12803 cleanup:
12804    if (oldha)
12805       ast_free_ha(oldha);
12806    if (oldcon)
12807       free_context(oldcon);
12808    return user;
12809 }

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

Definition at line 13443 of file chan_iax2.c.

References add_empty_calltoken_ie(), ARRAY_LEN, ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_trylock, ast_mutex_unlock, ast_strdupa, ast_string_field_set, ast_strlen_zero(), chan_iax2_pvt::capability, create_addr(), 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, LOG_WARNING, NEW_FORCE, parse_dial_string(), secret, and send_command().

Referenced by find_cache().

13444 {
13445    struct sockaddr_in sin;
13446    int x;
13447    int callno;
13448    struct iax_ie_data ied;
13449    struct create_addr_info cai;
13450    struct parsed_dial_string pds;
13451    char *tmpstr;
13452 
13453    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13454       /* Look for an *exact match* call.  Once a call is negotiated, it can only
13455          look up entries for a single context */
13456       if (!ast_mutex_trylock(&iaxsl[x])) {
13457          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13458             return x;
13459          ast_mutex_unlock(&iaxsl[x]);
13460       }
13461    }
13462 
13463    /* No match found, we need to create a new one */
13464 
13465    memset(&cai, 0, sizeof(cai));
13466    memset(&ied, 0, sizeof(ied));
13467    memset(&pds, 0, sizeof(pds));
13468 
13469    tmpstr = ast_strdupa(data);
13470    parse_dial_string(tmpstr, &pds);
13471 
13472    if (ast_strlen_zero(pds.peer)) {
13473       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13474       return -1;
13475    }
13476 
13477    /* Populate our address from the given */
13478    if (create_addr(pds.peer, NULL, &sin, &cai))
13479       return -1;
13480 
13481    ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13482       pds.peer, pds.username, pds.password, pds.context);
13483 
13484    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13485    if (callno < 1) {
13486       ast_log(LOG_WARNING, "Unable to create call\n");
13487       return -1;
13488    }
13489 
13490    ast_string_field_set(iaxs[callno], dproot, data);
13491    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13492 
13493    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13494    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13495    /* the string format is slightly different from a standard dial string,
13496       because the context appears in the 'exten' position
13497    */
13498    if (pds.exten)
13499       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13500    if (pds.username)
13501       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13502    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13503    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13504    /* Keep password handy */
13505    if (pds.password)
13506       ast_string_field_set(iaxs[callno], secret, pds.password);
13507    if (pds.key)
13508       ast_string_field_set(iaxs[callno], outkey, pds.key);
13509    /* Start the call going */
13510    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
13511    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13512 
13513    return callno;
13514 }

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

Definition at line 5981 of file chan_iax2.c.

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

Referenced by schedule_delivery().

05982 {
05983    /* Returns where in "receive time" we are.  That is, how many ms
05984       since we received (or would have received) the frame with timestamp 0 */
05985    int ms;
05986 #ifdef IAXTESTS
05987    int jit;
05988 #endif /* IAXTESTS */
05989    /* Setup rxcore if necessary */
05990    if (ast_tvzero(p->rxcore)) {
05991       p->rxcore = ast_tvnow();
05992       if (iaxdebug)
05993          ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
05994                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
05995       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
05996 #if 1
05997       if (iaxdebug)
05998          ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
05999                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06000 #endif
06001    }
06002 
06003    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06004 #ifdef IAXTESTS
06005    if (test_jit) {
06006       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06007          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06008          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06009             jit = -jit;
06010          ms += jit;
06011       }
06012    }
06013    if (test_late) {
06014       ms += test_late;
06015       test_late = 0;
06016    }
06017 #endif /* IAXTESTS */
06018    return ms;
06019 }

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

Definition at line 5848 of file chan_iax2.c.

References ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_samp2tv(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, f, iaxs, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, and chan_iax2_pvt::offset.

Referenced by iax2_send(), and socket_process().

05849 {
05850    int ms;
05851    int voice = 0;
05852    int genuine = 0;
05853    int adjust;
05854    int rate = ast_format_rate(f->subclass.codec) / 1000;
05855    struct timeval *delivery = NULL;
05856 
05857 
05858    /* What sort of frame do we have?: voice is self-explanatory
05859       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
05860       non-genuine frames are CONTROL frames [ringing etc], DTMF
05861       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
05862       the others need a timestamp slaved to the voice frames so that they go in sequence
05863    */
05864    if (f) {
05865       if (f->frametype == AST_FRAME_VOICE) {
05866          voice = 1;
05867          delivery = &f->delivery;
05868       } else if (f->frametype == AST_FRAME_IAX) {
05869          genuine = 1;
05870       } else if (f->frametype == AST_FRAME_CNG) {
05871          p->notsilenttx = 0;  
05872       }
05873    }
05874    if (ast_tvzero(p->offset)) {
05875       p->offset = ast_tvnow();
05876       /* Round to nearest 20ms for nice looking traces */
05877       p->offset.tv_usec -= p->offset.tv_usec % 20000;
05878    }
05879    /* If the timestamp is specified, just send it as is */
05880    if (ts)
05881       return ts;
05882    /* If we have a time that the frame arrived, always use it to make our timestamp */
05883    if (delivery && !ast_tvzero(*delivery)) {
05884       ms = ast_tvdiff_ms(*delivery, p->offset);
05885       if (ms < 0) {
05886          ms = 0;
05887       }
05888       if (iaxdebug)
05889          ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05890    } else {
05891       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05892       if (ms < 0)
05893          ms = 0;
05894       if (voice) {
05895          /* On a voice frame, use predicted values if appropriate */
05896          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05897             /* Adjust our txcore, keeping voice and non-voice synchronized */
05898             /* AN EXPLANATION:
05899                When we send voice, we usually send "calculated" timestamps worked out
05900                on the basis of the number of samples sent. When we send other frames,
05901                we usually send timestamps worked out from the real clock.
05902                The problem is that they can tend to drift out of step because the 
05903                   source channel's clock and our clock may not be exactly at the same rate.
05904                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
05905                for this call.  Moving it adjusts timestamps for non-voice frames.
05906                We make the adjustment in the style of a moving average.  Each time we
05907                adjust p->offset by 10% of the difference between our clock-derived
05908                timestamp and the predicted timestamp.  That's why you see "10000"
05909                below even though IAX2 timestamps are in milliseconds.
05910                The use of a moving average avoids offset moving too radically.
05911                Generally, "adjust" roams back and forth around 0, with offset hardly
05912                changing at all.  But if a consistent different starts to develop it
05913                will be eliminated over the course of 10 frames (200-300msecs) 
05914             */
05915             adjust = (ms - p->nextpred);
05916             if (adjust < 0)
05917                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05918             else if (adjust > 0)
05919                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05920 
05921             if (!p->nextpred) {
05922                p->nextpred = ms; /*f->samples / rate;*/
05923                if (p->nextpred <= p->lastsent)
05924                   p->nextpred = p->lastsent + 3;
05925             }
05926             ms = p->nextpred;
05927          } else {
05928                 /* in this case, just use the actual
05929             * time, since we're either way off
05930             * (shouldn't happen), or we're  ending a
05931             * silent period -- and seed the next
05932             * predicted time.  Also, round ms to the
05933             * next multiple of frame size (so our
05934             * silent periods are multiples of
05935             * frame size too) */
05936 
05937             if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05938                ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05939                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05940 
05941             if (f->samples >= rate) /* check to make sure we don't core dump */
05942             {
05943                int diff = ms % (f->samples / rate);
05944                if (diff)
05945                    ms += f->samples/rate - diff;
05946             }
05947 
05948             p->nextpred = ms;
05949             p->notsilenttx = 1;
05950          }
05951       } else if ( f->frametype == AST_FRAME_VIDEO ) {
05952          /*
05953          * IAX2 draft 03 says that timestamps MUST be in order.
05954          * It does not say anything about several frames having the same timestamp
05955          * When transporting video, we can have a frame that spans multiple iax packets
05956          * (so called slices), so it would make sense to use the same timestamp for all of
05957          * them
05958          * We do want to make sure that frames don't go backwards though
05959          */
05960          if ( (unsigned int)ms < p->lastsent )
05961             ms = p->lastsent;
05962       } else {
05963          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
05964             it's a genuine frame */
05965          if (genuine) {
05966             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
05967             if (ms <= p->lastsent)
05968                ms = p->lastsent + 3;
05969          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05970             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
05971             ms = p->lastsent + 3;
05972          }
05973       }
05974    }
05975    p->lastsent = ms;
05976    if (voice)
05977       p->nextpred = p->nextpred + f->samples / rate;
05978    return ms;
05979 }

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

Definition at line 5804 of file chan_iax2.c.

References ast_tvdiff_ms(), ast_tvzero(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lasttxtime, MAX_TIMESTAMP_SKEW, iax2_trunk_peer::trunkact, and iax2_trunk_peer::txtrunktime.

Referenced by send_trunk().

05805 {
05806    unsigned long int mssincetx; /* unsigned to handle overflows */
05807    long int ms, pred;
05808 
05809    tpeer->trunkact = *now;
05810    mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05811    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05812       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
05813       tpeer->txtrunktime = *now;
05814       tpeer->lastsent = 999999;
05815    }
05816    /* Update last transmit time now */
05817    tpeer->lasttxtime = *now;
05818    
05819    /* Calculate ms offset */
05820    ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05821    /* Predict from last value */
05822    pred = tpeer->lastsent + sampms;
05823    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05824       ms = pred;
05825    
05826    /* We never send the same timestamp twice, so fudge a little if we must */
05827    if (ms == tpeer->lastsent)
05828       ms = tpeer->lastsent + 1;
05829    tpeer->lastsent = ms;
05830    return ms;
05831 }

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

Definition at line 2657 of file chan_iax2.c.

References ast_random().

Referenced by create_callno_pools().

02658 {
02659    return abs(ast_random());
02660 }

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

Definition at line 2189 of file chan_iax2.c.

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

Referenced by handle_call_token().

02190 {
02191    struct addr_range *addr_range;
02192    struct iax2_peer *peer = NULL;
02193    struct iax2_user *user = NULL;
02194    /* if no username is given, check for guest accounts */
02195    const char *find = S_OR(name, "guest");
02196    int res = 1;  /* required by default */
02197    int optional = 0;
02198    enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02199    /* There are only two cases in which calltoken validation is not required.
02200     * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
02201     *         the peer definition has not set the requirecalltoken option.
02202     * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
02203     */
02204 
02205    /* ----- Case 1 ----- */
02206    if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02207       ao2_ref(addr_range, -1);
02208       optional = 1;
02209    }
02210 
02211    /* ----- Case 2 ----- */
02212    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02213       calltoken_required = user->calltoken_required;
02214    } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02215       calltoken_required = user->calltoken_required;
02216    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02217       calltoken_required = peer->calltoken_required;
02218    } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02219       calltoken_required = peer->calltoken_required;
02220    }
02221 
02222    if (peer) {
02223       peer_unref(peer);
02224    }
02225    if (user) {
02226       user_unref(user);
02227    }
02228 
02229    ast_debug(1, "Determining if address %s with username %s requires calltoken validation.  Optional = %d  calltoken_required = %d \n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required);
02230    if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02231       (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02232       res = 0;
02233    }
02234 
02235    return res;
02236 }

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

Definition at line 7499 of file chan_iax2.c.

References chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags64, ast_db_get(), ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag64, ast_set_flag64, ast_shrink_phone_number(), ast_sockaddr_from_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_variable_new(), chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, chan_iax2_pvt::capability, iax_ies::capability, cid_name, cid_num, iax_ies::codec_prefs, chan_iax2_pvt::context, context, DEFAULT_CONTEXT, iax_ies::dnid, chan_iax2_pvt::encmethods, exten, ast_variable::file, iax_ies::format, globalflags, iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_IMMEDIATE, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iax_ies::language, LOG_WARNING, ast_variable::name, ast_variable::next, parkinglot, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, chan_iax2_pvt::prefs, prefs, iax_ies::rdnis, realtime_user(), secret, user, user_unref(), iax_ies::username, users, ast_variable::value, chan_iax2_pvt::vars, iax_ies::version, and version.

Referenced by socket_process().

07500 {
07501    /* Start pessimistic */
07502    int res = -1;
07503    int version = 2;
07504    struct iax2_user *user = NULL, *best = NULL;
07505    int bestscore = 0;
07506    int gotcapability = 0;
07507    struct ast_variable *v = NULL, *tmpvar = NULL;
07508    struct ao2_iterator i;
07509    struct ast_sockaddr addr;
07510 
07511    if (!iaxs[callno])
07512       return res;
07513    if (ies->called_number)
07514       ast_string_field_set(iaxs[callno], exten, ies->called_number);
07515    if (ies->calling_number) {
07516       if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 
07517          ast_shrink_phone_number(ies->calling_number);
07518       }
07519       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07520    }
07521    if (ies->calling_name)
07522       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07523    if (ies->calling_ani)
07524       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07525    if (ies->dnid)
07526       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07527    if (ies->rdnis)
07528       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07529    if (ies->called_context)
07530       ast_string_field_set(iaxs[callno], context, ies->called_context);
07531    if (ies->language)
07532       ast_string_field_set(iaxs[callno], language, ies->language);
07533    if (ies->username)
07534       ast_string_field_set(iaxs[callno], username, ies->username);
07535    if (ies->calling_ton > -1)
07536       iaxs[callno]->calling_ton = ies->calling_ton;
07537    if (ies->calling_tns > -1)
07538       iaxs[callno]->calling_tns = ies->calling_tns;
07539    if (ies->calling_pres > -1)
07540       iaxs[callno]->calling_pres = ies->calling_pres;
07541    if (ies->format)
07542       iaxs[callno]->peerformat = ies->format;
07543    if (ies->adsicpe)
07544       iaxs[callno]->peeradsicpe = ies->adsicpe;
07545    if (ies->capability) {
07546       gotcapability = 1;
07547       iaxs[callno]->peercapability = ies->capability;
07548    } 
07549    if (ies->version)
07550       version = ies->version;
07551 
07552    /* Use provided preferences until told otherwise for actual preferences */
07553    if (ies->codec_prefs) {
07554       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07555       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07556    }
07557 
07558    if (!gotcapability) 
07559       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07560    if (version > IAX_PROTO_VERSION) {
07561       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
07562          ast_inet_ntoa(sin->sin_addr), version);
07563       return res;
07564    }
07565    /* Search the userlist for a compatible entry, and fill in the rest */
07566    i = ao2_iterator_init(users, 0);
07567    ast_sockaddr_from_sin(&addr, sin);
07568    while ((user = ao2_iterator_next(&i))) {
07569       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
07570          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
07571          && ast_apply_ha(user->ha, &addr)    /* Access is permitted from this IP */
07572          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
07573               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
07574          if (!ast_strlen_zero(iaxs[callno]->username)) {
07575             /* Exact match, stop right now. */
07576             if (best)
07577                user_unref(best);
07578             best = user;
07579             break;
07580          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07581             /* No required authentication */
07582             if (user->ha) {
07583                /* There was host authentication and we passed, bonus! */
07584                if (bestscore < 4) {
07585                   bestscore = 4;
07586                   if (best)
07587                      user_unref(best);
07588                   best = user;
07589                   continue;
07590                }
07591             } else {
07592                /* No host access, but no secret, either, not bad */
07593                if (bestscore < 3) {
07594                   bestscore = 3;
07595                   if (best)
07596                      user_unref(best);
07597                   best = user;
07598                   continue;
07599                }
07600             }
07601          } else {
07602             if (user->ha) {
07603                /* Authentication, but host access too, eh, it's something.. */
07604                if (bestscore < 2) {
07605                   bestscore = 2;
07606                   if (best)
07607                      user_unref(best);
07608                   best = user;
07609                   continue;
07610                }
07611             } else {
07612                /* Authentication and no host access...  This is our baseline */
07613                if (bestscore < 1) {
07614                   bestscore = 1;
07615                   if (best)
07616                      user_unref(best);
07617                   best = user;
07618                   continue;
07619                }
07620             }
07621          }
07622       }
07623       user_unref(user);
07624    }
07625    ao2_iterator_destroy(&i);
07626    user = best;
07627    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07628       user = realtime_user(iaxs[callno]->username, sin);
07629       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
07630           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
07631          user = user_unref(user);
07632       }
07633    }
07634    if (user) {
07635       /* We found our match (use the first) */
07636       /* copy vars */
07637       for (v = user->vars ; v ; v = v->next) {
07638          if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07639             tmpvar->next = iaxs[callno]->vars; 
07640             iaxs[callno]->vars = tmpvar;
07641          }
07642       }
07643       /* If a max AUTHREQ restriction is in place, activate it */
07644       if (user->maxauthreq > 0)
07645          ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07646       iaxs[callno]->prefs = user->prefs;
07647       ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07648       iaxs[callno]->encmethods = user->encmethods;
07649       /* Store the requested username if not specified */
07650       if (ast_strlen_zero(iaxs[callno]->username))
07651          ast_string_field_set(iaxs[callno], username, user->name);
07652       /* Store whether this is a trunked call, too, of course, and move if appropriate */
07653       ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07654       iaxs[callno]->capability = user->capability;
07655       /* And use the default context */
07656       if (ast_strlen_zero(iaxs[callno]->context)) {
07657          if (user->contexts)
07658             ast_string_field_set(iaxs[callno], context, user->contexts->context);
07659          else
07660             ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07661       }
07662       /* And any input keys */
07663       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07664       /* And the permitted authentication methods */
07665       iaxs[callno]->authmethods = user->authmethods;
07666       iaxs[callno]->adsi = user->adsi;
07667       /* If the user has callerid, override the remote caller id. */
07668       if (ast_test_flag64(user, IAX_HASCALLERID)) {
07669          iaxs[callno]->calling_tns = 0;
07670          iaxs[callno]->calling_ton = 0;
07671          ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07672          ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07673          ast_string_field_set(iaxs[callno], ani, user->cid_num);
07674          iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07675       } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07676          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07677       } /* else user is allowed to set their own CID settings */
07678       if (!ast_strlen_zero(user->accountcode))
07679          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07680       if (!ast_strlen_zero(user->mohinterpret))
07681          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07682       if (!ast_strlen_zero(user->mohsuggest))
07683          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07684       if (!ast_strlen_zero(user->parkinglot))
07685          ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07686       if (user->amaflags)
07687          iaxs[callno]->amaflags = user->amaflags;
07688       if (!ast_strlen_zero(user->language))
07689          ast_string_field_set(iaxs[callno], language, user->language);
07690       ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 
07691       /* Keep this check last */
07692       if (!ast_strlen_zero(user->dbsecret)) {
07693          char *family, *key=NULL;
07694          char buf[80];
07695          family = ast_strdupa(user->dbsecret);
07696          key = strchr(family, '/');
07697          if (key) {
07698             *key = '\0';
07699             key++;
07700          }
07701          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07702             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07703          else
07704             ast_string_field_set(iaxs[callno], secret, buf);
07705       } else
07706          ast_string_field_set(iaxs[callno], secret, user->secret);
07707       res = 0;
07708       user = user_unref(user);
07709    } else {
07710        /* user was not found, but we should still fake an AUTHREQ.
07711         * Set authmethods to the last known authmethod used by the system
07712         * Set a fake secret, it's not looked at, just required to attempt authentication.
07713         * Set authrej so the AUTHREP is rejected without even looking at its contents */
07714       iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07715       ast_string_field_set(iaxs[callno], secret, "badsecret");
07716       iaxs[callno]->authrej = 1;
07717       if (!ast_strlen_zero(iaxs[callno]->username)) {
07718          /* only send the AUTHREQ if a username was specified. */
07719          res = 0;
07720       }
07721    }
07722    ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07723    return res;
07724 }

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

Definition at line 9315 of file chan_iax2.c.

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

Referenced by socket_process().

09316 {
09317    unsigned int ourver;
09318    char rsi[80];
09319    snprintf(rsi, sizeof(rsi), "si-%s", si);
09320    if (iax_provision_version(&ourver, rsi, 1))
09321       return 0;
09322    ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09323    if (ourver != ver) 
09324       iax2_provision(sin, sockfd, NULL, rsi, 1);
09325    return 0;
09326 }

static int check_srcaddr ( struct sockaddr *  sa,
socklen_t  salen 
) [static]

Check if address can be used as packet source.

Returns:
0 address available, 1 address unavailable, -1 error

Definition at line 12144 of file chan_iax2.c.

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

Referenced by peer_set_srcaddr().

12145 {
12146    int sd;
12147    int res;
12148    
12149    sd = socket(AF_INET, SOCK_DGRAM, 0);
12150    if (sd < 0) {
12151       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12152       return -1;
12153    }
12154 
12155    res = bind(sd, sa, salen);
12156    if (res < 0) {
12157       ast_debug(1, "Can't bind: %s\n", strerror(errno));
12158       close(sd);
12159       return 1;
12160    }
12161 
12162    close(sd);
12163    return 0;
12164 }

static void cleanup_thread_list ( void *  head  )  [static]

Definition at line 14178 of file chan_iax2.c.

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

Referenced by __unload_module().

14179 {
14180    AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14181    struct iax2_thread_list *list_head = head;
14182    struct iax2_thread *thread;
14183 
14184    AST_LIST_LOCK(list_head);
14185    while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
14186       pthread_t thread_id = thread->threadid;
14187 
14188       thread->stop = 1;
14189       signal_condition(&thread->lock, &thread->cond);
14190 
14191       AST_LIST_UNLOCK(list_head);
14192       pthread_join(thread_id, NULL);
14193       AST_LIST_LOCK(list_head);
14194    }
14195    AST_LIST_UNLOCK(list_head);
14196 }

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

Definition at line 8289 of file chan_iax2.c.

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

Referenced by socket_process().

08290 {
08291    char exten[256] = "";
08292    int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08293    struct iax2_dpcache *dp = NULL;
08294    
08295    if (ies->called_number)
08296       ast_copy_string(exten, ies->called_number, sizeof(exten));
08297    
08298    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08299       status = CACHE_FLAG_EXISTS;
08300    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08301       status = CACHE_FLAG_CANEXIST;
08302    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08303       status = CACHE_FLAG_NONEXISTENT;
08304 
08305    if (ies->refresh)
08306       expiry = ies->refresh;
08307    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08308       matchmore = CACHE_FLAG_MATCHMORE;
08309    
08310    AST_LIST_LOCK(&dpcache);
08311    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08312       if (strcmp(dp->exten, exten))
08313          continue;
08314       AST_LIST_REMOVE_CURRENT(peer_list);
08315       dp->callno = 0;
08316       dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08317       if (dp->flags & CACHE_FLAG_PENDING) {
08318          dp->flags &= ~CACHE_FLAG_PENDING;
08319          dp->flags |= status;
08320          dp->flags |= matchmore;
08321       }
08322       /* Wake up waiters */
08323       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08324          if (dp->waiters[x] > -1) {
08325             if (write(dp->waiters[x], "asdf", 4) < 0) {
08326             }
08327          }
08328       }
08329    }
08330    AST_LIST_TRAVERSE_SAFE_END;
08331    AST_LIST_UNLOCK(&dpcache);
08332 
08333    return 0;
08334 }

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

Definition at line 3808 of file chan_iax2.c.

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

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

03809 {
03810    int which = 0;
03811    struct iax2_peer *peer;
03812    char *res = NULL;
03813    int wordlen = strlen(word);
03814    struct ao2_iterator i;
03815 
03816    i = ao2_iterator_init(peers, 0);
03817    while ((peer = ao2_iterator_next(&i))) {
03818       if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03819          && (!flags || ast_test_flag64(peer, flags))) {
03820          res = ast_strdup(peer->name);
03821          peer_unref(peer);
03822          break;
03823       }
03824       peer_unref(peer);
03825    }
03826    ao2_iterator_destroy(&i);
03827 
03828    return res;
03829 }

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

Definition at line 6852 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_unregister().

06853 {
06854    int which = 0;
06855    struct iax2_peer *p = NULL;
06856    char *res = NULL;
06857    int wordlen = strlen(word);
06858 
06859    /* 0 - iax2; 1 - unregister; 2 - <peername> */
06860    if (pos == 2) {
06861       struct ao2_iterator i = ao2_iterator_init(peers, 0);
06862       while ((p = ao2_iterator_next(&i))) {
06863          if (!strncasecmp(p->name, word, wordlen) && 
06864             ++which > state && p->expire > 0) {
06865             res = ast_strdup(p->name);
06866             peer_unref(p);
06867             break;
06868          }
06869          peer_unref(p);
06870       }
06871       ao2_iterator_destroy(&i);
06872    }
06873 
06874    return res;
06875 }

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

Definition at line 8336 of file chan_iax2.c.

References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, AST_LIST_TRAVERSE, ast_log(), iax_ies::callno, jb_frame::data, DEFAULT_RETRY_TIME, frame_queue, iax2_frame_free(), 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().

08337 {
08338    int peercallno = 0;
08339    struct chan_iax2_pvt *pvt = iaxs[callno];
08340    struct iax_frame *cur;
08341    jb_frame frame;
08342 
08343    if (ies->callno)
08344       peercallno = ies->callno;
08345 
08346    if (peercallno < 1) {
08347       ast_log(LOG_WARNING, "Invalid transfer request\n");
08348       return -1;
08349    }
08350    remove_by_transfercallno(pvt);
08351    /* since a transfer has taken place, the address will change.
08352     * This must be accounted for in the peercnts table.  Remove
08353     * the old address and add the new one */
08354    peercnt_remove_by_addr(&pvt->addr);
08355    peercnt_add(&pvt->transfer);
08356    /* now copy over the new address */
08357    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08358    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08359    /* Reset sequence numbers */
08360    pvt->oseqno = 0;
08361    pvt->rseqno = 0;
08362    pvt->iseqno = 0;
08363    pvt->aseqno = 0;
08364 
08365    if (pvt->peercallno) {
08366       remove_by_peercallno(pvt);
08367    }
08368    pvt->peercallno = peercallno;
08369    /*this is where the transfering call swiches hash tables */
08370    store_by_peercallno(pvt);
08371    pvt->transferring = TRANSFER_NONE;
08372    pvt->svoiceformat = -1;
08373    pvt->voiceformat = 0;
08374    pvt->svideoformat = -1;
08375    pvt->videoformat = 0;
08376    pvt->transfercallno = 0;
08377    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08378    memset(&pvt->offset, 0, sizeof(pvt->offset));
08379    /* reset jitterbuffer */
08380    while(jb_getall(pvt->jb,&frame) == JB_OK)
08381       iax2_frame_free(frame.data);
08382    jb_reset(pvt->jb);
08383    pvt->lag = 0;
08384    pvt->last = 0;
08385    pvt->lastsent = 0;
08386    pvt->nextpred = 0;
08387    pvt->pingtime = DEFAULT_RETRY_TIME;
08388    AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08389       /* We must cancel any packets that would have been transmitted
08390          because now we're talking to someone new.  It's okay, they
08391          were transmitted to someone that didn't care anyway. */
08392       cur->retries = -1;
08393    }
08394    return 0;
08395 }

static unsigned char compress_subclass ( format_t  subclass  )  [static]

Definition at line 1609 of file chan_iax2.c.

References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.

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

01610 {
01611    int x;
01612    int power=-1;
01613    /* If it's 64 or smaller, just return it */
01614    if (subclass < IAX_FLAG_SC_LOG)
01615       return subclass;
01616    /* Otherwise find its power */
01617    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01618       if (subclass & (1LL << x)) {
01619          if (power > -1) {
01620             ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass);
01621             return 0;
01622          } else
01623             power = x;
01624       }
01625    }
01626    return power | IAX_FLAG_SC_LOG;
01627 }

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

Definition at line 9328 of file chan_iax2.c.

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

Referenced by socket_process().

09329 {
09330    jb_info stats;
09331    jb_getinfo(pvt->jb, &stats);
09332    
09333    memset(iep, 0, sizeof(*iep));
09334 
09335    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09336    if(stats.frames_in == 0) stats.frames_in = 1;
09337    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09338    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09339    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09340    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09341    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09342 }

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

Definition at line 4536 of file chan_iax2.c.

References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ast_clear_flag64, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags64, ast_copy_string(), ast_db_get(), ast_debug, ast_get_ip_or_srv(), ast_log(), ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, iax2_peer::cid_name, create_addr_info::cid_name, iax2_peer::cid_num, create_addr_info::cid_num, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, IAX_DEFAULT_PORTNO, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::mohinterpret, create_addr_info::mohinterpret, iax2_peer::mohsuggest, create_addr_info::mohsuggest, ast_channel::nativeformats, iax2_peer::outkey, create_addr_info::outkey, peer_unref(), iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, ast_sockaddr::ss, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.

04537 {
04538    struct iax2_peer *peer;
04539    int res = -1;
04540    struct ast_codec_pref ourprefs;
04541    struct sockaddr_in peer_addr;
04542 
04543    ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04544    cai->sockfd = defaultsockfd;
04545    cai->maxtime = 0;
04546    sin->sin_family = AF_INET;
04547 
04548    if (!(peer = find_peer(peername, 1))) {
04549       struct ast_sockaddr sin_tmp;
04550 
04551       cai->found = 0;
04552       sin_tmp.ss.ss_family = AF_INET;
04553       if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
04554          ast_log(LOG_WARNING, "No such host: %s\n", peername);
04555          return -1;
04556       }
04557       ast_sockaddr_to_sin(&sin_tmp, sin);
04558       sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04559       /* use global iax prefs for unknown peer/user */
04560       /* But move the calling channel's native codec to the top of the preference list */
04561       memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04562       if (c)
04563          ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04564       ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04565       return 0;
04566    }
04567 
04568    cai->found = 1;
04569 
04570    ast_sockaddr_to_sin(&peer->addr, &peer_addr);
04571 
04572    /* if the peer has no address (current or default), return failure */
04573    if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
04574       goto return_unref;
04575    }
04576 
04577    /* if the peer is being monitored and is currently unreachable, return failure */
04578    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04579       goto return_unref;
04580 
04581    ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04582    cai->maxtime = peer->maxms;
04583    cai->capability = peer->capability;
04584    cai->encmethods = peer->encmethods;
04585    cai->sockfd = peer->sockfd;
04586    cai->adsi = peer->adsi;
04587    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04588    /* Move the calling channel's native codec to the top of the preference list */
04589    if (c) {
04590       ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
04591       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04592    }
04593    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04594    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04595    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04596    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04597    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04598    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04599    ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04600    ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04601    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04602    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04603    if (ast_strlen_zero(peer->dbsecret)) {
04604       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04605    } else {
04606       char *family;
04607       char *key = NULL;
04608 
04609       family = ast_strdupa(peer->dbsecret);
04610       key = strchr(family, '/');
04611       if (key)
04612          *key++ = '\0';
04613       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04614          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04615          goto return_unref;
04616       }
04617    }
04618 
04619    if (peer_addr.sin_addr.s_addr) {
04620       sin->sin_addr = peer_addr.sin_addr;
04621       sin->sin_port = peer_addr.sin_port;
04622    } else {
04623       sin->sin_addr = peer->defaddr.sin_addr;
04624       sin->sin_port = peer->defaddr.sin_port;
04625    }
04626 
04627    res = 0;
04628 
04629 return_unref:
04630    peer_unref(peer);
04631 
04632    return res;
04633 }

static int create_callno_pools ( void   )  [static]

Definition at line 2662 of file chan_iax2.c.

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

Referenced by load_objects().

02663 {
02664    uint16_t i;
02665 
02666    if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02667       return -1;
02668    }
02669 
02670    if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02671       return -1;
02672    }
02673 
02674    /* start at 2, 0 and 1 are reserved */
02675    for (i = 2; i <= IAX_MAX_CALLS; i++) {
02676       struct callno_entry *callno_entry;
02677 
02678       if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02679          return -1;
02680       }
02681 
02682       callno_entry->callno = i;
02683 
02684       if (i < TRUNK_CALL_START) {
02685          ao2_link(callno_pool, callno_entry);
02686       } else {
02687          ao2_link(callno_pool_trunk, callno_entry);
02688       }
02689 
02690       ao2_ref(callno_entry, -1);
02691    }
02692 
02693    return 0;
02694 }

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

References ast_debug, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, f, IAX_FLAG_FULL, memcpy_decrypt(), ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::type, and uncompress_subclass().

Referenced by decrypt_frame(), and update_packet().

06204 {
06205    int padding;
06206    unsigned char *workspace;
06207 
06208    workspace = alloca(*datalen);
06209    memset(f, 0, sizeof(*f));
06210    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06211       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06212       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06213          return -1;
06214       /* Decrypt */
06215       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06216 
06217       padding = 16 + (workspace[15] & 0x0f);
06218       if (iaxdebug)
06219          ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06220       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06221          return -1;
06222 
06223       *datalen -= padding;
06224       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06225       f->frametype = fh->type;
06226       if (f->frametype == AST_FRAME_VIDEO) {
06227          f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06228       } else if (f->frametype == AST_FRAME_VOICE) {
06229          f->subclass.codec = uncompress_subclass(fh->csub);
06230       } else {
06231          f->subclass.integer = uncompress_subclass(fh->csub);
06232       }
06233    } else {
06234       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06235       if (iaxdebug)
06236          ast_debug(1, "Decoding mini with length %d\n", *datalen);
06237       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06238          return -1;
06239       /* Decrypt */
06240       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06241       padding = 16 + (workspace[15] & 0x0f);
06242       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06243          return -1;
06244       *datalen -= padding;
06245       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06246    }
06247    return 0;
06248 }

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

Definition at line 6291 of file chan_iax2.c.

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

Referenced by socket_process().

06292 {
06293    int res=-1;
06294    if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06295       /* Search for possible keys, given secrets */
06296       struct MD5Context md5;
06297       unsigned char digest[16];
06298       char *tmppw, *stringp;
06299       
06300       tmppw = ast_strdupa(iaxs[callno]->secret);
06301       stringp = tmppw;
06302       while ((tmppw = strsep(&stringp, ";"))) {
06303          MD5Init(&md5);
06304          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06305          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06306          MD5Final(digest, &md5);
06307          build_encryption_keys(digest, iaxs[callno]);
06308          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06309          if (!res) {
06310             ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06311             break;
06312          }
06313       }
06314    } else 
06315       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06316    return res;
06317 }

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

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

Referenced by socket_read().

09476 {
09477    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09478    struct ast_iax2_full_hdr *fh, *cur_fh;
09479 
09480    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09481       return;
09482 
09483    pkt_buf->len = from_here->buf_len;
09484    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09485 
09486    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09487    ast_mutex_lock(&to_here->lock);
09488    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09489       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09490       if (fh->oseqno < cur_fh->oseqno) {
09491          AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09492          break;
09493       }
09494    }
09495    AST_LIST_TRAVERSE_SAFE_END
09496 
09497    if (!cur_pkt_buf)
09498       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09499    
09500    ast_mutex_unlock(&to_here->lock);
09501 }

static void delete_users ( void   )  [static]

Definition at line 12829 of file chan_iax2.c.

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

12830 {
12831    struct iax2_registry *reg;
12832 
12833    ao2_callback(users, 0, user_delme_cb, NULL);
12834 
12835    AST_LIST_LOCK(&registrations);
12836    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
12837       if (sched) {
12838          ast_sched_thread_del(sched, reg->expire);
12839       }
12840       if (reg->callno) {
12841          int callno = reg->callno;
12842          ast_mutex_lock(&iaxsl[callno]);
12843          if (iaxs[callno]) {
12844             iaxs[callno]->reg = NULL;
12845             iax2_destroy(callno);
12846          }
12847          ast_mutex_unlock(&iaxsl[callno]);
12848       }
12849       if (reg->dnsmgr)
12850          ast_dnsmgr_release(reg->dnsmgr);
12851       ast_free(reg);
12852    }
12853    AST_LIST_UNLOCK(&registrations);
12854 
12855    ao2_callback(peers, 0, peer_delme_cb, NULL);
12856 }

static void destroy_firmware ( struct iax_firmware cur  )  [static]

Definition at line 2992 of file chan_iax2.c.

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

Referenced by reload_firmware().

02993 {
02994    /* Close firmware */
02995    if (cur->fwh) {
02996       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02997    }
02998    close(cur->fd);
02999    ast_free(cur);
03000 }

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

Definition at line 9177 of file chan_iax2.c.

References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_IAX, ast_ignore_pattern(), ast_matchmore_extension(), ast_mutex_lock, ast_mutex_unlock, ast_parking_ext_valid(), 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, iaxs, iaxsl, and send_command().

Referenced by dp_lookup_thread(), and socket_process().

09178 {
09179    unsigned short dpstatus = 0;
09180    struct iax_ie_data ied1;
09181    int mm;
09182 
09183    memset(&ied1, 0, sizeof(ied1));
09184    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09185    /* Must be started */
09186    if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09187       dpstatus = IAX_DPSTATUS_EXISTS;
09188    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09189       dpstatus = IAX_DPSTATUS_CANEXIST;
09190    } else {
09191       dpstatus = IAX_DPSTATUS_NONEXISTENT;
09192    }
09193    if (ast_ignore_pattern(context, callednum))
09194       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09195    if (mm)
09196       dpstatus |= IAX_DPSTATUS_MATCHMORE;
09197    if (!skiplock)
09198       ast_mutex_lock(&iaxsl[callno]);
09199    if (iaxs[callno]) {
09200       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09201       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09202       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09203       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09204    }
09205    if (!skiplock)
09206       ast_mutex_unlock(&iaxsl[callno]);
09207 }

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

Definition at line 9209 of file chan_iax2.c.

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

Referenced by spawn_dp_lookup().

09210 {
09211    /* Look up for dpreq */
09212    struct dpreq_data *dpr = data;
09213    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09214    if (dpr->callerid)
09215       ast_free(dpr->callerid);
09216    ast_free(dpr);
09217    return NULL;
09218 }

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

Definition at line 1543 of file chan_iax2.c.

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

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

01544 {
01545    ast_str_set(&buf, 0, "(");
01546    if (e & IAX_ENCRYPT_AES128) {
01547       ast_str_append(&buf, 0, "aes128");
01548    }
01549    if (e & IAX_ENCRYPT_KEYROTATE) {
01550       ast_str_append(&buf, 0, ",keyrotate");
01551    }
01552    if (ast_str_strlen(buf) > 1) {
01553       ast_str_append(&buf, 0, ")");
01554    } else {
01555       ast_str_set(&buf, 0, "No");
01556    }
01557 }

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

Definition at line 6250 of file chan_iax2.c.

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

Referenced by iax2_send(), and update_packet().

06251 {
06252    int padding;
06253    unsigned char *workspace;
06254    workspace = alloca(*datalen + 32);
06255    if (!workspace)
06256       return -1;
06257    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06258       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06259       if (iaxdebug)
06260          ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06261       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06262       padding = 16 + (padding & 0xf);
06263       memcpy(workspace, poo, padding);
06264       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06265       workspace[15] &= 0xf0;
06266       workspace[15] |= (padding & 0xf);
06267       if (iaxdebug)
06268          ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06269       *datalen += padding;
06270       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06271       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06272          memcpy(poo, workspace + *datalen - 32, 32);
06273    } else {
06274       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06275       if (iaxdebug)
06276          ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06277       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06278       padding = 16 + (padding & 0xf);
06279       memcpy(workspace, poo, padding);
06280       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06281       workspace[15] &= 0xf0;
06282       workspace[15] |= (padding & 0x0f);
06283       *datalen += padding;
06284       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06285       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06286          memcpy(poo, workspace + *datalen - 32, 32);
06287    }
06288    return 0;
06289 }

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

Definition at line 8594 of file chan_iax2.c.

References __expire_registry(), and schedule_action.

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

08595 {
08596 #ifdef SCHED_MULTITHREADED
08597    if (schedule_action(__expire_registry, data))
08598 #endif      
08599       __expire_registry(data);
08600    return 0;
08601 }

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

References ARRAY_LEN, ast_calloc, ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_copy_string(), ast_free, ast_frfree, 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_read(), ast_test_flag, ast_tvcmp(), ast_tvnow(), ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, errno, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, iax2_dprequest(), IAX_STATE_STARTED, iaxs, iaxsl, LOG_WARNING, iax2_dpcache::orig, iax2_dpcache::peercontext, state, and iax2_dpcache::waiters.

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

13517 {
13518    struct iax2_dpcache *dp = NULL;
13519    struct timeval now = ast_tvnow();
13520    int x, com[2], timeout, old = 0, outfd, doabort, callno;
13521    struct ast_channel *c = NULL;
13522    struct ast_frame *f = NULL;
13523 
13524    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13525       if (ast_tvcmp(now, dp->expiry) > 0) {
13526          AST_LIST_REMOVE_CURRENT(cache_list);
13527          if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13528             ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13529          else
13530             ast_free(dp);
13531          continue;
13532       }
13533       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13534          break;
13535    }
13536    AST_LIST_TRAVERSE_SAFE_END;
13537 
13538    if (!dp) {
13539       /* No matching entry.  Create a new one. */
13540       /* First, can we make a callno? */
13541       if ((callno = cache_get_callno_locked(data)) < 0) {
13542          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13543          return NULL;
13544       }
13545       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13546          ast_mutex_unlock(&iaxsl[callno]);
13547          return NULL;
13548       }
13549       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13550       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13551       dp->expiry = ast_tvnow();
13552       dp->orig = dp->expiry;
13553       /* Expires in 30 mins by default */
13554       dp->expiry.tv_sec += iaxdefaultdpcache;
13555       dp->flags = CACHE_FLAG_PENDING;
13556       for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13557          dp->waiters[x] = -1;
13558       /* Insert into the lists */
13559       AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13560       AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13561       /* Send the request if we're already up */
13562       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13563          iax2_dprequest(dp, callno);
13564       ast_mutex_unlock(&iaxsl[callno]);
13565    }
13566 
13567    /* By here we must have a dp */
13568    if (dp->flags & CACHE_FLAG_PENDING) {
13569       /* Okay, here it starts to get nasty.  We need a pipe now to wait
13570          for a reply to come back so long as it's pending */
13571       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13572          /* Find an empty slot */
13573          if (dp->waiters[x] < 0)
13574             break;
13575       }
13576       if (x >= ARRAY_LEN(dp->waiters)) {
13577          ast_log(LOG_WARNING, "No more waiter positions available\n");
13578          return NULL;
13579       }
13580       if (pipe(com)) {
13581          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13582          return NULL;
13583       }
13584       dp->waiters[x] = com[1];
13585       /* Okay, now we wait */
13586       timeout = iaxdefaulttimeout * 1000;
13587       /* Temporarily unlock */
13588       AST_LIST_UNLOCK(&dpcache);
13589       /* Defer any dtmf */
13590       if (chan)
13591          old = ast_channel_defer_dtmf(chan);
13592       doabort = 0;
13593       while(timeout) {
13594          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
13595          if (outfd > -1)
13596             break;
13597          if (!c)
13598             continue;
13599          if (!(f = ast_read(c))) {
13600             doabort = 1;
13601             break;
13602          }
13603          ast_frfree(f);
13604       }
13605       if (!timeout) {
13606          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13607       }
13608       AST_LIST_LOCK(&dpcache);
13609       dp->waiters[x] = -1;
13610       close(com[1]);
13611       close(com[0]);
13612       if (doabort) {
13613          /* Don't interpret anything, just abort.  Not sure what th epoint
13614            of undeferring dtmf on a hung up channel is but hey whatever */
13615          if (!old && chan)
13616             ast_channel_undefer_dtmf(chan);
13617          return NULL;
13618       }
13619       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13620          /* Now to do non-independent analysis the results of our wait */
13621          if (dp->flags & CACHE_FLAG_PENDING) {
13622             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
13623                pending.  Don't let it take as long to timeout. */
13624             dp->flags &= ~CACHE_FLAG_PENDING;
13625             dp->flags |= CACHE_FLAG_TIMEOUT;
13626             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
13627                systems without leaving it unavailable once the server comes back online */
13628             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13629             for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13630                if (dp->waiters[x] > -1) {
13631                   if (write(dp->waiters[x], "asdf", 4) < 0) {
13632                      ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13633                   }
13634                }
13635             }
13636          }
13637       }
13638       /* Our caller will obtain the rest */
13639       if (!old && chan)
13640          ast_channel_undefer_dtmf(chan);
13641    }
13642    return dp;  
13643 }

static int find_callno ( unsigned short  callno,
unsigned short  dcallno,
struct sockaddr_in *  sin,
int  new,
int  sockfd,
int  full_frame 
) [static]

Definition at line 2917 of file chan_iax2.c.

References __find_callno().

Referenced by iax2_poke_peer(), and socket_process().

02917                                                                                                                                     { 
02918    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02919 }

static int find_callno_locked ( unsigned short  callno,
unsigned short  dcallno,
struct sockaddr_in *  sin,
int  new,
int  sockfd,
int  full_frame 
) [static]

Definition at line 2921 of file chan_iax2.c.

References __find_callno().

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

02921                                                                                                                                            {
02922 
02923    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02924 }

static struct iax2_thread* find_idle_thread ( void   )  [static]

Definition at line 1395 of file chan_iax2.c.

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_trunk_peer::list, and thread.

Referenced by __schedule_action(), and socket_read().

01396 {
01397    struct iax2_thread *thread = NULL;
01398 
01399    /* Pop the head of the idle list off */
01400    AST_LIST_LOCK(&idle_list);
01401    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01402    AST_LIST_UNLOCK(&idle_list);
01403 
01404    /* If we popped a thread off the idle list, just return it */
01405    if (thread) {
01406       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01407       return thread;
01408    }
01409 
01410    /* Pop the head of the dynamic list off */
01411    AST_LIST_LOCK(&dynamic_list);
01412    thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01413    AST_LIST_UNLOCK(&dynamic_list);
01414 
01415    /* If we popped a thread off the dynamic list, just return it */
01416    if (thread) {
01417       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01418       return thread;
01419    }
01420 
01421    /* If we can't create a new dynamic thread for any reason, return no thread at all */
01422    if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01423       return NULL;
01424 
01425    /* Set default values */
01426    ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01427    thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01428    thread->type = IAX_THREAD_TYPE_DYNAMIC;
01429 
01430    /* Initialize lock and condition */
01431    ast_mutex_init(&thread->lock);
01432    ast_cond_init(&thread->cond, NULL);
01433    ast_mutex_init(&thread->init_lock);
01434    ast_cond_init(&thread->init_cond, NULL);
01435    ast_mutex_lock(&thread->init_lock);
01436 
01437    /* Create thread and send it on it's way */
01438    if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01439       ast_cond_destroy(&thread->cond);
01440       ast_mutex_destroy(&thread->lock);
01441       ast_mutex_unlock(&thread->init_lock);
01442       ast_cond_destroy(&thread->init_cond);
01443       ast_mutex_destroy(&thread->init_lock);
01444       ast_free(thread);
01445       return NULL;
01446    }
01447 
01448    /* this thread is not processing a full frame (since it is idle),
01449       so ensure that the field for the full frame call number is empty */
01450    memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01451 
01452    /* Wait for the thread to be ready before returning it to the caller */
01453    ast_cond_wait(&thread->init_cond, &thread->init_lock);
01454 
01455    /* Done with init_lock */
01456    ast_mutex_unlock(&thread->init_lock);
01457 
01458    return thread;
01459 }

static struct iax2_peer* find_peer ( const char *  name,
int  realtime 
) [static]

Note:
This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno, so do not call it with a pvt lock held.

Definition at line 1687 of file chan_iax2.c.

References ao2_find, iax2_peer::name, OBJ_POINTER, peers, and realtime_peer().

01688 {
01689    struct iax2_peer *peer = NULL;
01690    struct iax2_peer tmp_peer = {
01691       .name = name,
01692    };
01693 
01694    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01695 
01696    /* Now go for realtime if applicable */
01697    if(!peer && realtime)
01698       peer = realtime_peer(name, NULL);
01699 
01700    return peer;
01701 }

static struct iax2_trunk_peer* find_tpeer ( struct sockaddr_in *  sin,
int  fd 
) [static]

Definition at line 6021 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_calloc, ast_debug, ast_inet_ntoa(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_init, ast_mutex_lock, ast_tvnow(), inaddrcmp(), iax2_trunk_peer::list, and iax2_trunk_peer::lock.

Referenced by iax2_trunk_queue(), and socket_process_meta().

06022 {
06023    struct iax2_trunk_peer *tpeer = NULL;
06024    
06025    /* Finds and locks trunk peer */
06026    AST_LIST_LOCK(&tpeers);
06027 
06028    AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06029       if (!inaddrcmp(&tpeer->addr, sin)) {
06030          ast_mutex_lock(&tpeer->lock);
06031          break;
06032       }
06033    }
06034 
06035    if (!tpeer) {
06036       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06037          ast_mutex_init(&tpeer->lock);
06038          tpeer->lastsent = 9999;
06039          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06040          tpeer->trunkact = ast_tvnow();
06041          ast_mutex_lock(&tpeer->lock);
06042          tpeer->sockfd = fd;
06043 #ifdef SO_NO_CHECK
06044          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06045 #endif
06046          ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06047          AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06048       }
06049    }
06050 
06051    AST_LIST_UNLOCK(&tpeers);
06052 
06053    return tpeer;
06054 }

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

Definition at line 1715 of file chan_iax2.c.

References ao2_find, iax2_user::name, OBJ_POINTER, and users.

01716 {
01717    struct iax2_user tmp_user = {
01718       .name = name,
01719    };
01720 
01721    return ao2_find(users, &tmp_user, OBJ_POINTER);
01722 }

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

Definition at line 5833 of file chan_iax2.c.

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

Referenced by socket_process_meta().

05834 {
05835    long ms; /* NOT unsigned */
05836    if (ast_tvzero(iaxs[callno]->rxcore)) {
05837       /* Initialize rxcore time if appropriate */
05838       iaxs[callno]->rxcore = ast_tvnow();
05839       /* Round to nearest 20ms so traces look pretty */
05840       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05841    }
05842    /* Calculate difference between trunk and channel */
05843    ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05844    /* Return as the sum of trunk time and the difference between trunk and real time */
05845    return ms + ts;
05846 }

static void free_context ( struct iax2_context con  )  [static]

Definition at line 11978 of file chan_iax2.c.

References ast_free, and iax2_context::next.

Referenced by build_user(), and user_destructor().

11979 {
11980    struct iax2_context *conl;
11981    while(con) {
11982       conl = con;
11983       con = con->next;
11984       ast_free(conl);
11985    }
11986 }

static void free_signaling_queue_entry ( struct signaling_queue_entry s  )  [static]

Definition at line 1821 of file chan_iax2.c.

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

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

01822 {
01823    ast_free(s->f.data.ptr);
01824    ast_free(s);
01825 }

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

Definition at line 13766 of file chan_iax2.c.

References iax2_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_test_flag64, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, iax2_peer::mailbox, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.

13767 {
13768    struct iax2_peer *peer;
13769    char *peername, *colname;
13770 
13771    peername = ast_strdupa(data);
13772 
13773    /* if our channel, return the IP address of the endpoint of current channel */
13774    if (!strcmp(peername,"CURRENTCHANNEL")) {
13775            unsigned short callno;
13776       if (chan->tech != &iax2_tech)
13777          return -1;
13778       callno = PTR_TO_CALLNO(chan->tech_pvt);   
13779       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13780       return 0;
13781    }
13782 
13783    if ((colname = strchr(peername, ',')))
13784       *colname++ = '\0';
13785    else
13786       colname = "ip";
13787 
13788    if (!(peer = find_peer(peername, 1)))
13789       return -1;
13790 
13791    if (!strcasecmp(colname, "ip")) {
13792       ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
13793    } else  if (!strcasecmp(colname, "status")) {
13794       peer_status(peer, buf, len); 
13795    } else  if (!strcasecmp(colname, "mailbox")) {
13796       ast_copy_string(buf, peer->mailbox, len);
13797    } else  if (!strcasecmp(colname, "context")) {
13798       ast_copy_string(buf, peer->context, len);
13799    } else  if (!strcasecmp(colname, "expire")) {
13800       snprintf(buf, len, "%d", peer->expire);
13801    } else  if (!strcasecmp(colname, "dynamic")) {
13802       ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13803    } else  if (!strcasecmp(colname, "callerid_name")) {
13804       ast_copy_string(buf, peer->cid_name, len);
13805    } else  if (!strcasecmp(colname, "callerid_num")) {
13806       ast_copy_string(buf, peer->cid_num, len);
13807    } else  if (!strcasecmp(colname, "codecs")) {
13808       ast_getformatname_multiple(buf, len -1, peer->capability);
13809    } else  if (!strncasecmp(colname, "codec[", 6)) {
13810       char *codecnum, *ptr;
13811       int codec = 0;
13812       
13813       codecnum = strchr(colname, '[');
13814       *codecnum = '\0';
13815       codecnum++;
13816       if ((ptr = strchr(codecnum, ']'))) {
13817          *ptr = '\0';
13818       }
13819       if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13820          ast_copy_string(buf, ast_getformatname(codec), len);
13821       } else {
13822          buf[0] = '\0';
13823       }
13824    } else {
13825       buf[0] = '\0';
13826    }
13827 
13828    peer_unref(peer);
13829 
13830    return 0;
13831 }

static int get_auth_methods ( const char *  value  )  [static]

Definition at line 12128 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

12129 {
12130    int methods = 0;
12131    if (strstr(value, "rsa"))
12132       methods |= IAX_AUTH_RSA;
12133    if (strstr(value, "md5"))
12134       methods |= IAX_AUTH_MD5;
12135    if (strstr(value, "plaintext"))
12136       methods |= IAX_AUTH_PLAINTEXT;
12137    return methods;
12138 }

static int get_encrypt_methods ( const char *  s  )  [static]

Definition at line 1559 of file chan_iax2.c.

References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.

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

01560 {
01561    int e;
01562    if (!strcasecmp(s, "aes128"))
01563       e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01564    else if (ast_true(s))
01565       e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01566    else
01567       e = 0;
01568    return e;
01569 }

static int get_from_jb ( const void *  p  )  [static]

Definition at line 4118 of file chan_iax2.c.

References __get_from_jb(), and schedule_action.

Referenced by update_jbsched().

04119 {
04120 #ifdef SCHED_MULTITHREADED
04121    if (schedule_action(__get_from_jb, data))
04122 #endif      
04123       __get_from_jb(data);
04124    return 0;
04125 }

static struct callno_entry * get_unused_callno ( int  trunk,
int  validated 
) [static]

Definition at line 2595 of file chan_iax2.c.

References ao2_container_count(), ao2_find, ao2_lock, ao2_unlock, ast_log(), LOG_WARNING, OBJ_CONTINUE, OBJ_POINTER, OBJ_UNLINK, and callno_entry::validated.

Referenced by __find_callno(), and make_trunk().

02596 {
02597    struct callno_entry *callno_entry = NULL;
02598    if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02599       ast_log(LOG_WARNING, "Out of CallNumbers\n");
02600       /* Minor optimization for the extreme case. */
02601       return NULL;
02602    }
02603 
02604    /* the callno_pool container is locked here primarily to ensure thread
02605     * safety of the total_nonval_callno_used check and increment */
02606    ao2_lock(callno_pool);
02607 
02608    /* only a certain number of nonvalidated call numbers should be allocated.
02609     * If there ever is an attack, this separates the calltoken validating
02610     * users from the non calltoken validating users. */
02611    if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02612       ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02613       ao2_unlock(callno_pool);
02614       return NULL;
02615    }
02616 
02617    /* unlink the object from the container, taking over ownership
02618     * of the reference the container had to the object */
02619    callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02620 
02621    if (callno_entry) {
02622       callno_entry->validated = validated;
02623       if (!validated) {
02624          total_nonval_callno_used++;
02625       }
02626    }
02627 
02628    ao2_unlock(callno_pool);
02629    return callno_entry;
02630 }

static int handle_call_token ( struct ast_iax2_full_hdr fh,
struct iax_ies ies,
struct sockaddr_in *  sin,
int  fd 
) [static]

Definition at line 4841 of file chan_iax2.c.

References ast_inet_ntoa(), ast_log(), ast_sha1_hash(), ast_str_alloca, ast_str_buffer(), ast_str_set(), iax_ie_data::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, 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().

04843 {
04844 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"  /* address + port + ts + randomcalldata */
04845 #define CALLTOKEN_IE_FORMAT   "%u?%s"     /* time + ? + (40 char hash) */
04846    struct ast_str *buf = ast_str_alloca(256);
04847    time_t t = time(NULL);
04848    char hash[41]; /* 40 char sha1 hash */
04849    int subclass = uncompress_subclass(fh->csub);
04850 
04851    /* ----- Case 1 ----- */
04852    if (ies->calltoken && !ies->calltokendata) {  /* empty calltoken is provided, client supports calltokens */
04853       struct iax_ie_data ied = {
04854          .buf = { 0 },
04855          .pos = 0,
04856       };
04857 
04858       /* create the hash with their address data and our timestamp */
04859       ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04860       ast_sha1_hash(hash, ast_str_buffer(buf));
04861 
04862       ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04863       iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04864       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04865 
04866       return 1;
04867 
04868    /* ----- Case 2 ----- */
04869    } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */
04870       char *rec_hash = NULL;    /* the received hash, make sure it matches with ours. */
04871       char *rec_ts = NULL;      /* received timestamp */
04872       unsigned int rec_time;  /* received time_t */
04873 
04874       /* split the timestamp from the hash data */
04875       rec_hash = strchr((char *) ies->calltokendata, '?');
04876       if (rec_hash) {
04877          *rec_hash++ = '\0';
04878          rec_ts = (char *) ies->calltokendata;
04879       }
04880 
04881       /* check that we have valid data before we do any comparisons */
04882       if (!rec_hash || !rec_ts) {
04883          goto reject;
04884       } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04885          goto reject;
04886       }
04887 
04888       /* create a hash with their address and the _TOKEN'S_ timestamp */
04889       ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04890       ast_sha1_hash(hash, ast_str_buffer(buf));
04891 
04892       /* compare hashes and then check timestamp delay */
04893       if (strcmp(hash, rec_hash)) {
04894          ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04895          goto reject; /* received hash does not match ours, reject */
04896       } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04897          ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04898          goto reject; /* too much delay, reject */
04899       }
04900 
04901       /* at this point the call token is valid, returning 0 
04902        * will allow socket_process to continue as usual */
04903       requirecalltoken_mark_auto(ies->username, subclass);
04904       return 0;
04905 
04906    /* ----- Case 3 ----- */
04907    } else { /* calltokens are not supported for this client, how do we respond? */
04908       if (calltoken_required(sin, ies->username, subclass)) {
04909          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_inet_ntoa(sin->sin_addr), S_OR(ies->username, "guest"));
04910          goto reject;
04911       }
04912       return 0; /* calltoken is not required for this addr, so permit it. */
04913    }
04914 
04915 reject:
04916    /* received frame has failed calltoken inspection, send apathetic reject messages */
04917    if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04918       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04919    } else {
04920       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04921    }
04922 
04923    return 1;
04924 }

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

Definition at line 11825 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, iax2_provision(), iax_prov_complete_template(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

11826 {
11827    int force = 0;
11828    int res;
11829 
11830    switch (cmd) {
11831    case CLI_INIT:
11832       e->command = "iax2 provision";
11833       e->usage = 
11834          "Usage: iax2 provision <host> <template> [forced]\n"
11835          "       Provisions the given peer or IP address using a template\n"
11836          "       matching either 'template' or '*' if the template is not\n"
11837          "       found.  If 'forced' is specified, even empty provisioning\n"
11838          "       fields will be provisioned as empty fields.\n";
11839       return NULL;
11840    case CLI_GENERATE:
11841       if (a->pos == 3)
11842          return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11843       return NULL;
11844    }
11845 
11846    if (a->argc < 4)
11847       return CLI_SHOWUSAGE;
11848    if (a->argc > 4) {
11849       if (!strcasecmp(a->argv[4], "forced"))
11850          force = 1;
11851       else
11852          return CLI_SHOWUSAGE;
11853    }
11854    res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11855    if (res < 0)
11856       ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11857    else if (res < 1)
11858       ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11859    else
11860       ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11861    return CLI_SUCCESS;
11862 }

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

Definition at line 3550 of file chan_iax2.c.

References ao2_unlink, ast_cli_args::argc, ast_cli_args::argv, 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(), ast_cli_args::fd, find_peer(), find_user(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, ast_cli_args::line, ast_cli_args::n, peer_ref(), peer_unref(), ast_cli_args::pos, prune_peers(), prune_users(), ast_cli_entry::usage, user, user_unref(), users, and ast_cli_args::word.

03551 {
03552    struct iax2_peer *peer = NULL;
03553    struct iax2_user *user = NULL;
03554    static const char * const choices[] = { "all", NULL };
03555    char *cmplt;
03556 
03557    switch (cmd) {
03558    case CLI_INIT:
03559       e->command = "iax2 prune realtime";
03560       e->usage =
03561          "Usage: iax2 prune realtime [<peername>|all]\n"
03562          "       Prunes object(s) from the cache\n";
03563       return NULL;
03564    case CLI_GENERATE:
03565       if (a->pos == 3) {
03566          cmplt = ast_cli_complete(a->word, choices, a->n);
03567          if (!cmplt)
03568             cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03569          return cmplt;
03570       }
03571       return NULL;
03572    }
03573    if (a->argc != 4)
03574       return CLI_SHOWUSAGE;
03575    if (!strcmp(a->argv[3], "all")) {
03576       prune_users();
03577       prune_peers();
03578       ast_cli(a->fd, "Cache flushed successfully.\n");
03579       return CLI_SUCCESS;
03580    }
03581    peer = find_peer(a->argv[3], 0);
03582    user = find_user(a->argv[3]);
03583    if (peer || user) {
03584       if (peer) {
03585          if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
03586             ast_set_flag64(peer, IAX_RTAUTOCLEAR);
03587             expire_registry(peer_ref(peer));
03588             ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03589          } else {
03590             ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03591          }
03592          peer_unref(peer);
03593       }
03594       if (user) {
03595          if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
03596             ast_set_flag64(user, IAX_RTAUTOCLEAR);
03597             ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03598          } else {
03599             ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03600          }
03601          ao2_unlink(users,user);
03602          user_unref(user);
03603       }
03604    } else {
03605       ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03606    }
03607 
03608    return CLI_SUCCESS;
03609 }

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

Definition at line 13420 of file chan_iax2.c.

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

13421 {
13422    switch (cmd) {
13423    case CLI_INIT:
13424       e->command = "iax2 reload";
13425       e->usage =
13426          "Usage: iax2 reload\n"
13427          "       Reloads IAX configuration from iax.conf\n";
13428       return NULL;
13429    case CLI_GENERATE:
13430       return NULL;
13431    }
13432 
13433    reload_config();
13434 
13435    return CLI_SUCCESS;
13436 }

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

Definition at line 7296 of file chan_iax2.c.

References iax2_peer::addr, ao2_ref, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_inet_ntoa(), ast_sockaddr_to_sin, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), debugaddr, ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

07297 {
07298    switch (cmd) {
07299    case CLI_INIT:
07300       e->command = "iax2 set debug {on|off|peer}";
07301       e->usage =
07302          "Usage: iax2 set debug {on|off|peer peername}\n"
07303          "       Enables/Disables dumping of IAX packets for debugging purposes.\n";
07304       return NULL;
07305    case CLI_GENERATE:
07306       if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07307          return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07308       return NULL;
07309    }
07310 
07311    if (a->argc < e->args  || a->argc > e->args + 1)
07312       return CLI_SHOWUSAGE;
07313 
07314    if (!strcasecmp(a->argv[3], "peer")) {
07315       struct iax2_peer *peer;
07316       struct sockaddr_in peer_addr;
07317 
07318 
07319       if (a->argc != e->args + 1)
07320          return CLI_SHOWUSAGE;
07321 
07322       peer = find_peer(a->argv[4], 1);
07323 
07324       if (!peer) {
07325          ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07326          return CLI_FAILURE;
07327       }
07328 
07329       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07330 
07331       debugaddr.sin_addr = peer_addr.sin_addr;
07332       debugaddr.sin_port = peer_addr.sin_port;
07333 
07334       ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07335          ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07336 
07337       ao2_ref(peer, -1);
07338    } else if (!strncasecmp(a->argv[3], "on", 2)) {
07339       iaxdebug = 1;
07340       ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07341    } else {
07342       iaxdebug = 0;
07343       memset(&debugaddr, 0, sizeof(debugaddr));
07344       ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07345    }
07346    return CLI_SUCCESS;
07347 }

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

Definition at line 7375 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), and ast_cli_entry::usage.

07376 {
07377    switch (cmd) {
07378    case CLI_INIT:
07379       e->command = "iax2 set debug jb {on|off}";
07380       e->usage =
07381          "Usage: iax2 set debug jb {on|off}\n"
07382          "       Enables/Disables jitterbuffer debugging information\n";
07383       return NULL;
07384    case CLI_GENERATE:
07385       return NULL;
07386    }
07387 
07388    if (a->argc != e->args)
07389       return CLI_SHOWUSAGE;
07390    
07391    if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07392       jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07393       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07394    } else {
07395       jb_setoutput(jb_error_output, jb_warning_output, NULL);
07396       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07397    }
07398    return CLI_SUCCESS;
07399 }

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

Definition at line 7349 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

07350 {
07351    switch (cmd) {
07352    case CLI_INIT:
07353       e->command = "iax2 set debug trunk {on|off}";
07354       e->usage =
07355          "Usage: iax2 set debug trunk {on|off}\n"
07356          "       Enables/Disables debugging of IAX trunking\n";
07357       return NULL;
07358    case CLI_GENERATE:
07359       return NULL;
07360    }
07361 
07362    if (a->argc != e->args)
07363       return CLI_SHOWUSAGE;
07364 
07365    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07366       iaxtrunkdebug = 1;
07367       ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07368    } else {
07369       iaxtrunkdebug = 0;
07370       ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07371    }
07372    return CLI_SUCCESS;
07373 }

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

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, MAX_TRUNK_MTU, and ast_cli_entry::usage.

03878 {
03879    int mtuv;
03880 
03881    switch (cmd) {
03882    case CLI_INIT:
03883       e->command = "iax2 set mtu";
03884       e->usage =
03885          "Usage: iax2 set mtu <value>\n"
03886          "       Set the system-wide IAX IP mtu to <value> bytes net or\n"
03887          "       zero to disable. Disabling means that the operating system\n"
03888          "       must handle fragmentation of UDP packets when the IAX2 trunk\n"
03889          "       packet exceeds the UDP payload size. This is substantially\n"
03890          "       below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03891          "       greater for G.711 samples.\n";
03892       return NULL;
03893    case CLI_GENERATE:
03894       return NULL;
03895    }
03896 
03897    if (a->argc != 4)
03898       return CLI_SHOWUSAGE; 
03899    if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03900       mtuv = MAX_TRUNK_MTU;
03901    else
03902       mtuv = atoi(a->argv[3]);
03903 
03904    if (mtuv == 0) {
03905       ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 
03906       global_max_trunk_mtu = 0; 
03907       return CLI_SUCCESS; 
03908    }
03909    if (mtuv < 172 || mtuv > 4000) {
03910       ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 
03911       return CLI_SHOWUSAGE; 
03912    }
03913    ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 
03914    global_max_trunk_mtu = mtuv; 
03915    return CLI_SUCCESS;
03916 }

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

Definition at line 3918 of file chan_iax2.c.

References 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, ast_cli_args::fd, iax2_dpcache::flags, iax2_dpcache::peercontext, ast_cli_entry::usage, and iax2_dpcache::waiters.

03919 {
03920    struct iax2_dpcache *dp = NULL;
03921    char tmp[1024], *pc = NULL;
03922    int s, x, y;
03923    struct timeval now = ast_tvnow();
03924 
03925    switch (cmd) {
03926    case CLI_INIT:
03927       e->command = "iax2 show cache";
03928       e->usage =
03929          "Usage: iax2 show cache\n"
03930          "       Display currently cached IAX Dialplan results.\n";
03931       return NULL;
03932    case CLI_GENERATE:
03933       return NULL;
03934    }
03935 
03936    AST_LIST_LOCK(&dpcache);
03937 
03938    ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03939 
03940    AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03941       s = dp->expiry.tv_sec - now.tv_sec;
03942       tmp[0] = '\0';
03943       if (dp->flags & CACHE_FLAG_EXISTS)
03944          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03945       if (dp->flags & CACHE_FLAG_NONEXISTENT)
03946          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03947       if (dp->flags & CACHE_FLAG_CANEXIST)
03948          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03949       if (dp->flags & CACHE_FLAG_PENDING)
03950          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03951       if (dp->flags & CACHE_FLAG_TIMEOUT)
03952          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03953       if (dp->flags & CACHE_FLAG_TRANSMITTED)
03954          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03955       if (dp->flags & CACHE_FLAG_MATCHMORE)
03956          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03957       if (dp->flags & CACHE_FLAG_UNKNOWN)
03958          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03959       /* Trim trailing pipe */
03960       if (!ast_strlen_zero(tmp)) {
03961          tmp[strlen(tmp) - 1] = '\0';
03962       } else {
03963          ast_copy_string(tmp, "(none)", sizeof(tmp));
03964       }
03965       y = 0;
03966       pc = strchr(dp->peercontext, '@');
03967       if (!pc) {
03968          pc = dp->peercontext;
03969       } else {
03970          pc++;
03971       }
03972       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
03973          if (dp->waiters[x] > -1)
03974             y++;
03975       }
03976       if (s > 0) {
03977          ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03978       } else {
03979          ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03980       }
03981    }
03982 
03983    AST_LIST_UNLOCK(&dpcache);
03984 
03985    return CLI_SUCCESS;
03986 }

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

Definition at line 2537 of file chan_iax2.c.

References peercnt::addr, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_inet_ntoa(), CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, peercnt::cur, ast_cli_args::fd, peercnt::limit, peercnts, and ast_cli_entry::usage.

02538 {
02539    struct ao2_iterator i;
02540    struct peercnt *peercnt;
02541    struct sockaddr_in sin;
02542    int found = 0;
02543 
02544    switch (cmd) {
02545    case CLI_INIT:
02546       e->command = "iax2 show callnumber usage";
02547       e->usage =
02548          "Usage: iax2 show callnumber usage [IP address]\n"
02549          "       Shows current IP addresses which are consuming iax2 call numbers\n";
02550       return NULL;
02551    case CLI_GENERATE:
02552       return NULL;
02553    case CLI_HANDLER:
02554       if (a->argc < 4 || a->argc > 5)
02555          return CLI_SHOWUSAGE;
02556 
02557       ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02558       i = ao2_iterator_init(peercnts, 0);
02559       while ((peercnt = ao2_iterator_next(&i))) {
02560          sin.sin_addr.s_addr = peercnt->addr;
02561          if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02562                ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02563                found = 1;
02564                break;
02565          } else {
02566             ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02567          }
02568          ao2_ref(peercnt, -1);
02569       }
02570       ao2_iterator_destroy(&i);
02571 
02572       if (a->argc == 4) {
02573          ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
02574                           "Non-CallToken Validated Callno Used:   %d\n",
02575             global_maxcallno_nonval,
02576             total_nonval_callno_used);
02577 
02578          ast_cli(a->fd,   "Total Available Callno:                %d\n"
02579                           "Regular Callno Available:              %d\n"
02580                           "Trunk Callno Available:                %d\n",
02581             ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk),
02582             ao2_container_count(callno_pool),
02583             ao2_container_count(callno_pool_trunk));
02584       } else if (a->argc == 5 && !found) {
02585          ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02586       }
02587 
02588 
02589       return CLI_SUCCESS;
02590    default:
02591       return NULL;
02592    }
02593 }

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

Definition at line 7123 of file chan_iax2.c.

References ast_cli_args::argc, ARRAY_LEN, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, iax2_registry::callno, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, jb_info::current, iax_rr::delay, ast_cli_args::fd, FORMAT, FORMAT2, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, MARK_IAX_SUBCLASS_TX, jb_info::min, ast_channel::name, chan_iax2_pvt::owner, chan_iax2_pvt::remote_rr, S_OR, and ast_cli_entry::usage.

07124 {
07125 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s  %s  %9s\n"
07126 #define FORMAT  "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-4.4dms  %-6.6s  %s%s  %3s%s\n"
07127 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
07128    int x;
07129    int numchans = 0;
07130    char first_message[10] = { 0, };
07131    char last_message[10] = { 0, };
07132 
07133    switch (cmd) {
07134    case CLI_INIT:
07135       e->command = "iax2 show channels";
07136       e->usage =
07137          "Usage: iax2 show channels\n"
07138          "       Lists all currently active IAX channels.\n";
07139       return NULL;
07140    case CLI_GENERATE:
07141       return NULL;
07142    }
07143 
07144    if (a->argc != 3)
07145       return CLI_SHOWUSAGE;
07146    ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07147    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07148       ast_mutex_lock(&iaxsl[x]);
07149       if (iaxs[x]) {
07150          int lag, jitter, localdelay;
07151          jb_info jbinfo;
07152          if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07153             jb_getinfo(iaxs[x]->jb, &jbinfo);
07154             jitter = jbinfo.jitter;
07155             localdelay = jbinfo.current - jbinfo.min;
07156          } else {
07157             jitter = -1;
07158             localdelay = 0;
07159          }
07160 
07161          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07162          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07163          lag = iaxs[x]->remote_rr.delay;
07164          ast_cli(a->fd, FORMAT,
07165             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07166             ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07167             S_OR(iaxs[x]->username, "(None)"),
07168             iaxs[x]->callno, iaxs[x]->peercallno,
07169             iaxs[x]->oseqno, iaxs[x]->iseqno,
07170             lag,
07171             jitter,
07172             localdelay,
07173             ast_getformatname(iaxs[x]->voiceformat),
07174             (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07175             first_message,
07176             (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07177             last_message);
07178          numchans++;
07179       }
07180       ast_mutex_unlock(&iaxsl[x]);
07181    }
07182    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07183    return CLI_SUCCESS;
07184 #undef FORMAT
07185 #undef FORMAT2
07186 #undef FORMATB
07187 }

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

Definition at line 6909 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, ast_cli_args::fd, iax_firmware::fwh, iax_firmware::list, ast_cli_entry::usage, and ast_iax2_firmware_header::version.

06910 {
06911    struct iax_firmware *cur = NULL;
06912 
06913    switch (cmd) {
06914    case CLI_INIT:
06915       e->command = "iax2 show firmware";
06916       e->usage =
06917          "Usage: iax2 show firmware\n"
06918          "       Lists all known IAX firmware images.\n";
06919       return NULL;
06920    case CLI_GENERATE:
06921       return NULL;
06922    }
06923 
06924    if (a->argc != 3 && a->argc != 4)
06925       return CLI_SHOWUSAGE;
06926 
06927    ast_cli(a->fd, "%-15.15s  %-15.15s %-15.15s\n", "Device", "Version", "Size");
06928    AST_LIST_LOCK(&firmwares);
06929    AST_LIST_TRAVERSE(&firmwares, cur, list) {
06930       if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname)))  {
06931          ast_cli(a->fd, "%-15.15s  %-15d %-15d\n", cur->fwh->devname, 
06932             ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06933       }
06934    }
06935    AST_LIST_UNLOCK(&firmwares);
06936 
06937    return CLI_SUCCESS;
06938 }

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

Definition at line 7273 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli(), ast_cli_netstats(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

07274 {
07275    int numchans = 0;
07276 
07277    switch (cmd) {
07278    case CLI_INIT:
07279       e->command = "iax2 show netstats";
07280       e->usage =
07281          "Usage: iax2 show netstats\n"
07282          "       Lists network status for all currently active IAX channels.\n";
07283       return NULL;
07284    case CLI_GENERATE:
07285       return NULL;
07286    }
07287    if (a->argc != 3)
07288       return CLI_SHOWUSAGE;
07289    ast_cli(a->fd, "                           -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
07290    ast_cli(a->fd, "Channel               RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts FirstMsg    LastMsg\n");
07291    numchans = ast_cli_netstats(NULL, a->fd, 1);
07292    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07293    return CLI_SUCCESS;
07294 }

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

References iax2_peer::addr, ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sockaddr_to_sin, ast_str_alloca, ast_str_buffer(), 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::encmethods, encmethods_to_str(), iax2_peer::expire, ast_cli_args::fd, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TRUNK, ast_cli_args::line, iax2_peer::mailbox, iax2_peer::maxcallno, ast_cli_args::n, iax2_peer::name, iax2_peer::parkinglot, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, ast_cli_args::pos, iax2_peer::prefs, iax2_peer::secret, iax2_peer::smoothing, status, ast_cli_entry::usage, iax2_peer::username, and ast_cli_args::word.

03726 {
03727    char status[30];
03728    char cbuf[256];
03729    struct iax2_peer *peer;
03730    char codec_buf[512];
03731    struct ast_str *encmethods = ast_str_alloca(256);
03732    int x = 0, codec = 0, load_realtime = 0;
03733 
03734    switch (cmd) {
03735    case CLI_INIT:
03736       e->command = "iax2 show peer";
03737       e->usage =
03738          "Usage: iax2 show peer <name>\n"
03739          "       Display details on specific IAX peer\n";
03740       return NULL;
03741    case CLI_GENERATE:
03742       if (a->pos == 3)
03743          return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03744       return NULL;
03745    }
03746 
03747    if (a->argc < 4)
03748       return CLI_SHOWUSAGE;
03749 
03750    load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03751 
03752    peer = find_peer(a->argv[3], load_realtime);
03753    if (peer) {
03754       struct sockaddr_in peer_addr;
03755 
03756       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
03757 
03758       encmethods_to_str(peer->encmethods, encmethods);
03759       ast_cli(a->fd, "\n\n");
03760       ast_cli(a->fd, "  * Name       : %s\n", peer->name);
03761       ast_cli(a->fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03762       ast_cli(a->fd, "  Context      : %s\n", peer->context);
03763       ast_cli(a->fd, "  Parking lot  : %s\n", peer->parkinglot);
03764       ast_cli(a->fd, "  Mailbox      : %s\n", peer->mailbox);
03765       ast_cli(a->fd, "  Dynamic      : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
03766       ast_cli(a->fd, "  Callnum limit: %d\n", peer->maxcallno);
03767       ast_cli(a->fd, "  Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03768       ast_cli(a->fd, "  Trunk        : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
03769       ast_cli(a->fd, "  Encryption   : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03770       ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03771       ast_cli(a->fd, "  Expire       : %d\n", peer->expire);
03772       ast_cli(a->fd, "  ACL          : %s\n", (peer->ha ? "Yes" : "No"));
03773       ast_cli(a->fd, "  Addr->IP     : %s Port %d\n",  peer_addr.sin_addr.s_addr ? ast_inet_ntoa(peer_addr.sin_addr) : "(Unspecified)", ntohs(peer_addr.sin_port));
03774       ast_cli(a->fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03775       ast_cli(a->fd, "  Username     : %s\n", peer->username);
03776       ast_cli(a->fd, "  Codecs       : ");
03777       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03778       ast_cli(a->fd, "%s\n", codec_buf);
03779 
03780       ast_cli(a->fd, "  Codec Order  : (");
03781       for(x = 0; x < 32 ; x++) {
03782          codec = ast_codec_pref_index(&peer->prefs,x);
03783          if(!codec)
03784             break;
03785          ast_cli(a->fd, "%s", ast_getformatname(codec));
03786          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03787             ast_cli(a->fd, "|");
03788       }
03789 
03790       if (!x)
03791          ast_cli(a->fd, "none");
03792       ast_cli(a->fd, ")\n");
03793 
03794       ast_cli(a->fd, "  Status       : ");
03795       peer_status(peer, status, sizeof(status));   
03796       ast_cli(a->fd, "%s\n",status);
03797       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");
03798       ast_cli(a->fd, "\n");
03799       peer_unref(peer);
03800    } else {
03801       ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03802       ast_cli(a->fd, "\n");
03803    }
03804 
03805    return CLI_SUCCESS;
03806 }

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

Definition at line 6877 of file chan_iax2.c.

References __iax2_show_peers(), ast_cli_args::argc, ast_cli_args::argv, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, RESULT_FAILURE, RESULT_SHOWUSAGE, and ast_cli_entry::usage.

06878 {
06879    switch (cmd) {
06880    case CLI_INIT:
06881       e->command = "iax2 show peers";
06882       e->usage =
06883          "Usage: iax2 show peers [registered] [like <pattern>]\n"
06884          "       Lists all known IAX2 peers.\n"
06885          "       Optional 'registered' argument lists only peers with known addresses.\n"
06886          "       Optional regular expression pattern is used to filter the peer list.\n";
06887       return NULL;
06888    case CLI_GENERATE:
06889       return NULL;
06890    }
06891 
06892    switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
06893    case RESULT_SHOWUSAGE:
06894       return CLI_SHOWUSAGE;
06895    case RESULT_FAILURE:
06896       return CLI_FAILURE;
06897    default:
06898       return CLI_SUCCESS;
06899    }
06900 }

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

Definition at line 7032 of file chan_iax2.c.

References iax2_registry::addr, ast_cli_args::argc, ast_cli(), ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_registry::dnsmgr, iax2_registry::entry, ast_cli_args::fd, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), iax2_registry::us, ast_cli_entry::usage, and iax2_registry::username.

07033 {
07034 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
07035 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
07036    struct iax2_registry *reg = NULL;
07037    char host[80];
07038    char perceived[80];
07039    int counter = 0;
07040 
07041    switch (cmd) {
07042    case CLI_INIT:
07043       e->command = "iax2 show registry";
07044       e->usage =
07045          "Usage: iax2 show registry\n"
07046          "       Lists all registration requests and status.\n";
07047       return NULL;
07048    case CLI_GENERATE:
07049       return NULL;
07050    }
07051    if (a->argc != 3)
07052       return CLI_SHOWUSAGE;
07053    ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07054    AST_LIST_LOCK(&registrations);
07055    AST_LIST_TRAVERSE(&registrations, reg, entry) {
07056       snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
07057       if (reg->us.sin_addr.s_addr) 
07058          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07059       else
07060          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07061       ast_cli(a->fd, FORMAT, host, 
07062                (reg->dnsmgr) ? "Y" : "N", 
07063                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07064       counter++;
07065    }
07066    AST_LIST_UNLOCK(&registrations);
07067    ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07068    return CLI_SUCCESS;
07069 #undef FORMAT
07070 #undef FORMAT2
07071 }

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

Definition at line 3831 of file chan_iax2.c.

References ast_cli_args::argc, 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, ast_cli_args::fd, iax_frame::final, frame_queue, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxsl, iax2_trunk_peer::list, iax_frame::retries, and ast_cli_entry::usage.

03832 {
03833    struct iax_frame *cur;
03834    int cnt = 0, dead = 0, final = 0, i = 0;
03835 
03836    switch (cmd) {
03837    case CLI_INIT:
03838       e->command = "iax2 show stats";
03839       e->usage =
03840          "Usage: iax2 show stats\n"
03841          "       Display statistics on IAX channel driver.\n";
03842       return NULL;
03843    case CLI_GENERATE:
03844       return NULL;
03845    }
03846 
03847    if (a->argc != 3)
03848       return CLI_SHOWUSAGE;
03849 
03850    for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
03851       ast_mutex_lock(&iaxsl[i]);
03852       AST_LIST_TRAVERSE(&frame_queue[i], cur, list) {
03853          if (cur->retries < 0)
03854             dead++;
03855          if (cur->final)
03856             final++;
03857          cnt++;
03858       }
03859       ast_mutex_unlock(&iaxsl[i]);
03860    }
03861 
03862    ast_cli(a->fd, "    IAX Statistics\n");
03863    ast_cli(a->fd, "---------------------\n");
03864    ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03865    ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03866       trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03867    ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03868 
03869    trunk_timed = trunk_untimed = 0;
03870    if (trunk_maxmtu > trunk_nmaxmtu)
03871       trunk_nmaxmtu = trunk_maxmtu;
03872 
03873    return CLI_SUCCESS;
03874 }

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

Definition at line 6740 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, IAX_THREAD_TYPE_DYNAMIC, iaxthreadcount, iax2_thread::list, thread, and ast_cli_entry::usage.

06741 {
06742    struct iax2_thread *thread = NULL;
06743    time_t t;
06744    int threadcount = 0, dynamiccount = 0;
06745    char type;
06746 
06747    switch (cmd) {
06748    case CLI_INIT:
06749       e->command = "iax2 show threads";
06750       e->usage =
06751          "Usage: iax2 show threads\n"
06752          "       Lists status of IAX helper threads\n";
06753       return NULL;
06754    case CLI_GENERATE:
06755       return NULL;
06756    }
06757    if (a->argc != 3)
06758       return CLI_SHOWUSAGE;
06759       
06760    ast_cli(a->fd, "IAX2 Thread Information\n");
06761    time(&t);
06762    ast_cli(a->fd, "Idle Threads:\n");
06763    AST_LIST_LOCK(&idle_list);
06764    AST_LIST_TRAVERSE(&idle_list, thread, list) {
06765 #ifdef DEBUG_SCHED_MULTITHREAD
06766       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 
06767          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06768 #else
06769       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
06770          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06771 #endif
06772       threadcount++;
06773    }
06774    AST_LIST_UNLOCK(&idle_list);
06775    ast_cli(a->fd, "Active Threads:\n");
06776    AST_LIST_LOCK(&active_list);
06777    AST_LIST_TRAVERSE(&active_list, thread, list) {
06778       if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06779          type = 'D';
06780       else
06781          type = 'P';
06782 #ifdef DEBUG_SCHED_MULTITHREAD
06783       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 
06784          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06785 #else
06786       ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
06787          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06788 #endif
06789       threadcount++;
06790    }
06791    AST_LIST_UNLOCK(&active_list);
06792    ast_cli(a->fd, "Dynamic Threads:\n");
06793    AST_LIST_LOCK(&dynamic_list);
06794    AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06795 #ifdef DEBUG_SCHED_MULTITHREAD
06796       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06797          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06798 #else
06799       ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06800          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06801 #endif
06802       dynamiccount++;
06803    }
06804    AST_LIST_UNLOCK(&dynamic_list);
06805    ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06806    return CLI_SUCCESS;
06807 }

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

Definition at line 6529 of file chan_iax2.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_args::argc, ast_cli_args::argv, 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, ast_cli_args::fd, FORMAT, FORMAT2, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, ast_cli_entry::usage, user, user_unref(), and users.

06530 {
06531    regex_t regexbuf;
06532    int havepattern = 0;
06533 
06534 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
06535 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
06536 
06537    struct iax2_user *user = NULL;
06538    char auth[90];
06539    char *pstr = "";
06540    struct ao2_iterator i;
06541 
06542    switch (cmd) {
06543    case CLI_INIT:
06544       e->command = "iax2 show users [like]";
06545       e->usage =
06546          "Usage: iax2 show users [like <pattern>]\n"
06547          "       Lists all known IAX2 users.\n"
06548          "       Optional regular expression pattern is used to filter the user list.\n";
06549       return NULL;
06550    case CLI_GENERATE:
06551       return NULL;
06552    }
06553 
06554    switch (a->argc) {
06555    case 5:
06556       if (!strcasecmp(a->argv[3], "like")) {
06557          if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06558             return CLI_SHOWUSAGE;
06559          havepattern = 1;
06560       } else
06561          return CLI_SHOWUSAGE;
06562    case 3:
06563       break;
06564    default:
06565       return CLI_SHOWUSAGE;
06566    }
06567 
06568    ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06569    i = ao2_iterator_init(users, 0);
06570    for (user = ao2_iterator_next(&i); user; 
06571       user_unref(user), user = ao2_iterator_next(&i)) {
06572       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
06573          continue;
06574 
06575       if (!ast_strlen_zero(user->secret)) {
06576          ast_copy_string(auth,user->secret, sizeof(auth));
06577       } else if (!ast_strlen_zero(user->inkeys)) {
06578          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06579       } else
06580          ast_copy_string(auth, "-no secret-", sizeof(auth));
06581 
06582       if(ast_test_flag64(user, IAX_CODEC_NOCAP))
06583          pstr = "REQ Only";
06584       else if(ast_test_flag64(user, IAX_CODEC_NOPREFS))
06585          pstr = "Disabled";
06586       else
06587          pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06588 
06589       ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 
06590          user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06591          user->ha ? "Yes" : "No", pstr);
06592    }
06593    ao2_iterator_destroy(&i);
06594 
06595    if (havepattern)
06596       regfree(&regexbuf);
06597 
06598    return CLI_SUCCESS;
06599 #undef FORMAT
06600 #undef FORMAT2
06601 }

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

Definition at line 3611 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.

03612 {
03613    switch (cmd) {
03614    case CLI_INIT:
03615       e->command = "iax2 test losspct";
03616       e->usage =
03617          "Usage: iax2 test losspct <percentage>\n"
03618          "       For testing, throws away <percentage> percent of incoming packets\n";
03619       return NULL;
03620    case CLI_GENERATE:
03621       return NULL;
03622    }
03623    if (a->argc != 4)
03624       return CLI_SHOWUSAGE;
03625 
03626    test_losspct = atoi(a->argv[3]);
03627 
03628    return CLI_SUCCESS;
03629 }

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

Definition at line 6809 of file chan_iax2.c.

References ao2_find, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_unregister(), iax2_peer::expire, expire_registry(), ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, iax2_peer::name, OBJ_POINTER, peer_ref(), peer_unref(), peers, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

06810 {
06811    struct iax2_peer *p;
06812 
06813    switch (cmd) {
06814    case CLI_INIT:
06815       e->command = "iax2 unregister";
06816       e->usage =
06817          "Usage: iax2 unregister <peername>\n"
06818          "       Unregister (force expiration) an IAX2 peer from the registry.\n";
06819       return NULL;
06820    case CLI_GENERATE:
06821       return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06822    }
06823 
06824    if (a->argc != 3)
06825       return CLI_SHOWUSAGE;
06826 
06827    p = find_peer(a->argv[2], 1);
06828    if (p) {
06829       if (p->expire > 0) {
06830          struct iax2_peer tmp_peer = {
06831             .name = a->argv[2],
06832          };
06833          struct iax2_peer *peer;
06834 
06835          peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06836          if (peer) {
06837             expire_registry(peer_ref(peer)); /* will release its own reference when done */
06838             peer_unref(peer); /* ref from ao2_find() */
06839             ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06840          } else {
06841             ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06842          }
06843       } else {
06844          ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06845       }
06846    } else {
06847       ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06848    }
06849    return CLI_SUCCESS;
06850 }

static void handle_deferred_full_frames ( struct iax2_thread thread  )  [static]

Handle any deferred full frames for this thread.

Definition at line 9445 of file chan_iax2.c.

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

09446 {
09447    struct iax2_pkt_buf *pkt_buf;
09448 
09449    ast_mutex_lock(&thread->lock);
09450 
09451    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09452       ast_mutex_unlock(&thread->lock);
09453 
09454       thread->buf = pkt_buf->buf;
09455       thread->buf_len = pkt_buf->len;
09456       thread->buf_size = pkt_buf->len + 1;
09457       
09458       socket_process(thread);
09459 
09460       thread->buf = NULL;
09461       ast_free(pkt_buf);
09462 
09463       ast_mutex_lock(&thread->lock);
09464    }
09465 
09466    ast_mutex_unlock(&thread->lock);
09467 }

static int handle_error ( void   )  [static]

Definition at line 3266 of file chan_iax2.c.

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

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

03267 {
03268    /* XXX Ideally we should figure out why an error occurred and then abort those
03269       rather than continuing to try.  Unfortunately, the published interface does
03270       not seem to work XXX */
03271 #if 0
03272    struct sockaddr_in *sin;
03273    int res;
03274    struct msghdr m;
03275    struct sock_extended_err e;
03276    m.msg_name = NULL;
03277    m.msg_namelen = 0;
03278    m.msg_iov = NULL;
03279    m.msg_control = &e;
03280    m.msg_controllen = sizeof(e);
03281    m.msg_flags = 0;
03282    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03283    if (res < 0)
03284       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03285    else {
03286       if (m.msg_controllen) {
03287          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03288          if (sin) 
03289             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03290          else
03291             ast_log(LOG_WARNING, "No address detected??\n");
03292       } else {
03293          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03294       }
03295    }
03296 #endif
03297    return 0;
03298 }

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

Acknowledgment received for OUR registration.

Definition at line 8398 of file chan_iax2.c.

References iax2_registry::addr, iax_ies::apparent_addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_sockaddr_to_sin, ast_verb, iax_ies::calling_number, EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_replace(), iaxs, inaddrcmp(), LOG_WARNING, manager_event, iax2_registry::messages, iax_ies::msgcount, iax2_registry::refresh, iax_ies::refresh, refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, sched, iax2_registry::us, and iax_ies::username.

Referenced by socket_process().

08399 {
08400    struct iax2_registry *reg;
08401    /* Start pessimistic */
08402    char peer[256] = "";
08403    char msgstatus[60];
08404    int refresh = 60;
08405    char ourip[256] = "<Unspecified>";
08406    struct sockaddr_in oldus;
08407    struct sockaddr_in us;
08408    int oldmsgs;
08409    struct sockaddr_in reg_addr;
08410 
08411    memset(&us, 0, sizeof(us));
08412    if (ies->apparent_addr)
08413       memmove(&us, ies->apparent_addr, sizeof(us));
08414    if (ies->username)
08415       ast_copy_string(peer, ies->username, sizeof(peer));
08416    if (ies->refresh)
08417       refresh = ies->refresh;
08418    if (ies->calling_number) {
08419       /* We don't do anything with it really, but maybe we should */
08420    }
08421    reg = iaxs[callno]->reg;
08422    if (!reg) {
08423       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08424       return -1;
08425    }
08426    memcpy(&oldus, &reg->us, sizeof(oldus));
08427    oldmsgs = reg->messages;
08428    ast_sockaddr_to_sin(&reg->addr, &reg_addr);
08429    if (inaddrcmp(&reg_addr, sin)) {
08430       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08431       return -1;
08432    }
08433    memcpy(&reg->us, &us, sizeof(reg->us));
08434    if (ies->msgcount >= 0)
08435       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
08436    /* always refresh the registration at the interval requested by the server
08437       we are registering to
08438    */
08439    reg->refresh = refresh;
08440    reg->expire = iax2_sched_replace(reg->expire, sched, 
08441       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08442    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
08443          if (reg->messages > 255)
08444             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08445          else if (reg->messages > 1)
08446             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
08447          else if (reg->messages > 0)
08448             ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
08449          else
08450             ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
08451          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08452       ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08453       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08454    }
08455    reg->regstate = REG_STATE_REGISTERED;
08456    return 0;
08457 }

static int attribute_pure iax2_allow_new ( int  frametype,
int  subclass,
int  inbound 
) [inline, static]

Definition at line 2731 of file chan_iax2.c.

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

02732 {
02733    if (frametype != AST_FRAME_IAX) {
02734       return 0;
02735    }
02736    switch (subclass) {
02737    case IAX_COMMAND_NEW:
02738    case IAX_COMMAND_REGREQ:
02739    case IAX_COMMAND_FWDOWNL:
02740    case IAX_COMMAND_REGREL:
02741       return 1;
02742    case IAX_COMMAND_POKE:
02743       if (!inbound) {
02744          return 1;
02745       }
02746       break;
02747    }
02748    return 0;
02749 }

static void iax2_ami_channelupdate ( struct chan_iax2_pvt pvt  )  [static]

Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers.

Definition at line 1324 of file chan_iax2.c.

References chan_iax2_pvt::callno, EVENT_FLAG_SYSTEM, manager_event, ast_channel::name, chan_iax2_pvt::owner, chan_iax2_pvt::peer, and chan_iax2_pvt::peercallno.

Referenced by ast_iax2_new(), and iax2_answer().

01325 {
01326    manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01327       "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01328       pvt->owner ? pvt->owner->name : "",
01329       pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01330 }

static int iax2_answer ( struct ast_channel c  )  [static]

Definition at line 5581 of file chan_iax2.c.

References AST_CONTROL_ANSWER, ast_debug, AST_FRAME_CONTROL, ast_mutex_lock, ast_mutex_unlock, iax2_ami_channelupdate(), iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

05582 {
05583    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05584    ast_debug(1, "Answering IAX2 call\n");
05585    ast_mutex_lock(&iaxsl[callno]);
05586    if (iaxs[callno])
05587       iax2_ami_channelupdate(iaxs[callno]);
05588    ast_mutex_unlock(&iaxsl[callno]);
05589    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05590 }

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

Definition at line 8459 of file chan_iax2.c.

References ast_calloc, ast_copy_string(), ast_dnsmgr_lookup(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_sockaddr_set_port, iax2_registry::entry, IAX_DEFAULT_PORTNO, and IAX_DEFAULT_REG_EXPIRE.

Referenced by iax2_register().

08461 {
08462    struct iax2_registry *reg;
08463 
08464    if (!(reg = ast_calloc(1, sizeof(*reg))))
08465       return -1;
08466 
08467    if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08468       ast_free(reg);
08469       return -1;
08470    }
08471 
08472    ast_copy_string(reg->username, username, sizeof(reg->username));
08473 
08474    if (secret)
08475       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08476 
08477    reg->expire = -1;
08478    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08479    ast_sockaddr_set_port(&reg->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08480 
08481    AST_LIST_LOCK(&registrations);
08482    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
08483    AST_LIST_UNLOCK(&registrations);
08484    
08485    return 0;
08486 }

static enum ast_bridge_result iax2_bridge ( struct ast_channel c0,
struct ast_channel c1,
int  flags,
struct ast_frame **  fo,
struct ast_channel **  rc,
int  timeoutms 
) [static]

Definition at line 5426 of file chan_iax2.c.

References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, ast_mutex_lock, ast_mutex_unlock, ast_verb, chan_iax2_pvt::bridgecallno, f, iax2_tech, iaxs, iaxsl, lock_both(), PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, and unlock_both().

05427 {
05428    struct ast_channel *cs[3];
05429    struct ast_channel *who, *other;
05430    int to = -1;
05431    int res = -1;
05432    int transferstarted=0;
05433    struct ast_frame *f;
05434    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05435    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05436    struct timeval waittimer = {0, 0};
05437 
05438    /* We currently do not support native bridging if a timeoutms value has been provided */
05439    if (timeoutms > 0) {
05440       return AST_BRIDGE_FAILED;
05441    }
05442 
05443    timeoutms = -1;
05444 
05445    lock_both(callno0, callno1);
05446    if (!iaxs[callno0] || !iaxs[callno1]) {
05447       unlock_both(callno0, callno1);
05448       return AST_BRIDGE_FAILED;
05449    }
05450    /* Put them in native bridge mode */
05451    if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05452       iaxs[callno0]->bridgecallno = callno1;
05453       iaxs[callno1]->bridgecallno = callno0;
05454    }
05455    unlock_both(callno0, callno1);
05456 
05457    /* If not, try to bridge until we can execute a transfer, if we can */
05458    cs[0] = c0;
05459    cs[1] = c1;
05460    for (/* ever */;;) {
05461       /* Check in case we got masqueraded into */
05462       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05463          ast_verb(3, "Can't masquerade, we're different...\n");
05464          /* Remove from native mode */
05465          if (c0->tech == &iax2_tech) {
05466             ast_mutex_lock(&iaxsl[callno0]);
05467             iaxs[callno0]->bridgecallno = 0;
05468             ast_mutex_unlock(&iaxsl[callno0]);
05469          }
05470          if (c1->tech == &iax2_tech) {
05471             ast_mutex_lock(&iaxsl[callno1]);
05472             iaxs[callno1]->bridgecallno = 0;
05473             ast_mutex_unlock(&iaxsl[callno1]);
05474          }
05475          return AST_BRIDGE_FAILED_NOWARN;
05476       }
05477       if (c0->nativeformats != c1->nativeformats) {
05478          char buf0[256];
05479          char buf1[256];
05480          ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05481          ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05482          ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05483          /* Remove from native mode */
05484          lock_both(callno0, callno1);
05485          if (iaxs[callno0])
05486             iaxs[callno0]->bridgecallno = 0;
05487          if (iaxs[callno1])
05488             iaxs[callno1]->bridgecallno = 0;
05489          unlock_both(callno0, callno1);
05490          return AST_BRIDGE_FAILED_NOWARN;
05491       }
05492       /* check if transfered and if we really want native bridging */
05493       if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05494          /* Try the transfer */
05495          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05496                      ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05497             ast_log(LOG_WARNING, "Unable to start the transfer\n");
05498          transferstarted = 1;
05499       }
05500       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05501          /* Call has been transferred.  We're no longer involved */
05502          struct timeval now = ast_tvnow();
05503          if (ast_tvzero(waittimer)) {
05504             waittimer = now;
05505          } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05506             c0->_softhangup |= AST_SOFTHANGUP_DEV;
05507             c1->_softhangup |= AST_SOFTHANGUP_DEV;
05508             *fo = NULL;
05509             *rc = c0;
05510             res = AST_BRIDGE_COMPLETE;
05511             break;
05512          }
05513       }
05514       to = 1000;
05515       who = ast_waitfor_n(cs, 2, &to);
05516       if (timeoutms > -1) {
05517          timeoutms -= (1000 - to);
05518          if (timeoutms < 0)
05519             timeoutms = 0;
05520       }
05521       if (!who) {
05522          if (!timeoutms) {
05523             res = AST_BRIDGE_RETRY;
05524             break;
05525          }
05526          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05527             res = AST_BRIDGE_FAILED;
05528             break;
05529          }
05530          continue;
05531       }
05532       f = ast_read(who);
05533       if (!f) {
05534          *fo = NULL;
05535          *rc = who;
05536          res = AST_BRIDGE_COMPLETE;
05537          break;
05538       }
05539       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) {
05540          *fo = f;
05541          *rc = who;
05542          res =  AST_BRIDGE_COMPLETE;
05543          break;
05544       }
05545       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
05546       if ((f->frametype == AST_FRAME_VOICE) ||
05547          (f->frametype == AST_FRAME_TEXT) ||
05548          (f->frametype == AST_FRAME_VIDEO) || 
05549          (f->frametype == AST_FRAME_IMAGE) ||
05550          (f->frametype == AST_FRAME_DTMF) ||
05551          (f->frametype == AST_FRAME_CONTROL)) {
05552          /* monitored dtmf take out of the bridge.
05553           * check if we monitor the specific source.
05554           */
05555          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05556          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05557             *rc = who;
05558             *fo = f;
05559             res = AST_BRIDGE_COMPLETE;
05560             /* Remove from native mode */
05561             break;
05562          }
05563          /* everything else goes to the other side */
05564          ast_write(other, f);
05565       }
05566       ast_frfree(f);
05567       /* Swap who gets priority */
05568       cs[2] = cs[0];
05569       cs[0] = cs[1];
05570       cs[1] = cs[2];
05571    }
05572    lock_both(callno0, callno1);
05573    if(iaxs[callno0])
05574       iaxs[callno0]->bridgecallno = 0;
05575    if(iaxs[callno1])
05576       iaxs[callno1]->bridgecallno = 0;
05577    unlock_both(callno0, callno1);
05578    return res;
05579 }

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

Definition at line 4984 of file chan_iax2.c.

References ast_channel::_state, add_empty_calltoken_ie(), chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_party_connected_line::ani, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, ast_channel_datastore_find(), ast_copy_string(), 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_party_id_presentation(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), 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(), auto_congest(), CALLNO_TO_PTR, capability, ast_channel::connected, context, ast_channel::context, create_addr(), ast_datastore::data, ast_channel::dialed, chan_iax2_pvt::encmethods, ast_party_redirecting::from, ast_channel::hangupcause, iax2_datetime(), iax2_sched_add(), iax2_variable_datastore_info, 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_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, iaxs, iaxsl, ast_party_connected_line::id, chan_iax2_pvt::initid, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, chan_iax2_pvt::mohinterpret, chan_iax2_pvt::mohsuggest, ast_party_id::name, ast_channel::name, ast_channel::nativeformats, ast_party_dialed::number, ast_party_id::number, parse_dial_string(), pbx_builtin_getvar_helper(), chan_iax2_pvt::pingtime, ast_party_number::plan, PTR_TO_CALLNO, ast_channel::redirecting, sched, secret, send_command(), chan_iax2_pvt::sockfd, ast_party_dialed::str, ast_party_name::str, ast_party_number::str, ast_channel::tech_pvt, ast_party_dialed::transit_network_select, chan_iax2_pvt::username, ast_party_name::valid, ast_party_number::valid, and var.

04985 {
04986    struct sockaddr_in sin;
04987    char *l=NULL, *n=NULL, *tmpstr;
04988    struct iax_ie_data ied;
04989    char *defaultrdest = "s";
04990    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04991    struct parsed_dial_string pds;
04992    struct create_addr_info cai;
04993    struct ast_var_t *var;
04994    struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
04995    const char* osp_token_ptr;
04996    unsigned int osp_token_length;
04997    unsigned char osp_block_index;
04998    unsigned int osp_block_length;
04999    unsigned char osp_buffer[256];
05000 
05001    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
05002       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
05003       return -1;
05004    }
05005 
05006    memset(&cai, 0, sizeof(cai));
05007    cai.encmethods = iax2_encryption;
05008 
05009    memset(&pds, 0, sizeof(pds));
05010    tmpstr = ast_strdupa(dest);
05011    parse_dial_string(tmpstr, &pds);
05012 
05013    if (ast_strlen_zero(pds.peer)) {
05014       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
05015       return -1;
05016    }
05017    if (!pds.exten) {
05018       pds.exten = defaultrdest;
05019    }
05020    if (create_addr(pds.peer, c, &sin, &cai)) {
05021       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
05022       return -1;
05023    }
05024    if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) {
05025       ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
05026       c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05027       return -1;
05028    }
05029    if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
05030       ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
05031       return -1;
05032    }
05033    if (!pds.username && !ast_strlen_zero(cai.username))
05034       pds.username = cai.username;
05035    if (!pds.password && !ast_strlen_zero(cai.secret))
05036       pds.password = cai.secret;
05037    if (!pds.key && !ast_strlen_zero(cai.outkey))
05038       pds.key = cai.outkey;
05039    if (!pds.context && !ast_strlen_zero(cai.peercontext))
05040       pds.context = cai.peercontext;
05041 
05042    /* Keep track of the context for outgoing calls too */
05043    ast_copy_string(c->context, cai.context, sizeof(c->context));
05044 
05045    if (pds.port)
05046       sin.sin_port = htons(atoi(pds.port));
05047 
05048    l = c->connected.id.number.valid ? c->connected.id.number.str : NULL;
05049    n = c->connected.id.name.valid ? c->connected.id.name.str : NULL;
05050 
05051    /* Now build request */ 
05052    memset(&ied, 0, sizeof(ied));
05053 
05054    /* On new call, first IE MUST be IAX version of caller */
05055    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
05056    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
05057    if (pds.options && strchr(pds.options, 'a')) {
05058       /* Request auto answer */
05059       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
05060    }
05061 
05062    /* WARNING: this breaks down at 190 bits! */
05063    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
05064 
05065    if (l) {
05066       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
05067       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05068          ast_party_id_presentation(&c->connected.id));
05069    } else if (n) {
05070       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05071          ast_party_id_presentation(&c->connected.id));
05072    } else {
05073       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
05074    }
05075 
05076    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan);
05077    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select);
05078 
05079    if (n)
05080       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
05081    if (ast_test_flag64(iaxs[callno], IAX_SENDANI)
05082       && c->connected.ani.number.valid
05083       && c->connected.ani.number.str) {
05084       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str);
05085    }
05086 
05087    if (!ast_strlen_zero(c->language))
05088       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
05089    if (!ast_strlen_zero(c->dialed.number.str)) {
05090       iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str);
05091    }
05092    if (c->redirecting.from.number.valid
05093       && !ast_strlen_zero(c->redirecting.from.number.str)) {
05094       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str);
05095    }
05096 
05097    if (pds.context)
05098       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
05099 
05100    if (pds.username)
05101       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
05102 
05103    if (cai.encmethods)
05104       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
05105 
05106    ast_mutex_lock(&iaxsl[callno]);
05107 
05108    if (!ast_strlen_zero(c->context))
05109       ast_string_field_set(iaxs[callno], context, c->context);
05110 
05111    if (pds.username)
05112       ast_string_field_set(iaxs[callno], username, pds.username);
05113 
05114    iaxs[callno]->encmethods = cai.encmethods;
05115 
05116    iaxs[callno]->adsi = cai.adsi;
05117    
05118    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
05119    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
05120 
05121    if (pds.key)
05122       ast_string_field_set(iaxs[callno], outkey, pds.key);
05123    if (pds.password)
05124       ast_string_field_set(iaxs[callno], secret, pds.password);
05125 
05126    iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats);
05127    iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats);
05128    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
05129    iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
05130    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
05131    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
05132 
05133    if (iaxs[callno]->maxtime) {
05134       /* Initialize pingtime and auto-congest time */
05135       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
05136       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
05137    } else if (autokill) {
05138       iaxs[callno]->pingtime = autokill / 2;
05139       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
05140    }
05141 
05142    /* Check if there is an OSP token */
05143    osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
05144    if (!ast_strlen_zero(osp_token_ptr)) {
05145       if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
05146          osp_block_index = 0;
05147          while (osp_token_length > 0) {
05148             osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
05149             osp_buffer[0] = osp_block_index;
05150             memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
05151             iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
05152             osp_block_index++;
05153             osp_token_ptr += osp_block_length;
05154             osp_token_length -= osp_block_length;
05155          } 
05156       } else
05157          ast_log(LOG_WARNING, "OSP token is too long\n");
05158    } else if (iaxdebug)
05159       ast_debug(1, "OSP token is undefined\n");
05160 
05161    /* send the command using the appropriate socket for this peer */
05162    iaxs[callno]->sockfd = cai.sockfd;
05163 
05164    /* Add remote vars */
05165    if (variablestore) {
05166       AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
05167       ast_debug(1, "Found an IAX variable store on this channel\n");
05168       AST_LIST_LOCK(variablelist);
05169       AST_LIST_TRAVERSE(variablelist, var, entries) {
05170          char tmp[256];
05171          int i;
05172          ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
05173          /* Automatically divide the value up into sized chunks */
05174          for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
05175             snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
05176             iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
05177          }
05178       }
05179       AST_LIST_UNLOCK(variablelist);
05180    }
05181 
05182    /* Transmit the string in a "NEW" request */
05183    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
05184    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
05185 
05186    ast_mutex_unlock(&iaxsl[callno]);
05187    ast_setstate(c, AST_STATE_RINGING);
05188 
05189    return 0;
05190 }

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

References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_CANEXIST, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.

13670 {
13671    int res = 0;
13672    struct iax2_dpcache *dp = NULL;
13673 #if 0
13674    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13675 #endif
13676    if ((priority != 1) && (priority != 2))
13677       return 0;
13678 
13679    AST_LIST_LOCK(&dpcache);
13680    if ((dp = find_cache(chan, data, context, exten, priority))) {
13681       if (dp->flags & CACHE_FLAG_CANEXIST)
13682          res = 1;
13683    } else {
13684       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13685    }
13686    AST_LIST_UNLOCK(&dpcache);
13687 
13688    return res;
13689 }

static unsigned int iax2_datetime ( const char *  tz  )  [static]

Definition at line 4657 of file chan_iax2.c.

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

Referenced by iax2_call(), and update_registry().

04658 {
04659    struct timeval t = ast_tvnow();
04660    struct ast_tm tm;
04661    unsigned int tmp;
04662    ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04663    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
04664    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
04665    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
04666    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
04667    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
04668    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
04669    return tmp;
04670 }

static void iax2_destroy ( int  callno  )  [static]

Definition at line 3372 of file chan_iax2.c.

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

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

03373 {
03374    struct chan_iax2_pvt *pvt = NULL;
03375    struct ast_channel *owner = NULL;
03376 
03377 retry:
03378    if ((pvt = iaxs[callno])) {
03379 #if 0
03380       /* iax2_destroy_helper gets called from this function later on.  When
03381        * called twice, we get the (previously) familiar FRACK! errors in
03382        * devmode, from the scheduler.  An alternative to this approach is to
03383        * reset the scheduler entries to -1 when they're deleted in
03384        * iax2_destroy_helper().  That approach was previously decided to be
03385        * "wrong" because "the memory is going to be deallocated anyway.  Why
03386        * should we be resetting those values?" */
03387       iax2_destroy_helper(pvt);
03388 #endif
03389    }
03390 
03391    owner = pvt ? pvt->owner : NULL;
03392 
03393    if (owner) {
03394       if (ast_channel_trylock(owner)) {
03395          ast_debug(3, "Avoiding IAX destroy deadlock\n");
03396          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03397          goto retry;
03398       }
03399    }
03400 
03401    if (!owner) {
03402       iaxs[callno] = NULL;
03403    }
03404 
03405    if (pvt) {
03406       if (!owner) {
03407          pvt->owner = NULL;
03408       } else {
03409          /* If there's an owner, prod it to give up */
03410          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
03411           * because we already hold the owner channel lock. */
03412          ast_queue_hangup(owner);
03413       }
03414 
03415       if (pvt->peercallno) {
03416          remove_by_peercallno(pvt);
03417       }
03418 
03419       if (pvt->transfercallno) {
03420          remove_by_transfercallno(pvt);
03421       }
03422 
03423       if (!owner) {
03424          ao2_ref(pvt, -1);
03425          pvt = NULL;
03426       }
03427    }
03428 
03429    if (owner) {
03430       ast_channel_unlock(owner);
03431    }
03432 
03433    if (callno & 0x4000) {
03434       update_max_trunk();
03435    }
03436 }

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

References ao2_find, ast_atomic_fetchadd_int(), ast_clear_flag64, AST_SCHED_DEL_SPINLOCK, ast_sched_thread_del, ast_sched_thread_get_context(), ast_test_flag64, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::callno, DONT_RESCHEDULE, IAX_MAXAUTHREQ, iaxsl, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, iax2_user::name, OBJ_POINTER, chan_iax2_pvt::pingid, sched, user, user_unref(), chan_iax2_pvt::username, and users.

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

01773 {
01774    /* Decrement AUTHREQ count if needed */
01775    if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) {
01776       struct iax2_user *user;
01777       struct iax2_user tmp_user = {
01778          .name = pvt->username,
01779       };
01780 
01781       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01782       if (user) {
01783          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01784          user_unref(user);
01785       }
01786 
01787       ast_clear_flag64(pvt, IAX_MAXAUTHREQ);
01788    }
01789    /* No more pings or lagrq's */
01790    AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]);
01791    pvt->pingid = DONT_RESCHEDULE;
01792    AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]);
01793    pvt->lagid = DONT_RESCHEDULE;
01794    ast_sched_thread_del(sched, pvt->autoid);
01795    ast_sched_thread_del(sched, pvt->authid);
01796    ast_sched_thread_del(sched, pvt->initid);
01797    ast_sched_thread_del(sched, pvt->jbid);
01798    ast_sched_thread_del(sched, pvt->keyrotateid);
01799 }

static int iax2_devicestate ( void *  data  )  [static]

Part of the device state notification system ---.

Definition at line 13874 of file chan_iax2.c.

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

13875 {
13876    struct parsed_dial_string pds;
13877    char *tmp = ast_strdupa(data);
13878    struct iax2_peer *p;
13879    int res = AST_DEVICE_INVALID;
13880 
13881    memset(&pds, 0, sizeof(pds));
13882    parse_dial_string(tmp, &pds);
13883 
13884    if (ast_strlen_zero(pds.peer)) {
13885       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13886       return res;
13887    }
13888    
13889    ast_debug(3, "Checking device state for device %s\n", pds.peer);
13890 
13891    /* SLD: FIXME: second call to find_peer during registration */
13892    if (!(p = find_peer(pds.peer, 1)))
13893       return res;
13894 
13895    res = AST_DEVICE_UNAVAILABLE;
13896    ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13897       pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13898    
13899    if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
13900        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13901       /* Peer is registered, or have default IP address
13902          and a valid registration */
13903       if (p->historicms == 0 || p->historicms <= p->maxms)
13904          /* let the core figure out whether it is in use or not */
13905          res = AST_DEVICE_UNKNOWN;  
13906    }
13907 
13908    peer_unref(p);
13909 
13910    return res;
13911 }

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

Definition at line 4262 of file chan_iax2.c.

References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

04263 {
04264    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04265 }

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

Definition at line 4267 of file chan_iax2.c.

References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

04268 {
04269    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04270 }

static int iax2_do_register ( struct iax2_registry reg  )  [static]

Definition at line 11683 of file chan_iax2.c.

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_ipv4(), ast_sockaddr_to_sin, iax2_registry::callno, 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, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), and iax2_registry::username.

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

11684 {
11685    struct iax_ie_data ied;
11686    if (iaxdebug)
11687       ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11688 
11689    if (reg->dnsmgr && 
11690        ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(&reg->addr))) {
11691       /* Maybe the IP has changed, force DNS refresh */
11692       ast_dnsmgr_refresh(reg->dnsmgr);
11693    }
11694    
11695    /*
11696     * if IP has Changed, free allocated call to create a new one with new IP
11697     * call has the pointer to IP and must be updated to the new one
11698     */
11699    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11700       int callno = reg->callno;
11701       ast_mutex_lock(&iaxsl[callno]);
11702       iax2_destroy(callno);
11703       ast_mutex_unlock(&iaxsl[callno]);
11704       reg->callno = 0;
11705    }
11706    if (!ast_sockaddr_ipv4(&reg->addr)) {
11707       if (iaxdebug)
11708          ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11709       /* Setup the next registration attempt */
11710       reg->expire = iax2_sched_replace(reg->expire, sched, 
11711          (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11712       return -1;
11713    }
11714 
11715    if (!reg->callno) {
11716       struct sockaddr_in reg_addr;
11717 
11718       ast_debug(3, "Allocate call number\n");
11719 
11720       ast_sockaddr_to_sin(&reg->addr, &reg_addr);
11721 
11722       reg->callno = find_callno_locked(0, 0, &reg_addr, NEW_FORCE, defaultsockfd, 0);
11723       if (reg->callno < 1) {
11724          ast_log(LOG_WARNING, "Unable to create call for registration\n");
11725          return -1;
11726       } else
11727          ast_debug(3, "Registration created on call %d\n", reg->callno);
11728       iaxs[reg->callno]->reg = reg;
11729       ast_mutex_unlock(&iaxsl[reg->callno]);
11730    }
11731    /* Setup the next registration a little early */
11732    reg->expire = iax2_sched_replace(reg->expire, sched, 
11733       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11734    /* Send the request */
11735    memset(&ied, 0, sizeof(ied));
11736    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11737    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11738    add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */
11739    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11740    reg->regstate = REG_STATE_REGSENT;
11741    return 0;
11742 }

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

Definition at line 8245 of file chan_iax2.c.

References __iax2_do_register_s(), and schedule_action.

Referenced by iax2_ack_registry(), and iax2_do_register().

08246 {
08247 #ifdef SCHED_MULTITHREADED
08248    if (schedule_action(__iax2_do_register_s, data))
08249 #endif      
08250       __iax2_do_register_s(data);
08251    return 0;
08252 }

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

Definition at line 9010 of file chan_iax2.c.

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

Referenced by find_cache(), and socket_process().

09011 {
09012    struct iax_ie_data ied;
09013    /* Auto-hangup with 30 seconds of inactivity */
09014    iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
09015       sched, 30000, auto_hangup, (void *)(long)callno);
09016    memset(&ied, 0, sizeof(ied));
09017    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09018    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09019    dp->flags |= CACHE_FLAG_TRANSMITTED;
09020 }

static void * iax2_dup_variable_datastore ( void *   )  [static]

Definition at line 1338 of file chan_iax2.c.

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, and LOG_ERROR.

01339 {
01340    AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01341    struct ast_var_t *oldvar, *newvar;
01342 
01343    newlist = ast_calloc(sizeof(*newlist), 1);
01344    if (!newlist) {
01345       ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01346       return NULL;
01347    }
01348 
01349    AST_LIST_HEAD_INIT(newlist);
01350    AST_LIST_LOCK(oldlist);
01351    AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01352       newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01353       if (newvar)
01354          AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01355       else
01356          ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01357    }
01358    AST_LIST_UNLOCK(oldlist);
01359    return newlist;
01360 }

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

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_verb, CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_exec(), and pbx_findapp().

13716 {
13717    char odata[256];
13718    char req[256];
13719    char *ncontext;
13720    struct iax2_dpcache *dp = NULL;
13721    struct ast_app *dial = NULL;
13722 #if 0
13723    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);
13724 #endif
13725    if (priority == 2) {
13726       /* Indicate status, can be overridden in dialplan */
13727       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13728       if (dialstatus) {
13729          dial = pbx_findapp(dialstatus);
13730          if (dial) 
13731             pbx_exec(chan, dial, "");
13732       }
13733       return -1;
13734    } else if (priority != 1)
13735       return -1;
13736 
13737    AST_LIST_LOCK(&dpcache);
13738    if ((dp = find_cache(chan, data, context, exten, priority))) {
13739       if (dp->flags & CACHE_FLAG_EXISTS) {
13740          ast_copy_string(odata, data, sizeof(odata));
13741          ncontext = strchr(odata, '/');
13742          if (ncontext) {
13743             *ncontext = '\0';
13744             ncontext++;
13745             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13746          } else {
13747             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13748          }
13749          ast_verb(3, "Executing Dial('%s')\n", req);
13750       } else {
13751          AST_LIST_UNLOCK(&dpcache);
13752          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13753          return -1;
13754       }
13755    }
13756    AST_LIST_UNLOCK(&dpcache);
13757 
13758    if ((dial = pbx_findapp("Dial")))
13759       return pbx_exec(chan, dial, req);
13760    else
13761       ast_log(LOG_WARNING, "No dial application registered\n");
13762 
13763    return -1;
13764 }

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

References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.

13647 {
13648    int res = 0;
13649    struct iax2_dpcache *dp = NULL;
13650 #if 0
13651    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13652 #endif
13653    if ((priority != 1) && (priority != 2))
13654       return 0;
13655 
13656    AST_LIST_LOCK(&dpcache);
13657    if ((dp = find_cache(chan, data, context, exten, priority))) {
13658       if (dp->flags & CACHE_FLAG_EXISTS)
13659          res = 1;
13660    } else {
13661       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13662    }
13663    AST_LIST_UNLOCK(&dpcache);
13664 
13665    return res;
13666 }

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

Definition at line 4289 of file chan_iax2.c.

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

04290 {
04291    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04292    ast_mutex_lock(&iaxsl[callno]);
04293    if (iaxs[callno])
04294       iaxs[callno]->owner = newchan;
04295    else
04296       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04297    ast_mutex_unlock(&iaxsl[callno]);
04298    return 0;
04299 }

static void iax2_frame_free ( struct iax_frame fr  )  [static]

Definition at line 1801 of file chan_iax2.c.

References ast_sched_thread_del, iax_frame_free(), iax_frame::retrans, and sched.

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

01802 {
01803    ast_sched_thread_del(sched, fr->retrans);
01804    iax_frame_free(fr);
01805 }

static void iax2_free_variable_datastore ( void *   )  [static]

Definition at line 1362 of file chan_iax2.c.

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.

01363 {
01364    AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01365    struct ast_var_t *oldvar;
01366 
01367    AST_LIST_LOCK(oldlist);
01368    while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01369       ast_free(oldvar);
01370    }
01371    AST_LIST_UNLOCK(oldlist);
01372    AST_LIST_HEAD_DESTROY(oldlist);
01373    ast_free(oldlist);
01374 }

static int iax2_getpeername ( struct sockaddr_in  sin,
char *  host,
int  len 
) [static]

Definition at line 1735 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), ast_sockaddr_to_sin, iax2_peer::name, peer_unref(), peers, and realtime_peer().

Referenced by __find_callno().

01736 {
01737    struct iax2_peer *peer = NULL;
01738    int res = 0;
01739    struct ao2_iterator i;
01740 
01741    i = ao2_iterator_init(peers, 0);
01742    while ((peer = ao2_iterator_next(&i))) {
01743       struct sockaddr_in peer_addr;
01744 
01745       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
01746 
01747       if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01748           (peer_addr.sin_port == sin.sin_port)) {
01749          ast_copy_string(host, peer->name, len);
01750          peer_unref(peer);
01751          res = 1;
01752          break;
01753       }
01754       peer_unref(peer);
01755    }
01756    ao2_iterator_destroy(&i);
01757 
01758    if (!peer) {
01759       peer = realtime_peer(NULL, &sin);
01760       if (peer) {
01761          ast_copy_string(host, peer->name, len);
01762          peer_unref(peer);
01763          res = 1;
01764       }
01765    }
01766 
01767    return res;
01768 }

static int iax2_getpeertrunk ( struct sockaddr_in  sin  )  [static]

Definition at line 5656 of file chan_iax2.c.

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

Referenced by check_access().

05657 {
05658    struct iax2_peer *peer;
05659    int res = 0;
05660    struct ao2_iterator i;
05661 
05662    i = ao2_iterator_init(peers, 0);
05663    while ((peer = ao2_iterator_next(&i))) {
05664       struct sockaddr_in peer_addr;
05665 
05666       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05667 
05668       if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05669           (peer_addr.sin_port == sin.sin_port)) {
05670          res = ast_test_flag64(peer, IAX_TRUNK);
05671          peer_unref(peer);
05672          break;
05673       }
05674       peer_unref(peer);
05675    }
05676    ao2_iterator_destroy(&i);
05677 
05678    return res;
05679 }

static int iax2_hangup ( struct ast_channel c  )  [static]

Definition at line 5192 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_add(), ast_test_flag64, ast_verb, CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_ERROR, LOG_WARNING, ast_channel::name, PTR_TO_CALLNO, sched, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.

05193 {
05194    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05195    struct iax_ie_data ied;
05196    int alreadygone;
05197    memset(&ied, 0, sizeof(ied));
05198    ast_mutex_lock(&iaxsl[callno]);
05199    if (callno && iaxs[callno]) {
05200       ast_debug(1, "We're hanging up %s now...\n", c->name);
05201       alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
05202       /* Send the hangup unless we have had a transmission error or are already gone */
05203       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05204       if (!iaxs[callno]->error && !alreadygone) {
05205          if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05206             ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05207          }
05208          if (!iaxs[callno]) {
05209             ast_mutex_unlock(&iaxsl[callno]);
05210             return 0;
05211          }
05212       }
05213       /* Explicitly predestroy it */
05214       iax2_predestroy(callno);
05215       /* If we were already gone to begin with, destroy us now */
05216       if (iaxs[callno] && alreadygone) {
05217          ast_debug(1, "Really destroying %s now...\n", c->name);
05218          iax2_destroy(callno);
05219       } else if (iaxs[callno]) {
05220          if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05221             ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!!  Destroying immediately.\n", callno);
05222             iax2_destroy(callno);
05223          }
05224       }
05225    } else if (c->tech_pvt) {
05226       /* If this call no longer exists, but the channel still
05227        * references it we need to set the channel's tech_pvt to null
05228        * to avoid ast_channel_free() trying to free it.
05229        */
05230       c->tech_pvt = NULL;
05231    }
05232    ast_mutex_unlock(&iaxsl[callno]);
05233    ast_verb(3, "Hungup '%s'\n", c->name);
05234    return 0;
05235 }

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

Definition at line 5592 of file chan_iax2.c.

References AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_CONTROL, ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, IAX_SENDCONNECTEDLINE, iaxs, iaxsl, chan_iax2_pvt::mohinterpret, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().

05593 {
05594    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05595    struct chan_iax2_pvt *pvt;
05596    int res = 0;
05597 
05598    if (iaxdebug)
05599       ast_debug(1, "Indicating condition %d\n", condition);
05600 
05601    ast_mutex_lock(&iaxsl[callno]);
05602    pvt = iaxs[callno];
05603 
05604    if (wait_for_peercallno(pvt)) {
05605       res = -1;
05606       goto done;
05607    }
05608 
05609    switch (condition) {
05610    case AST_CONTROL_HOLD:
05611       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05612          ast_moh_start(c, data, pvt->mohinterpret);
05613          goto done;
05614       }
05615       break;
05616    case AST_CONTROL_UNHOLD:
05617       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05618          ast_moh_stop(c);
05619          goto done;
05620       }
05621       break;
05622    case AST_CONTROL_CONNECTED_LINE:
05623       if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
05624          goto done;
05625       break;
05626    }
05627 
05628    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05629 
05630 done:
05631    ast_mutex_unlock(&iaxsl[callno]);
05632 
05633    return res;
05634 }

static int iax2_key_rotate ( const void *  vpvt  )  [static]

Definition at line 5344 of file chan_iax2.c.

References AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_sched_thread_add(), iax_ie_data::buf, build_ecx_key(), chan_iax2_pvt::callno, 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, sched, and send_command().

Referenced by iax2_send().

05345 {
05346    int res = 0;
05347    struct chan_iax2_pvt *pvt = (void *) vpvt;
05348    struct MD5Context md5;
05349    char key[17] = "";
05350    struct iax_ie_data ied = {
05351       .pos = 0,   
05352    };
05353    
05354    ast_mutex_lock(&iaxsl[pvt->callno]);
05355    pvt->keyrotateid = 
05356       ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05357 
05358    snprintf(key, sizeof(key), "%lX", ast_random());
05359 
05360    MD5Init(&md5);
05361    MD5Update(&md5, (unsigned char *) key, strlen(key));
05362    MD5Final((unsigned char *) key, &md5);
05363 
05364    IAX_DEBUGDIGEST("Sending", key);
05365 
05366    iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05367 
05368    res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05369 
05370    build_ecx_key((unsigned char *) key, pvt);
05371 
05372    ast_mutex_unlock(&iaxsl[pvt->callno]);
05373 
05374    return res;
05375 }

static void iax2_lock_owner ( int  callno  )  [static]

Definition at line 1258 of file chan_iax2.c.

References ast_channel_trylock, DEADLOCK_AVOIDANCE, iaxs, and iaxsl.

Referenced by iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), schedule_delivery(), set_hangup_source_and_cause(), and socket_process().

01259 {
01260    for (;;) {
01261       if (!iaxs[callno] || !iaxs[callno]->owner) {
01262          /* There is no owner lock to get. */
01263          break;
01264       }
01265       if (!ast_channel_trylock(iaxs[callno]->owner)) {
01266          /* We got the lock */
01267          break;
01268       }
01269       /* Avoid deadlock by pausing and trying again */
01270       DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01271    }
01272 }

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

References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_MATCHMORE, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.

13693 {
13694    int res = 0;
13695    struct iax2_dpcache *dp = NULL;
13696 #if 0
13697    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13698 #endif
13699    if ((priority != 1) && (priority != 2))
13700       return 0;
13701 
13702    AST_LIST_LOCK(&dpcache);
13703    if ((dp = find_cache(chan, data, context, exten, priority))) {
13704       if (dp->flags & CACHE_FLAG_MATCHMORE)
13705          res = 1;
13706    } else {
13707       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13708    }
13709    AST_LIST_UNLOCK(&dpcache);
13710 
13711    return res;
13712 }

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

Definition at line 11887 of file chan_iax2.c.

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

Referenced by iax2_poke_peer().

11888 {
11889    struct iax2_peer *peer = (struct iax2_peer *)data;
11890    peer->pokeexpire = -1;
11891 #ifdef SCHED_MULTITHREADED
11892    if (schedule_action(__iax2_poke_noanswer, data))
11893 #endif      
11894       __iax2_poke_noanswer(data);
11895    peer_unref(peer);
11896    return 0;
11897 }

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

Definition at line 11908 of file chan_iax2.c.

References add_empty_calltoken_ie(), iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, ast_sockaddr_ipv4(), ast_sockaddr_to_sin, iax_ie_data::buf, iax2_peer::callno, DEFAULT_MAXMS, 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, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax_ie_data::pos, sched, 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().

11909 {
11910    int callno;
11911    struct sockaddr_in peer_addr;
11912 
11913    if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
11914       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
11915         immediately after clearing things out */
11916       peer->lastms = 0;
11917       peer->historicms = 0;
11918       peer->pokeexpire = -1;
11919       peer->callno = 0;
11920       return 0;
11921    }
11922 
11923    ast_sockaddr_to_sin(&peer->addr, &peer_addr);
11924 
11925    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
11926    if ((callno = peer->callno) > 0) {
11927       ast_log(LOG_NOTICE, "Still have a callno...\n");
11928       ast_mutex_lock(&iaxsl[callno]);
11929       iax2_destroy(callno);
11930       ast_mutex_unlock(&iaxsl[callno]);
11931    }
11932    if (heldcall)
11933       ast_mutex_unlock(&iaxsl[heldcall]);
11934    callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
11935    if (heldcall)
11936       ast_mutex_lock(&iaxsl[heldcall]);
11937    if (peer->callno < 1) {
11938       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
11939       return -1;
11940    }
11941 
11942    /* Speed up retransmission times for this qualify call */
11943    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
11944    iaxs[peer->callno]->peerpoke = peer;
11945 
11946    if (peer->pokeexpire > -1) {
11947       if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
11948          peer->pokeexpire = -1;
11949          peer_unref(peer);
11950       }
11951    }
11952  
11953    /* Queue up a new task to handle no reply */
11954    /* If the host is already unreachable then use the unreachable interval instead */
11955    if (peer->lastms < 0)
11956       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
11957    else
11958       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
11959 
11960    if (peer->pokeexpire == -1)
11961       peer_unref(peer);
11962 
11963    /* And send the poke */
11964    ast_mutex_lock(&iaxsl[callno]);
11965    if (iaxs[callno]) {
11966       struct iax_ie_data ied = {
11967          .buf = { 0 },
11968          .pos = 0,
11969       };
11970       add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
11971       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
11972    }
11973    ast_mutex_unlock(&iaxsl[callno]);
11974 
11975    return 0;
11976 }

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

Definition at line 11899 of file chan_iax2.c.

References iax2_poke_peer().

Referenced by load_module().

11900 {
11901    struct iax2_peer *peer = obj;
11902 
11903    iax2_poke_peer(peer, 0);
11904 
11905    return 0;
11906 }

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

Definition at line 9047 of file chan_iax2.c.

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

Referenced by __iax2_poke_noanswer(), and socket_process().

09048 {
09049    struct iax2_peer *peer = (struct iax2_peer *)data;
09050    peer->pokeexpire = -1;
09051 #ifdef SCHED_MULTITHREADED
09052    if (schedule_action(__iax2_poke_peer_s, data))
09053 #endif      
09054       __iax2_poke_peer_s(data);
09055    return 0;
09056 }

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

References ast_module_unref(), ast_set_flag64, ast_test_flag64, iax2_destroy_helper(), iax2_queue_hangup(), IAX_ALREADYGONE, iaxs, chan_iax2_pvt::owner, and ast_channel::tech_pvt.

Referenced by iax2_hangup(), and send_command_final().

03350 {
03351    struct ast_channel *c = NULL;
03352    struct chan_iax2_pvt *pvt = iaxs[callno];
03353 
03354    if (!pvt)
03355       return -1;
03356 
03357    if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
03358       iax2_destroy_helper(pvt);
03359       ast_set_flag64(pvt, IAX_ALREADYGONE);
03360    }
03361 
03362    if ((c = pvt->owner)) {
03363       c->tech_pvt = NULL;
03364       iax2_queue_hangup(callno);
03365       pvt->owner = NULL;
03366       ast_module_unref(ast_module_info->self);
03367    }
03368 
03369    return 0;
03370 }

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

Definition at line 11544 of file chan_iax2.c.

References ast_atomic_fetchadd_int(), ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), iax2_process_thread_cleanup(), IAX_THREAD_TYPE_DYNAMIC, iaxactivethreadcount, insert_idle_thread(), signal_condition(), and thread.

Referenced by find_idle_thread(), and start_network_thread().

11545 {
11546    struct iax2_thread *thread = data;
11547    struct timeval wait;
11548    struct timespec ts;
11549    int put_into_idle = 0;
11550    int first_time = 1;
11551    int old_state;
11552 
11553    ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11554 
11555    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11556    pthread_cleanup_push(iax2_process_thread_cleanup, data);
11557 
11558    for (;;) {
11559       /* Wait for something to signal us to be awake */
11560       ast_mutex_lock(&thread->lock);
11561 
11562       if (thread->stop) {
11563          ast_mutex_unlock(&thread->lock);
11564          break;
11565       }
11566 
11567       /* Flag that we're ready to accept signals */
11568       if (first_time) {
11569          signal_condition(&thread->init_lock, &thread->init_cond);
11570          first_time = 0;
11571       }
11572 
11573       /* Put into idle list if applicable */
11574       if (put_into_idle) {
11575          insert_idle_thread(thread);
11576       }
11577 
11578       if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11579          struct iax2_thread *t = NULL;
11580          /* Wait to be signalled or time out */
11581          wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11582          ts.tv_sec = wait.tv_sec;
11583          ts.tv_nsec = wait.tv_usec * 1000;
11584          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11585             /* This thread was never put back into the available dynamic
11586              * thread list, so just go away. */
11587             if (!put_into_idle || thread->stop) {
11588                ast_mutex_unlock(&thread->lock);
11589                break;
11590             }
11591             AST_LIST_LOCK(&dynamic_list);
11592             /* Account for the case where this thread is acquired *right* after a timeout */
11593             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11594                ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11595             AST_LIST_UNLOCK(&dynamic_list);
11596             if (t) {
11597                /* This dynamic thread timed out waiting for a task and was
11598                 * not acquired immediately after the timeout, 
11599                 * so it's time to go away. */
11600                ast_mutex_unlock(&thread->lock);
11601                break;
11602             }
11603             /* Someone grabbed our thread *right* after we timed out.
11604              * Wait for them to set us up with something to do and signal
11605              * us to continue. */
11606             wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11607             ts.tv_sec = wait.tv_sec;
11608             ts.tv_nsec = wait.tv_usec * 1000;
11609             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11610                ast_mutex_unlock(&thread->lock);
11611                break;
11612             }
11613          }
11614       } else {
11615          ast_cond_wait(&thread->cond, &thread->lock);
11616       }
11617 
11618       /* Go back into our respective list */
11619       put_into_idle = 1;
11620 
11621       ast_mutex_unlock(&thread->lock);
11622 
11623       if (thread->stop) {
11624          break;
11625       }
11626 
11627       if (thread->iostate == IAX_IOSTATE_IDLE)
11628          continue;
11629 
11630       /* See what we need to do */
11631       switch (thread->iostate) {
11632       case IAX_IOSTATE_READY:
11633          thread->actions++;
11634          thread->iostate = IAX_IOSTATE_PROCESSING;
11635          socket_process(thread);
11636          handle_deferred_full_frames(thread);
11637          break;
11638       case IAX_IOSTATE_SCHEDREADY:
11639          thread->actions++;
11640          thread->iostate = IAX_IOSTATE_PROCESSING;
11641 #ifdef SCHED_MULTITHREADED
11642          thread->schedfunc(thread->scheddata);
11643 #endif      
11644       default:
11645          break;
11646       }
11647       time(&thread->checktime);
11648       thread->iostate = IAX_IOSTATE_IDLE;
11649 #ifdef DEBUG_SCHED_MULTITHREAD
11650       thread->curfunc[0]='\0';
11651 #endif      
11652 
11653       /* The network thread added us to the active_thread list when we were given
11654        * frames to process, Now that we are done, we must remove ourselves from
11655        * the active list, and return to the idle list */
11656       AST_LIST_LOCK(&active_list);
11657       AST_LIST_REMOVE(&active_list, thread, list);
11658       AST_LIST_UNLOCK(&active_list);
11659 
11660       /* Make sure another frame didn't sneak in there after we thought we were done. */
11661       handle_deferred_full_frames(thread);
11662    }
11663 
11664    /*!\note For some reason, idle threads are exiting without being removed
11665     * from an idle list, which is causing memory corruption.  Forcibly remove
11666     * it from the list, if it's there.
11667     */
11668    AST_LIST_LOCK(&idle_list);
11669    AST_LIST_REMOVE(&idle_list, thread, list);
11670    AST_LIST_UNLOCK(&idle_list);
11671 
11672    AST_LIST_LOCK(&dynamic_list);
11673    AST_LIST_REMOVE(&dynamic_list, thread, list);
11674    AST_LIST_UNLOCK(&dynamic_list);
11675 
11676    /* I am exiting here on my own volition, I need to clean up my own data structures
11677    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
11678    */
11679    pthread_cleanup_pop(1);
11680    return NULL;
11681 }

static void iax2_process_thread_cleanup ( void *  data  )  [static]

Definition at line 11533 of file chan_iax2.c.

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

Referenced by iax2_process_thread().

11534 {
11535    struct iax2_thread *thread = data;
11536    ast_mutex_destroy(&thread->lock);
11537    ast_cond_destroy(&thread->cond);
11538    ast_mutex_destroy(&thread->init_lock);
11539    ast_cond_destroy(&thread->init_cond);
11540    ast_free(thread);
11541    ast_atomic_dec_and_test(&iaxactivethreadcount);
11542 }

static int iax2_provision ( struct sockaddr_in *  end,
int  sockfd,
const char *  dest,
const char *  template,
int  force 
) [static]

Definition at line 11744 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_mutex_unlock, ast_set_flag64, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), 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, iax_ie_data::pos, sched, and send_command().

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

11745 {
11746    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
11747       is found for template */
11748    struct iax_ie_data provdata;
11749    struct iax_ie_data ied;
11750    unsigned int sig;
11751    struct sockaddr_in sin;
11752    int callno;
11753    struct create_addr_info cai;
11754 
11755    memset(&cai, 0, sizeof(cai));
11756 
11757    ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11758 
11759    if (iax_provision_build(&provdata, &sig, template, force)) {
11760       ast_debug(1, "No provisioning found for template '%s'\n", template);
11761       return 0;
11762    }
11763 
11764    if (end) {
11765       memcpy(&sin, end, sizeof(sin));
11766       cai.sockfd = sockfd;
11767    } else if (create_addr(dest, NULL, &sin, &cai))
11768       return -1;
11769 
11770    /* Build the rest of the message */
11771    memset(&ied, 0, sizeof(ied));
11772    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11773 
11774    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11775    if (!callno)
11776       return -1;
11777 
11778    if (iaxs[callno]) {
11779       /* Schedule autodestruct in case they don't ever give us anything back */
11780       iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
11781          sched, 15000, auto_hangup, (void *)(long)callno);
11782       ast_set_flag64(iaxs[callno], IAX_PROVISION);
11783       /* Got a call number now, so go ahead and send the provisioning information */
11784       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11785    }
11786    ast_mutex_unlock(&iaxsl[callno]);
11787 
11788    return 1;
11789 }

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

Definition at line 5321 of file chan_iax2.c.

References ast_mutex_lock, ast_mutex_unlock, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_test_flag64, chan_iax2_pvt::callno, IAX_FORCE_ENCRYPT, iaxs, iaxsl, PTR_TO_CALLNO, and ast_channel::tech_pvt.

05322 {
05323    switch (option) {
05324    case AST_OPTION_SECURE_SIGNALING:
05325    case AST_OPTION_SECURE_MEDIA:
05326    {
05327       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05328       ast_mutex_lock(&iaxsl[callno]);
05329       *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05330       ast_mutex_unlock(&iaxsl[callno]);
05331       return 0;
05332    }
05333    default:
05334       return -1;
05335    }
05336 }

static int iax2_queue_control_data ( int  callno,
enum ast_control_frame_type  control,
const void *  data,
size_t  datalen 
) [static]

Queue a control frame on the ast_channel owner.

This function queues a control 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 2982 of file chan_iax2.c.

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

Referenced by socket_process().

02984 {
02985    iax2_lock_owner(callno);
02986    if (iaxs[callno] && iaxs[callno]->owner) {
02987       ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02988       ast_channel_unlock(iaxs[callno]->owner);
02989    }
02990    return 0;
02991 }

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

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

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

02937 {
02938    iax2_lock_owner(callno);
02939    if (iaxs[callno] && iaxs[callno]->owner) {
02940       ast_queue_frame(iaxs[callno]->owner, f);
02941       ast_channel_unlock(iaxs[callno]->owner);
02942    }
02943    return 0;
02944 }

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

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

Referenced by iax2_predestroy().

02960 {
02961    iax2_lock_owner(callno);
02962    if (iaxs[callno] && iaxs[callno]->owner) {
02963       ast_queue_hangup(iaxs[callno]->owner);
02964       ast_channel_unlock(iaxs[callno]->owner);
02965    }
02966    return 0;
02967 }

static struct ast_frame * iax2_read ( struct ast_channel c  )  [static]

Definition at line 5338 of file chan_iax2.c.

References ast_log(), ast_null_frame, and LOG_NOTICE.

05339 {
05340    ast_log(LOG_NOTICE, "I should never be called!\n");
05341    return &ast_null_frame;
05342 }

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

Definition at line 8488 of file chan_iax2.c.

References ast_copy_string(), ast_log(), copy(), hostname, iax2_append_register(), LOG_WARNING, secret, and strsep().

Referenced by set_config().

08489 {
08490    char copy[256];
08491    char *username, *hostname, *secret;
08492    char *porta;
08493    char *stringp=NULL;
08494    
08495    if (!value)
08496       return -1;
08497 
08498    ast_copy_string(copy, value, sizeof(copy));
08499    stringp = copy;
08500    username = strsep(&stringp, "@");
08501    hostname = strsep(&stringp, "@");
08502 
08503    if (!hostname) {
08504       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08505       return -1;
08506    }
08507 
08508    stringp = username;
08509    username = strsep(&stringp, ":");
08510    secret = strsep(&stringp, ":");
08511    stringp = hostname;
08512    hostname = strsep(&stringp, ":");
08513    porta = strsep(&stringp, ":");
08514    
08515    if (porta && !atoi(porta)) {
08516       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08517       return -1;
08518    }
08519 
08520    return iax2_append_register(hostname, username, secret, porta);
08521 }

static struct ast_channel * iax2_request ( const char *  type,
format_t  format,
const struct ast_channel requestor,
void *  data,
int *  cause 
) [static]

Definition at line 11988 of file chan_iax2.c.

References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags64, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_unlock, AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_translator_best_choice(), create_addr(), find_callno_locked(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, ast_channel::linkedid, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), chan_iax2_pvt::peer, ast_channel::readformat, and ast_channel::writeformat.

11989 {
11990    int callno;
11991    int res;
11992    format_t fmt, native;
11993    struct sockaddr_in sin;
11994    struct ast_channel *c;
11995    struct parsed_dial_string pds;
11996    struct create_addr_info cai;
11997    char *tmpstr;
11998 
11999    memset(&pds, 0, sizeof(pds));
12000    tmpstr = ast_strdupa(data);
12001    parse_dial_string(tmpstr, &pds);
12002 
12003    if (ast_strlen_zero(pds.peer)) {
12004       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12005       return NULL;
12006    }
12007           
12008    memset(&cai, 0, sizeof(cai));
12009    cai.capability = iax2_capability;
12010 
12011    ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12012    
12013    /* Populate our address from the given */
12014    if (create_addr(pds.peer, NULL, &sin, &cai)) {
12015       *cause = AST_CAUSE_UNREGISTERED;
12016       return NULL;
12017    }
12018 
12019    if (pds.port)
12020       sin.sin_port = htons(atoi(pds.port));
12021 
12022    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12023    if (callno < 1) {
12024       ast_log(LOG_WARNING, "Unable to create call\n");
12025       *cause = AST_CAUSE_CONGESTION;
12026       return NULL;
12027    }
12028 
12029    /* If this is a trunk, update it now */
12030    ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12031    if (ast_test_flag64(&cai, IAX_TRUNK)) {
12032       int new_callno;
12033       if ((new_callno = make_trunk(callno, 1)) != -1)
12034          callno = new_callno;
12035    }
12036    iaxs[callno]->maxtime = cai.maxtime;
12037    if (cai.found)
12038       ast_string_field_set(iaxs[callno], host, pds.peer);
12039 
12040    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL);
12041 
12042    ast_mutex_unlock(&iaxsl[callno]);
12043 
12044    if (c) {
12045       /* Choose a format we can live with */
12046       if (c->nativeformats & format) 
12047          c->nativeformats &= format;
12048       else {
12049          native = c->nativeformats;
12050          fmt = format;
12051          res = ast_translator_best_choice(&fmt, &native);
12052          if (res < 0) {
12053             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12054                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
12055             ast_hangup(c);
12056             return NULL;
12057          }
12058          c->nativeformats = native;
12059       }
12060       c->readformat = ast_best_codec(c->nativeformats);
12061       c->writeformat = c->readformat;
12062    }
12063 
12064    return c;
12065 }

static int iax2_sched_add ( struct ast_sched_thread st,
int  when,
ast_sched_cb  callback,
const void *  data 
) [static]

Definition at line 1498 of file chan_iax2.c.

References ast_sched_thread_add().

Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), iax2_call(), iax2_poke_peer(), make_trunk(), network_change_event_cb(), reg_source_db(), sched_delay_remove(), socket_process(), transmit_frame(), and update_registry().

01500 {
01501    return ast_sched_thread_add(st, when, callback, data);
01502 }

static int iax2_sched_replace ( int  id,
struct ast_sched_thread st,
int  when,
ast_sched_cb  callback,
const void *  data 
) [static]

Definition at line 1490 of file chan_iax2.c.

References ast_sched_thread_add(), and ast_sched_thread_del.

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

01492 {
01493    ast_sched_thread_del(st, id);
01494 
01495    return ast_sched_thread_add(st, when, callback, data);
01496 }

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

References iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag64, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, ast_frame_subclass::codec, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, ast_frame::datalen, iax_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, iax_frame::encmethods, encrypt_frame(), f, iax_frame::final, chan_iax2_pvt::first_iax_message, 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, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::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, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::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, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_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().

06320 {
06321    /* Queue a packet for delivery on a given private structure.  Use "ts" for
06322       timestamp, or calculate if ts is 0.  Send immediately without retransmission
06323       or delayed, with retransmission */
06324    struct ast_iax2_full_hdr *fh;
06325    struct ast_iax2_mini_hdr *mh;
06326    struct ast_iax2_video_hdr *vh;
06327    struct {
06328       struct iax_frame fr2;
06329       unsigned char buffer[4096];
06330    } frb;
06331    struct iax_frame *fr;
06332    int res;
06333    int sendmini=0;
06334    unsigned int lastsent;
06335    unsigned int fts;
06336 
06337    frb.fr2.afdatalen = sizeof(frb.buffer);
06338 
06339    if (!pvt) {
06340       ast_log(LOG_WARNING, "No private structure for packet?\n");
06341       return -1;
06342    }
06343    
06344    lastsent = pvt->lastsent;
06345 
06346    /* Calculate actual timestamp */
06347    fts = calc_timestamp(pvt, ts, f);
06348 
06349    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
06350     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
06351     * increment the "predicted timestamps" for voice, if we're predicting */
06352    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06353       return 0;
06354 #if 0
06355    ast_log(LOG_NOTICE, 
06356       "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06357       *("=!" + (f->frametype == AST_FRAME_VOICE)),
06358       IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06359       pvt->keyrotateid != -1 ? "" : "no "
06360    );
06361 #endif
06362    if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06363       iax2_key_rotate(pvt);
06364    }
06365 
06366    if ((ast_test_flag64(pvt, IAX_TRUNK) || 
06367          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06368          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06369       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
06370        (f->frametype == AST_FRAME_VOICE) 
06371       /* is a voice frame */ &&
06372       (f->subclass.codec == pvt->svoiceformat) 
06373       /* is the same type */ ) {
06374          /* Force immediate rather than delayed transmission */
06375          now = 1;
06376          /* Mark that mini-style frame is appropriate */
06377          sendmini = 1;
06378    }
06379    if ( f->frametype == AST_FRAME_VIDEO ) {
06380       /*
06381        * If the lower 15 bits of the timestamp roll over, or if
06382        * the video format changed then send a full frame.
06383        * Otherwise send a mini video frame
06384        */
06385       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06386           ((f->subclass.codec & ~0x1LL) == pvt->svideoformat)
06387          ) {
06388          now = 1;
06389          sendmini = 1;
06390       } else {
06391          now = 0;
06392          sendmini = 0;
06393       }
06394       pvt->lastvsent = fts;
06395    }
06396    if (f->frametype == AST_FRAME_IAX) {
06397       /* 0x8000 marks this message as TX:, this bit will be stripped later */
06398       pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX;
06399       if (!pvt->first_iax_message) {
06400          pvt->first_iax_message = pvt->last_iax_message;
06401       }
06402    }
06403    /* Allocate an iax_frame */
06404    if (now) {
06405       fr = &frb.fr2;
06406    } else
06407       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));
06408    if (!fr) {
06409       ast_log(LOG_WARNING, "Out of memory\n");
06410       return -1;
06411    }
06412    /* Copy our prospective frame into our immediate or retransmitted wrapper */
06413    iax_frame_wrap(fr, f);
06414 
06415    fr->ts = fts;
06416    fr->callno = pvt->callno;
06417    fr->transfer = transfer;
06418    fr->final = final;
06419    fr->encmethods = 0;
06420    if (!sendmini) {
06421       /* We need a full frame */
06422       if (seqno > -1)
06423          fr->oseqno = seqno;
06424       else
06425          fr->oseqno = pvt->oseqno++;
06426       fr->iseqno = pvt->iseqno;
06427       fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06428       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06429       fh->ts = htonl(fr->ts);
06430       fh->oseqno = fr->oseqno;
06431       if (transfer) {
06432          fh->iseqno = 0;
06433       } else
06434          fh->iseqno = fr->iseqno;
06435       /* Keep track of the last thing we've acknowledged */
06436       if (!transfer)
06437          pvt->aseqno = fr->iseqno;
06438       fh->type = fr->af.frametype & 0xFF;
06439 
06440       if (fr->af.frametype == AST_FRAME_VIDEO) {
06441          fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6);
06442       } else if (fr->af.frametype == AST_FRAME_VOICE) {
06443          fh->csub = compress_subclass(fr->af.subclass.codec);
06444       } else {
06445          fh->csub = compress_subclass(fr->af.subclass.integer);
06446       }
06447 
06448       if (transfer) {
06449          fr->dcallno = pvt->transfercallno;
06450       } else
06451          fr->dcallno = pvt->peercallno;
06452       fh->dcallno = htons(fr->dcallno);
06453       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06454       fr->data = fh;
06455       fr->retries = 0;
06456       /* Retry after 2x the ping time has passed */
06457       fr->retrytime = pvt->pingtime * 2;
06458       if (fr->retrytime < MIN_RETRY_TIME)
06459          fr->retrytime = MIN_RETRY_TIME;
06460       if (fr->retrytime > MAX_RETRY_TIME)
06461          fr->retrytime = MAX_RETRY_TIME;
06462       /* Acks' don't get retried */
06463       if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
06464          fr->retries = -1;
06465       else if (f->frametype == AST_FRAME_VOICE)
06466          pvt->svoiceformat = f->subclass.codec;
06467       else if (f->frametype == AST_FRAME_VIDEO)
06468          pvt->svideoformat = f->subclass.codec & ~0x1LL;
06469       if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06470          if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06471             if (fr->transfer)
06472                iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06473             else
06474                iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06475             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06476             fr->encmethods = pvt->encmethods;
06477             fr->ecx = pvt->ecx;
06478             fr->mydcx = pvt->mydcx;
06479             memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06480          } else
06481             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06482       }
06483 
06484       if (now) {
06485          res = send_packet(fr);
06486       } else
06487          res = iax2_transmit(fr);
06488    } else {
06489       if (ast_test_flag64(pvt, IAX_TRUNK)) {
06490          iax2_trunk_queue(pvt, fr);
06491          res = 0;
06492       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06493          /* Video frame have no sequence number */
06494          fr->oseqno = -1;
06495          fr->iseqno = -1;
06496          vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06497          vh->zeros = 0;
06498          vh->callno = htons(0x8000 | fr->callno);
06499          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0));
06500          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06501          fr->data = vh;
06502          fr->retries = -1;
06503          res = send_packet(fr);
06504       } else {
06505          /* Mini-frames have no sequence number */
06506          fr->oseqno = -1;
06507          fr->iseqno = -1;
06508          /* Mini frame will do */
06509          mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06510          mh->callno = htons(fr->callno);
06511          mh->ts = htons(fr->ts & 0xFFFF);
06512          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06513          fr->data = mh;
06514          fr->retries = -1;
06515          if (pvt->transferring == TRANSFER_MEDIAPASS)
06516             fr->transfer = 1;
06517          if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06518             if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06519                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06520             } else
06521                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06522          }
06523          res = send_packet(fr);
06524       }
06525    }
06526    return res;
06527 }

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

Definition at line 4284 of file chan_iax2.c.

References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

04285 {
04286    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04287 }

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

Definition at line 4279 of file chan_iax2.c.

References AST_FRAME_IMAGE, ast_frame::data, ast_frame::datalen, ast_frame_subclass::integer, ast_frame::ptr, PTR_TO_CALLNO, send_command_locked(), ast_frame::subclass, and ast_channel::tech_pvt.

04280 {
04281    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1);
04282 }

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

Definition at line 4272 of file chan_iax2.c.

References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

04273 {
04274    
04275    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04276       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04277 }

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

Definition at line 5259 of file chan_iax2.c.

References ast_clear_flag64, AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_free, ast_malloc, ast_mutex_lock, ast_mutex_unlock, AST_OPTION_FLAG_REQUEST, AST_OPTION_FORMAT_READ, AST_OPTION_FORMAT_WRITE, AST_OPTION_MAKE_COMPATIBLE, AST_OPTION_OPRMODE, AST_OPTION_RXGAIN, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_TXGAIN, ast_set_flag64, errno, IAX_FORCE_ENCRYPT, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().

05260 {
05261    struct ast_option_header *h;
05262    int res;
05263 
05264    switch (option) {
05265    case AST_OPTION_TXGAIN:
05266    case AST_OPTION_RXGAIN:
05267       /* these two cannot be sent, because they require a result */
05268       errno = ENOSYS;
05269       return -1;
05270    case AST_OPTION_FORMAT_READ:
05271    case AST_OPTION_FORMAT_WRITE:
05272    case AST_OPTION_MAKE_COMPATIBLE:
05273       return -1;
05274    case AST_OPTION_OPRMODE:
05275       errno = EINVAL;
05276       return -1;
05277    case AST_OPTION_SECURE_SIGNALING:
05278    case AST_OPTION_SECURE_MEDIA:
05279    {
05280       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05281       ast_mutex_lock(&iaxsl[callno]);
05282       if ((*(int *) data)) {
05283          ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05284       } else {
05285          ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05286       }
05287       ast_mutex_unlock(&iaxsl[callno]);
05288       return 0;
05289    }
05290    default:
05291    {
05292       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05293       struct chan_iax2_pvt *pvt;
05294 
05295       ast_mutex_lock(&iaxsl[callno]);
05296       pvt = iaxs[callno];
05297 
05298       if (wait_for_peercallno(pvt)) {
05299          ast_mutex_unlock(&iaxsl[callno]);
05300          return -1;
05301       }
05302 
05303       ast_mutex_unlock(&iaxsl[callno]);
05304 
05305       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05306          return -1;
05307       }
05308 
05309       h->flag = AST_OPTION_FLAG_REQUEST;
05310       h->option = htons(option);
05311       memcpy(h->data, data, datalen);
05312       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05313                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
05314                  datalen + sizeof(*h), -1);
05315       ast_free(h);
05316       return res;
05317    }
05318    }
05319 }

static int iax2_start_transfer ( unsigned short  callno0,
unsigned short  callno1,
int  mediaonly 
) [static]

Definition at line 5377 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_random(), ast_set_flag64, IAX_CALLENCRYPTED, IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, IAX_NOTRANSFER, iaxs, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.

05378 {
05379    int res;
05380    struct iax_ie_data ied0;
05381    struct iax_ie_data ied1;
05382    unsigned int transferid = (unsigned int)ast_random();
05383 
05384    if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05385       ast_debug(1, "transfers are not supported for encrypted calls at this time");
05386       ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05387       ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05388       return 0;
05389    }
05390 
05391    memset(&ied0, 0, sizeof(ied0));
05392    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05393    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05394    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05395 
05396    memset(&ied1, 0, sizeof(ied1));
05397    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05398    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05399    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05400    
05401    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05402    if (res)
05403       return -1;
05404    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05405    if (res)
05406       return -1;
05407    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05408    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05409    return 0;
05410 }

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

Definition at line 5636 of file chan_iax2.c.

References AST_CONTROL_TRANSFER, ast_copy_string(), ast_debug, AST_FRAME_IAX, ast_queue_control_data(), AST_TRANSFER_SUCCESS, chan_iax2_pvt::callno, context, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, ast_channel::name, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

05637 {
05638    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05639    struct iax_ie_data ied = { "", };
05640    char tmp[256], *context;
05641    enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05642    ast_copy_string(tmp, dest, sizeof(tmp));
05643    context = strchr(tmp, '@');
05644    if (context) {
05645       *context = '\0';
05646       context++;
05647    }
05648    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05649    if (context)
05650       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05651    ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05652    ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05653    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05654 }

static int iax2_transmit ( struct iax_frame fr  )  [static]

Definition at line 4255 of file chan_iax2.c.

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

Referenced by iax2_send().

04256 {
04257    fr->sentyet = 0;
04258 
04259    return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04260 }

static int iax2_trunk_expired ( struct iax2_trunk_peer tpeer,
struct timeval *  now 
) [inline, static]

Definition at line 9101 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

09102 {
09103    /* Drop when trunk is about 5 seconds idle */
09104    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
09105       return 1;
09106    return 0;
09107 }

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

Definition at line 6056 of file chan_iax2.c.

References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_unlock, ast_realloc, ast_test_flag64, ast_tvnow(), ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, DEFAULT_TRUNKDATA, f, find_tpeer(), 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, send_trunk(), chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.

Referenced by iax2_send().

06057 {
06058    struct ast_frame *f;
06059    struct iax2_trunk_peer *tpeer;
06060    void *tmp, *ptr;
06061    struct timeval now;
06062    int res; 
06063    struct ast_iax2_meta_trunk_entry *met;
06064    struct ast_iax2_meta_trunk_mini *mtm;
06065 
06066    f = &fr->af;
06067    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06068    if (tpeer) {
06069       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06070          /* Need to reallocate space */
06071          if (tpeer->trunkdataalloc < trunkmaxsize) {
06072             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06073                ast_mutex_unlock(&tpeer->lock);
06074                return -1;
06075             }
06076             
06077             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06078             tpeer->trunkdata = tmp;
06079             ast_debug(1, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
06080          } else {
06081             ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06082             ast_mutex_unlock(&tpeer->lock);
06083             return -1;
06084          }
06085       }
06086 
06087       /* Append to meta frame */
06088       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06089       if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06090          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06091          mtm->len = htons(f->datalen);
06092          mtm->mini.callno = htons(pvt->callno);
06093          mtm->mini.ts = htons(0xffff & fr->ts);
06094          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06095          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06096       } else {
06097          met = (struct ast_iax2_meta_trunk_entry *)ptr;
06098          /* Store call number and length in meta header */
06099          met->callno = htons(pvt->callno);
06100          met->len = htons(f->datalen);
06101          /* Advance pointers/decrease length past trunk entry header */
06102          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06103          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06104       }
06105       /* Copy actual trunk data */
06106       memcpy(ptr, f->data.ptr, f->datalen);
06107       tpeer->trunkdatalen += f->datalen;
06108 
06109       tpeer->calls++;
06110 
06111       /* track the largest mtu we actually have sent */
06112       if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 
06113          trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 
06114 
06115       /* if we have enough for a full MTU, ship it now without waiting */
06116       if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06117          now = ast_tvnow();
06118          res = send_trunk(tpeer, &now); 
06119          trunk_untimed ++; 
06120       }
06121 
06122       ast_mutex_unlock(&tpeer->lock);
06123    }
06124    return 0;
06125 }

static int iax2_vnak ( int  callno  )  [static]

Definition at line 9022 of file chan_iax2.c.

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

Referenced by socket_process(), and socket_process_meta().

09023 {
09024    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09025 }

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

Definition at line 7401 of file chan_iax2.c.

References ast_debug, AST_FRAME_NULL, AST_FRAME_VOICE, ast_mutex_lock, ast_mutex_unlock, ast_test_flag, ast_test_flag64, errno, f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, PTR_TO_CALLNO, state, and ast_channel::tech_pvt.

07402 {
07403    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07404    int res = -1;
07405    ast_mutex_lock(&iaxsl[callno]);
07406    if (iaxs[callno]) {
07407    /* If there's an outstanding error, return failure now */
07408       if (!iaxs[callno]->error) {
07409          if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07410             res = 0;
07411             /* Don't waste bandwidth sending null frames */
07412          else if (f->frametype == AST_FRAME_NULL)
07413             res = 0;
07414          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07415             res = 0;
07416          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07417             res = 0;
07418          else
07419          /* Simple, just queue for transmission */
07420             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07421       } else {
07422          ast_debug(1, "Write error: %s\n", strerror(errno));
07423       }
07424    }
07425    /* If it's already gone, just return */
07426    ast_mutex_unlock(&iaxsl[callno]);
07427    return res;
07428 }

static int iax_check_version ( char *  dev  )  [static]

Definition at line 3141 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_iax2_firmware_header::devname, iax_firmware::fwh, iax2_trunk_peer::list, and ast_iax2_firmware_header::version.

Referenced by update_registry().

03142 {
03143    int res = 0;
03144    struct iax_firmware *cur = NULL;
03145 
03146    if (ast_strlen_zero(dev))
03147       return 0;
03148 
03149    AST_LIST_LOCK(&firmwares);
03150    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03151       if (!strcmp(dev, (char *)cur->fwh->devname)) {
03152          res = ntohs(cur->fwh->version);
03153          break;
03154       }
03155    }
03156    AST_LIST_UNLOCK(&firmwares);
03157 
03158    return res;
03159 }

static void iax_debug_output ( const char *  data  )  [static]

Definition at line 1115 of file chan_iax2.c.

References ast_verbose.

Referenced by load_module().

01116 {
01117    if (iaxdebug)
01118       ast_verbose("%s", data);
01119 }

static void iax_error_output ( const char *  data  )  [static]

Definition at line 1121 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

01122 {
01123    ast_log(LOG_WARNING, "%s", data);
01124 }

static int iax_firmware_append ( struct iax_ie_data ied,
const unsigned char *  dev,
unsigned int  desc 
) [static]

Definition at line 3161 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, iax_firmware::fwh, iax_ie_append(), iax_ie_append_int(), iax_ie_append_raw(), IAX_IE_FWBLOCKDATA, IAX_IE_FWBLOCKDESC, and iax2_trunk_peer::list.

Referenced by socket_process().

03162 {
03163    int res = -1;
03164    unsigned int bs = desc & 0xff;
03165    unsigned int start = (desc >> 8) & 0xffffff;
03166    unsigned int bytes;
03167    struct iax_firmware *cur;
03168 
03169    if (ast_strlen_zero((char *)dev) || !bs)
03170       return -1;
03171 
03172    start *= bs;
03173    
03174    AST_LIST_LOCK(&firmwares);
03175    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03176       if (strcmp((char *)dev, (char *)cur->fwh->devname))
03177          continue;
03178       iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03179       if (start < ntohl(cur->fwh->datalen)) {
03180          bytes = ntohl(cur->fwh->datalen) - start;
03181          if (bytes > bs)
03182             bytes = bs;
03183          iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03184       } else {
03185          bytes = 0;
03186          iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03187       }
03188       if (bytes == bs)
03189          res = 0;
03190       else
03191          res = 1;
03192       break;
03193    }
03194    AST_LIST_UNLOCK(&firmwares);
03195 
03196    return res;
03197 }

static void iax_outputframe ( struct iax_frame f,
struct ast_iax2_full_hdr fhi,
int  rx,
struct sockaddr_in *  sin,
int  datalen 
) [static]

Definition at line 1098 of file chan_iax2.c.

References debugaddr, f, and iax_showframe().

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

01099 {
01100    if (iaxdebug ||
01101        (sin && debugaddr.sin_addr.s_addr && 
01102         (!ntohs(debugaddr.sin_port) ||
01103          debugaddr.sin_port == sin->sin_port) &&
01104         debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
01105       if (iaxdebug) {
01106          iax_showframe(f, fhi, rx, sin, datalen);
01107       } else {
01108          iaxdebug = 1;
01109          iax_showframe(f, fhi, rx, sin, datalen);
01110          iaxdebug = 0;
01111       }
01112    }
01113 }

static int iax_park ( struct ast_channel chan1,
struct ast_channel chan2,
const char *  parkexten 
) [static]

Definition at line 9264 of file chan_iax2.c.

References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, ast_channel_alloc, ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_channel::context, ast_channel::exten, iax_park_thread(), ast_channel::linkedid, LOG_WARNING, ast_channel::name, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.

Referenced by socket_process().

09265 {
09266    struct iax_dual *d;
09267    struct ast_channel *chan1m, *chan2m;
09268    pthread_t th;
09269    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09270    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09271    if (chan2m && chan1m) {
09272       /* Make formats okay */
09273       chan1m->readformat = chan1->readformat;
09274       chan1m->writeformat = chan1->writeformat;
09275       ast_channel_masquerade(chan1m, chan1);
09276       /* Setup the extensions and such */
09277       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09278       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09279       chan1m->priority = chan1->priority;
09280       
09281       /* We make a clone of the peer channel too, so we can play
09282          back the announcement */
09283       /* Make formats okay */
09284       chan2m->readformat = chan2->readformat;
09285       chan2m->writeformat = chan2->writeformat;
09286       ast_channel_masquerade(chan2m, chan2);
09287       /* Setup the extensions and such */
09288       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09289       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09290       chan2m->priority = chan2->priority;
09291       if (ast_do_masquerade(chan2m)) {
09292          ast_log(LOG_WARNING, "Masquerade failed :(\n");
09293          ast_hangup(chan2m);
09294          return -1;
09295       }
09296    } else {
09297       if (chan1m)
09298          ast_hangup(chan1m);
09299       if (chan2m)
09300          ast_hangup(chan2m);
09301       return -1;
09302    }
09303    if ((d = ast_calloc(1, sizeof(*d)))) {
09304       d->chan1 = chan1m;
09305       d->chan2 = chan2m;
09306       d->parkexten = parkexten;
09307       if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
09308          return 0;
09309       }
09310       ast_free(d);
09311    }
09312    return -1;
09313 }

static void* iax_park_thread ( void *  stuff  )  [static]

Definition at line 9244 of file chan_iax2.c.

References ast_free, ast_frfree, ast_hangup(), ast_log(), ast_park_call(), ast_read(), iax_dual::chan1, iax_dual::chan2, ext, f, LOG_NOTICE, and iax_dual::parkexten.

Referenced by iax_park().

09245 {
09246    struct ast_channel *chan1, *chan2;
09247    struct iax_dual *d;
09248    struct ast_frame *f;
09249    int ext;
09250    int res;
09251    d = stuff;
09252    chan1 = d->chan1;
09253    chan2 = d->chan2;
09254    ast_free(d);
09255    f = ast_read(chan1);
09256    if (f)
09257       ast_frfree(f);
09258    res = ast_park_call(chan1, chan2, 0, d->parkexten, &ext);
09259    ast_hangup(chan2);
09260    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09261    return NULL;
09262 }

static struct iax_frame* iaxfrdup2 ( struct iax_frame fr  )  [static]

Definition at line 1955 of file chan_iax2.c.

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

Referenced by socket_process(), and socket_process_meta().

01956 {
01957    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01958    if (new) {
01959       size_t afdatalen = new->afdatalen;
01960       memcpy(new, fr, sizeof(*new));
01961       iax_frame_wrap(new, &fr->af);
01962       new->afdatalen = afdatalen;
01963       new->data = NULL;
01964       new->datalen = 0;
01965       new->direction = DIRECTION_INGRESS;
01966       new->retrans = -1;
01967    }
01968    return new;
01969 }

static void insert_idle_thread ( struct iax2_thread thread  )  [static]

Definition at line 1380 of file chan_iax2.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_THREAD_TYPE_DYNAMIC, iax2_trunk_peer::list, and thread.

Referenced by iax2_process_thread().

01381 {
01382    if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01383       AST_LIST_LOCK(&dynamic_list);
01384       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01385       AST_LIST_UNLOCK(&dynamic_list);
01386    } else {
01387       AST_LIST_LOCK(&idle_list);
01388       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01389       AST_LIST_UNLOCK(&idle_list);
01390    }
01391 
01392    return;
01393 }

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

Definition at line 1150 of file chan_iax2.c.

References args, and ast_verbose.

Referenced by handle_cli_iax2_set_debug_jb().

01151 {
01152    va_list args;
01153    char buf[1024];
01154 
01155    va_start(args, fmt);
01156    vsnprintf(buf, sizeof(buf), fmt, args);
01157    va_end(args);
01158 
01159    ast_verbose("%s", buf);
01160 }

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

Definition at line 1126 of file chan_iax2.c.

References args, ast_log(), and LOG_ERROR.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

01127 {
01128    va_list args;
01129    char buf[1024];
01130 
01131    va_start(args, fmt);
01132    vsnprintf(buf, sizeof(buf), fmt, args);
01133    va_end(args);
01134 
01135    ast_log(LOG_ERROR, "%s", buf);
01136 }

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

Definition at line 1138 of file chan_iax2.c.

References args, ast_log(), and LOG_WARNING.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

01139 {
01140    va_list args;
01141    char buf[1024];
01142 
01143    va_start(args, fmt);
01144    vsnprintf(buf, sizeof(buf), fmt, args);
01145    va_end(args);
01146 
01147    ast_log(LOG_WARNING, "%s", buf);
01148 }

static int load_module ( void   )  [static]

Load IAX2 module, load configuraiton ---.

Definition at line 14575 of file chan_iax2.c.

References __unload_module(), ao2_callback, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, 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_thread_create(), ast_sched_thread_destroy(), AST_TEST_REGISTER, ast_timer_close(), ast_timer_open(), ast_timer_set_rate(), ast_verb, cli_iax2, config, iax2_registry::entry, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, iax2_data_providers, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), 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_event_subscribe(), outsock, papp, peer_set_sock_cb(), peers, reload_firmware(), RQ_CHAR, RQ_UINTEGER2, sched, SENTINEL, set_config(), start_network_thread(), and timer.

14576 {
14577    static const char config[] = "iax.conf";
14578    int x = 0;
14579    struct iax2_registry *reg = NULL;
14580 
14581    if (load_objects()) {
14582       return AST_MODULE_LOAD_FAILURE;
14583    }
14584 
14585    memset(iaxs, 0, sizeof(iaxs));
14586 
14587    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14588       ast_mutex_init(&iaxsl[x]);
14589    }
14590 
14591    if (!(sched = ast_sched_thread_create())) {
14592       ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14593       return AST_MODULE_LOAD_FAILURE;
14594    }
14595 
14596    if (!(io = io_context_create())) {
14597       ast_log(LOG_ERROR, "Failed to create I/O context\n");
14598       sched = ast_sched_thread_destroy(sched);
14599       return AST_MODULE_LOAD_FAILURE;
14600    }
14601 
14602    if (!(netsock = ast_netsock_list_alloc())) {
14603       ast_log(LOG_ERROR, "Failed to create netsock list\n");
14604       io_context_destroy(io);
14605       sched = ast_sched_thread_destroy(sched);
14606       return AST_MODULE_LOAD_FAILURE;
14607    }
14608    ast_netsock_init(netsock);
14609    
14610    outsock = ast_netsock_list_alloc();
14611    if (!outsock) {
14612       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14613       io_context_destroy(io);
14614       sched = ast_sched_thread_destroy(sched);
14615       return AST_MODULE_LOAD_FAILURE;
14616    }
14617    ast_netsock_init(outsock);
14618 
14619    randomcalltokendata = ast_random();
14620 
14621    iax_set_output(iax_debug_output);
14622    iax_set_error(iax_error_output);
14623    jb_setoutput(jb_error_output, jb_warning_output, NULL);
14624    
14625    if ((timer = ast_timer_open())) {
14626       ast_timer_set_rate(timer, trunkfreq);
14627    }
14628 
14629    if (set_config(config, 0) == -1) {
14630       if (timer) {
14631          ast_timer_close(timer);
14632       }
14633       return AST_MODULE_LOAD_DECLINE;
14634    }
14635 
14636 #ifdef TEST_FRAMEWORK
14637    AST_TEST_REGISTER(test_iax2_peers_get);
14638    AST_TEST_REGISTER(test_iax2_users_get);
14639 #endif
14640 
14641    /* Register AstData providers */
14642    ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
14643    ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14644 
14645    ast_register_application_xml(papp, iax2_prov_app);
14646 
14647    ast_custom_function_register(&iaxpeer_function);
14648    ast_custom_function_register(&iaxvar_function);
14649 
14650    ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
14651    ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
14652    ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
14653    ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
14654 
14655    if (ast_channel_register(&iax2_tech)) {
14656       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
14657       __unload_module();
14658       return AST_MODULE_LOAD_FAILURE;
14659    }
14660 
14661    if (ast_register_switch(&iax2_switch)) {
14662       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
14663    }
14664 
14665    if (start_network_thread()) {
14666       ast_log(LOG_ERROR, "Unable to start network thread\n");
14667       __unload_module();
14668       return AST_MODULE_LOAD_FAILURE;
14669    } else {
14670       ast_verb(2, "IAX Ready and Listening\n");
14671    }
14672 
14673    AST_LIST_LOCK(&registrations);
14674    AST_LIST_TRAVERSE(&registrations, reg, entry)
14675       iax2_do_register(reg);
14676    AST_LIST_UNLOCK(&registrations); 
14677    
14678    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
14679    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
14680 
14681 
14682    reload_firmware(0);
14683    iax_provision_reload(0);
14684 
14685    ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
14686 
14687    network_change_event_subscribe();
14688 
14689    return AST_MODULE_LOAD_SUCCESS;
14690 }

static int load_objects ( void   )  [static]

Definition at line 14334 of file chan_iax2.c.

References addr_range_cmp_cb(), addr_range_hash_cb(), ao2_container_alloc, ao2_ref, AST_MODULE_LOAD_FAILURE, ast_taskprocessor_get(), callno_limits, calltoken_ignores, create_callno_pools(), iax_peercallno_pvts, iax_transfercallno_pvts, MAX_PEER_BUCKETS, MAX_USER_BUCKETS, peer_cmp_cb(), peer_hash_cb(), peercnt_cmp_cb(), peercnt_hash_cb(), peercnts, peers, pvt_cmp_cb(), pvt_hash_cb(), TPS_REF_DEFAULT, transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), user_hash_cb(), and users.

Referenced by load_module().

14335 {
14336    peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14337    peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14338 
14339    if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14340       goto container_fail;
14341    } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14342       goto container_fail;
14343    } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14344       goto container_fail;
14345    } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14346       goto container_fail;
14347    } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14348       goto container_fail;
14349    } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14350       goto container_fail;
14351    } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14352       goto container_fail;
14353    } else if (create_callno_pools()) {
14354       goto container_fail;
14355    } else if  (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14356       goto container_fail;
14357    }
14358 
14359    return 0;
14360 
14361 container_fail:
14362    if (peers) {
14363       ao2_ref(peers, -1);
14364    }
14365    if (users) {
14366       ao2_ref(users, -1);
14367    }
14368    if (iax_peercallno_pvts) {
14369       ao2_ref(iax_peercallno_pvts, -1);
14370    }
14371    if (iax_transfercallno_pvts) {
14372       ao2_ref(iax_transfercallno_pvts, -1);
14373    }
14374    if (peercnts) {
14375       ao2_ref(peercnts, -1);
14376    }
14377    if (callno_limits) {
14378       ao2_ref(callno_limits, -1);
14379    }
14380    if (calltoken_ignores) {
14381       ao2_ref(calltoken_ignores, -1);
14382    }
14383    if (callno_pool) {
14384       ao2_ref(callno_pool, -1);
14385    }
14386    if (callno_pool_trunk) {
14387       ao2_ref(callno_pool_trunk, -1);
14388    }
14389    return AST_MODULE_LOAD_FAILURE;
14390 }

static void lock_both ( unsigned short  callno0,
unsigned short  callno1 
) [static]

Definition at line 5412 of file chan_iax2.c.

References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.

Referenced by iax2_bridge().

05413 {
05414    ast_mutex_lock(&iaxsl[callno0]);
05415    while (ast_mutex_trylock(&iaxsl[callno1])) {
05416       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05417    }
05418 }

static void log_jitterstats ( unsigned short  callno  )  [static]

Definition at line 9385 of file chan_iax2.c.

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

Referenced by socket_process().

09386 {
09387    int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09388    jb_info jbinfo;
09389 
09390    ast_mutex_lock(&iaxsl[callno]);
09391    if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09392       if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09393          jb_getinfo(iaxs[callno]->jb, &jbinfo);
09394          localjitter = jbinfo.jitter;
09395          localdelay = jbinfo.current - jbinfo.min;
09396          locallost = jbinfo.frames_lost;
09397          locallosspct = jbinfo.losspct/1000;
09398          localdropped = jbinfo.frames_dropped;
09399          localooo = jbinfo.frames_ooo;
09400          localpackets = jbinfo.frames_in;
09401       }
09402       ast_debug(3, "JB STATS:%s ping=%d 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",
09403          iaxs[callno]->owner->name,
09404          iaxs[callno]->pingtime,
09405          localjitter,
09406          localdelay,
09407          locallost,
09408          locallosspct,
09409          localdropped,
09410          localooo,
09411          localpackets,
09412          iaxs[callno]->remote_rr.jitter,
09413          iaxs[callno]->remote_rr.delay,
09414          iaxs[callno]->remote_rr.losscnt,
09415          iaxs[callno]->remote_rr.losspct/1000,
09416          iaxs[callno]->remote_rr.dropped,
09417          iaxs[callno]->remote_rr.ooo,
09418          iaxs[callno]->remote_rr.packets);
09419       manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %d\r\nLocalJitter: %d\r\nLocalJBDelay: %d\r\nLocalTotalLost: %d\r\nLocalLossPercent: %d\r\nLocalDropped: %d\r\nLocalooo: %d\r\nLocalReceived: %d\r\nRemoteJitter: %d\r\nRemoteJBDelay: %d\r\nRemoteTotalLost: %d\r\nRemoteLossPercent: %d\r\nRemoteDropped: %d\r\nRemoteooo: %d\r\nRemoteReceived: %d\r\n",
09420          iaxs[callno]->owner->name,
09421          iaxs[callno]->pingtime,
09422          localjitter,
09423          localdelay,
09424          locallost,
09425          locallosspct,
09426          localdropped,
09427          localooo,
09428          localpackets,
09429          iaxs[callno]->remote_rr.jitter,
09430          iaxs[callno]->remote_rr.delay,
09431          iaxs[callno]->remote_rr.losscnt,
09432          iaxs[callno]->remote_rr.losspct/1000,
09433          iaxs[callno]->remote_rr.dropped,
09434          iaxs[callno]->remote_rr.ooo,
09435          iaxs[callno]->remote_rr.packets);
09436    }
09437    ast_mutex_unlock(&iaxsl[callno]);
09438 }

static int make_trunk ( unsigned short  callno,
int  locked 
) [static]

Definition at line 2035 of file chan_iax2.c.

References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, chan_iax2_pvt::callno, callno_entry::callno, chan_iax2_pvt::callno_entry, get_unused_callno(), iax2_sched_add(), iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_WARNING, MIN_REUSE_TIME, chan_iax2_pvt::pingid, replace_callno(), sched, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), update_max_trunk(), and callno_entry::validated.

Referenced by iax2_request(), and socket_process().

02036 {
02037    int x;
02038    int res= 0;
02039    struct callno_entry *callno_entry;
02040    if (iaxs[callno]->oseqno) {
02041       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
02042       return -1;
02043    }
02044    if (callno & TRUNK_CALL_START) {
02045       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
02046       return -1;
02047    }
02048 
02049    if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
02050       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
02051       return -1;
02052    }
02053 
02054    x = callno_entry->callno;
02055    ast_mutex_lock(&iaxsl[x]);
02056 
02057    /*!
02058     * \note We delete these before switching the slot, because if
02059     * they fire in the meantime, they will generate a warning.
02060     */
02061    ast_sched_thread_del(sched, iaxs[callno]->pingid);
02062    ast_sched_thread_del(sched, iaxs[callno]->lagid);
02063    iaxs[callno]->lagid = iaxs[callno]->pingid = -1;
02064    iaxs[x] = iaxs[callno];
02065    iaxs[x]->callno = x;
02066 
02067    /* since we copied over the pvt from a different callno, make sure the old entry is replaced
02068     * before assigning the new one */
02069    if (iaxs[x]->callno_entry) {
02070       iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
02071    }
02072    iaxs[x]->callno_entry = callno_entry;
02073 
02074    iaxs[callno] = NULL;
02075    /* Update the two timers that should have been started */
02076    iaxs[x]->pingid = iax2_sched_add(sched, 
02077       ping_time * 1000, send_ping, (void *)(long)x);
02078    iaxs[x]->lagid = iax2_sched_add(sched, 
02079       lagrq_time * 1000, send_lagrq, (void *)(long)x);
02080 
02081    if (locked)
02082       ast_mutex_unlock(&iaxsl[callno]);
02083    res = x;
02084    if (!locked)
02085       ast_mutex_unlock(&iaxsl[x]);
02086 
02087    ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
02088    /* We move this call from a non-trunked to a trunked call */
02089    update_max_trunk();
02090    update_max_nontrunk();
02091    return res;
02092 }

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

Definition at line 6902 of file chan_iax2.c.

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

Referenced by load_module().

06903 {
06904    ast_cli_netstats(s, -1, 0);
06905    astman_append(s, "\r\n");
06906    return RESULT_SUCCESS;
06907 }

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

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, astman_append(), astman_get_header(), iax2_peer::encmethods, encmethods_to_str(), IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, peer_status(), peer_unref(), peers, RESULT_SUCCESS, status, and iax2_peer::username.

Referenced by load_module().

06966 {
06967    struct iax2_peer *peer = NULL;
06968    int peer_count = 0;
06969    char nm[20];
06970    char status[20];
06971    const char *id = astman_get_header(m,"ActionID");
06972    char idtext[256] = "";
06973    struct ast_str *encmethods = ast_str_alloca(256);
06974    struct ao2_iterator i;
06975 
06976    if (!ast_strlen_zero(id))
06977       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06978 
06979    astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06980 
06981 
06982    i = ao2_iterator_init(peers, 0);
06983    for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
06984       encmethods_to_str(peer->encmethods, encmethods);
06985       astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06986       if (!ast_strlen_zero(peer->username)) {
06987          astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
06988       } else {
06989          astman_append(s, "ObjectName: %s\r\n", peer->name);
06990       }
06991       astman_append(s, "ChanObjectType: peer\r\n");
06992       astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
06993       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06994       astman_append(s, "Mask: %s\r\n", nm);
06995       astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
06996       astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
06997       astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
06998       astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
06999       peer_status(peer, status, sizeof(status));
07000       astman_append(s, "Status: %s\r\n\r\n", status);
07001       peer_count++;
07002    }
07003    ao2_iterator_destroy(&i);
07004 
07005    astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07006    return RESULT_SUCCESS;
07007 }

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

callback to display iax peers in manager

Definition at line 6941 of file chan_iax2.c.

References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), and total.

Referenced by load_module().

06942 {
06943    static const char * const a[] = { "iax2", "show", "peers" };
06944    const char *id = astman_get_header(m,"ActionID");
06945    char idtext[256] = "";
06946    int total = 0;
06947 
06948    if (!ast_strlen_zero(id))
06949       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06950 
06951    astman_send_listack(s, m, "Peer status list will follow", "start");
06952         /* List the peers in separate manager events */
06953    __iax2_show_peers(-1, &total, s, 3, a);
06954         /* Send final confirmation */
06955         astman_append(s,
06956         "Event: PeerlistComplete\r\n"
06957         "EventList: Complete\r\n"
06958         "ListItems: %d\r\n"
06959         "%s"
06960         "\r\n", total, idtext);
06961         return 0;
06962 }

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

Definition at line 7073 of file chan_iax2.c.

References iax2_registry::addr, ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_stringify(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), iax2_registry::dnsmgr, iax2_registry::entry, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), total, iax2_registry::us, and iax2_registry::username.

Referenced by load_module().

07074 {
07075    const char *id = astman_get_header(m, "ActionID");
07076    struct iax2_registry *reg = NULL;
07077    char idtext[256] = "";
07078    char host[80] = "";
07079    char perceived[80] = "";
07080    int total = 0;
07081 
07082    if (!ast_strlen_zero(id))
07083       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07084 
07085    astman_send_listack(s, m, "Registrations will follow", "start");
07086 
07087    AST_LIST_LOCK(&registrations);
07088    AST_LIST_TRAVERSE(&registrations, reg, entry) {
07089       snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
07090       
07091       if (reg->us.sin_addr.s_addr) {
07092          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07093       } else {
07094          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07095       }
07096       
07097       astman_append(s,
07098          "Event: RegistryEntry\r\n"
07099          "%s"
07100          "Host: %s\r\n"
07101          "DNSmanager: %s\r\n"
07102          "Username: %s\r\n"
07103          "Perceived: %s\r\n"
07104          "Refresh: %d\r\n"
07105          "State: %s\r\n"
07106          "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 
07107          reg->refresh, regstate2str(reg->regstate));
07108 
07109       total++;
07110    }
07111    AST_LIST_UNLOCK(&registrations);
07112 
07113    astman_append(s,
07114       "Event: RegistrationsComplete\r\n"
07115       "EventList: Complete\r\n"
07116       "ListItems: %d\r\n"
07117       "%s"
07118       "\r\n", total, idtext);
07119    
07120    return 0;
07121 }

static int match ( struct sockaddr_in *  sin,
unsigned short  callno,
unsigned short  dcallno,
const struct chan_iax2_pvt cur,
int  check_dcallno 
) [static]

Definition at line 1984 of file chan_iax2.c.

References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.

Referenced by __find_callno(), ast_parse_device_state(), ast_srtp_add_stream(), ast_srtp_change_source(), check_blacklist(), find_by_name(), find_command(), handle_updates(), internal_ao2_callback(), lua_find_extension(), misdn_update_redirecting(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), and transfercallno_pvt_cmp_cb().

01985 {
01986    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01987       (cur->addr.sin_port == sin->sin_port)) {
01988       /* This is the main host */
01989       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01990           (check_dcallno ? dcallno == cur->callno : 1) ) {
01991          /* That's us.  Be sure we keep track of the peer call number */
01992          return 1;
01993       }
01994    }
01995    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01996        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01997       /* We're transferring */
01998       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01999          return 1;
02000    }
02001    return 0;
02002 }

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

Definition at line 6155 of file chan_iax2.c.

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

Referenced by decode_frame().

06156 {
06157 #if 0
06158    /* Debug with "fake encryption" */
06159    int x;
06160    if (len % 16)
06161       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06162    for (x=0;x<len;x++)
06163       dst[x] = src[x] ^ 0xff;
06164 #else 
06165    unsigned char lastblock[16] = { 0 };
06166    int x;
06167    while(len > 0) {
06168       ast_aes_decrypt(src, dst, dcx);
06169       for (x=0;x<16;x++)
06170          dst[x] ^= lastblock[x];
06171       memcpy(lastblock, src, sizeof(lastblock));
06172       dst += 16;
06173       src += 16;
06174       len -= 16;
06175    }
06176 #endif
06177 }

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

Definition at line 6179 of file chan_iax2.c.

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

Referenced by encrypt_frame().

06180 {
06181 #if 0
06182    /* Debug with "fake encryption" */
06183    int x;
06184    if (len % 16)
06185       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06186    for (x=0;x<len;x++)
06187       dst[x] = src[x] ^ 0xff;
06188 #else
06189    unsigned char curblock[16] = { 0 };
06190    int x;
06191    while(len > 0) {
06192       for (x=0;x<16;x++)
06193          curblock[x] ^= src[x];
06194       ast_aes_encrypt(curblock, dst, ecx);
06195       memcpy(curblock, dst, sizeof(curblock)); 
06196       dst += 16;
06197       src += 16;
06198       len -= 16;
06199    }
06200 #endif
06201 }

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

Definition at line 7745 of file chan_iax2.c.

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

Referenced by authenticate_reply(), and socket_process().

07746 {
07747    /* Select exactly one common encryption if there are any */
07748    p->encmethods &= enc;
07749    if (p->encmethods) {
07750       if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */
07751          p->keyrotateid = -2;
07752       }
07753       if (p->encmethods & IAX_ENCRYPT_AES128)
07754          p->encmethods = IAX_ENCRYPT_AES128;
07755       else
07756          p->encmethods = 0;
07757    }
07758 }

static void mwi_event_cb ( const struct ast_event event,
void *  userdata 
) [static]

Definition at line 1274 of file chan_iax2.c.

01275 {
01276    /* The MWI subscriptions exist just so the core knows we care about those
01277     * mailboxes.  However, we just grab the events out of the cache when it
01278     * is time to send MWI, since it is only sent with a REGACK. */
01279 }

static void network_change_event_cb ( const struct ast_event ,
void *   
) [static]

Definition at line 1312 of file chan_iax2.c.

References ast_debug, iax2_sched_add(), network_change_event_sched_cb(), and sched.

Referenced by network_change_event_subscribe().

01313 {
01314    ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n");
01315    if (network_change_event_sched_id == -1) {
01316       network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
01317    }
01318 
01319 }

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

Definition at line 1299 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_registry::entry, and iax2_do_register().

Referenced by network_change_event_cb().

01300 {
01301    struct iax2_registry *reg;
01302    network_change_event_sched_id = -1;
01303    AST_LIST_LOCK(&registrations);
01304    AST_LIST_TRAVERSE(&registrations, reg, entry) {
01305       iax2_do_register(reg);
01306    }
01307    AST_LIST_UNLOCK(&registrations);
01308 
01309    return 0;
01310 }

static void network_change_event_subscribe ( void   )  [static]

Definition at line 1281 of file chan_iax2.c.

References AST_EVENT_IE_END, AST_EVENT_NETWORK_CHANGE, ast_event_subscribe(), network_change_event_cb(), and network_change_event_subscription.

Referenced by load_module(), and set_config().

01282 {
01283    if (!network_change_event_subscription) {
01284       network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE,
01285          network_change_event_cb,
01286          "SIP Network Change ",
01287          NULL,
01288          AST_EVENT_IE_END);
01289    }
01290 }

static void network_change_event_unsubscribe ( void   )  [static]

Definition at line 1292 of file chan_iax2.c.

References ast_event_unsubscribe(), and network_change_event_subscription.

Referenced by __unload_module(), set_config(), and unload_module().

01293 {
01294    if (network_change_event_subscription) {
01295       network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription);
01296    }
01297 }

static void* network_thread ( void *  ignore  )  [static]

Definition at line 12067 of file chan_iax2.c.

References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), ast_timer_fd(), io, timer, and timing_read().

Referenced by start_network_thread().

12068 {
12069    if (timer) {
12070       ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12071    }
12072 
12073    for (;;) {
12074       pthread_testcancel();
12075       /* Wake up once a second just in case SIGURG was sent while
12076        * we weren't in poll(), to make sure we don't hang when trying
12077        * to unload. */
12078       ast_io_wait(io, 1000);
12079    }
12080 
12081    return NULL;
12082 }

static struct chan_iax2_pvt* new_iax ( struct sockaddr_in *  sin,
const char *  host 
) [static]

Definition at line 1913 of file chan_iax2.c.

References ao2_alloc, ao2_ref, AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_string_field_set, exten, jb_new(), jb_setconf(), jb_conf::max_contig_interp, jb_conf::max_jitterbuf, prefs, pvt_destructor(), jb_conf::resync_threshold, and jb_conf::target_extra.

Referenced by __find_callno().

01914 {
01915    struct chan_iax2_pvt *tmp;
01916    jb_conf jbconf;
01917 
01918    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01919       return NULL;
01920    }
01921 
01922    if (ast_string_field_init(tmp, 32)) {
01923       ao2_ref(tmp, -1);
01924       tmp = NULL;
01925       return NULL;
01926    }
01927       
01928    tmp->prefs = prefs;
01929    tmp->pingid = -1;
01930    tmp->lagid = -1;
01931    tmp->autoid = -1;
01932    tmp->authid = -1;
01933    tmp->initid = -1;
01934    tmp->keyrotateid = -1;
01935 
01936    ast_string_field_set(tmp,exten, "s");
01937    ast_string_field_set(tmp,host, host);
01938 
01939    tmp->jb = jb_new();
01940    tmp->jbid = -1;
01941    jbconf.max_jitterbuf = maxjitterbuffer;
01942    jbconf.resync_threshold = resyncthreshold;
01943    jbconf.max_contig_interp = maxjitterinterps;
01944    jbconf.target_extra = jittertargetextra;
01945    jb_setconf(tmp->jb,&jbconf);
01946 
01947    AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01948 
01949    tmp->hold_signaling = 1;
01950    AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
01951 
01952    return tmp;
01953 }

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

Parses an IAX dial string into its component parts.

Parameters:
data the string to be parsed
pds pointer to a struct parsed_dial_string to be filled in
Returns:
nothing
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 4944 of file chan_iax2.c.

References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, 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().

04945 {
04946    if (ast_strlen_zero(data))
04947       return;
04948 
04949    pds->peer = strsep(&data, "/");
04950    pds->exten = strsep(&data, "/");
04951    pds->options = data;
04952 
04953    if (pds->exten) {
04954       data = pds->exten;
04955       pds->exten = strsep(&data, "@");
04956       pds->context = data;
04957    }
04958 
04959    if (strchr(pds->peer, '@')) {
04960       data = pds->peer;
04961       pds->username = strsep(&data, "@");
04962       pds->peer = data;
04963    }
04964 
04965    if (pds->username) {
04966       data = pds->username;
04967       pds->username = strsep(&data, ":");
04968       pds->password = data;
04969    }
04970 
04971    data = pds->peer;
04972    pds->peer = strsep(&data, ":");
04973    pds->port = data;
04974 
04975    /* check for a key name wrapped in [] in the secret position, if found,
04976       move it to the key field instead
04977    */
04978    if (pds->password && (pds->password[0] == '[')) {
04979       pds->key = ast_strip_quoted(pds->password, "[", "]");
04980       pds->password = NULL;
04981    }
04982 }

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

References CMP_MATCH, CMP_STOP, and iax2_peer::name.

Referenced by load_module(), and load_objects().

01657 {
01658    struct iax2_peer *peer = obj, *peer2 = arg;
01659 
01660    return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01661 }

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

Definition at line 12811 of file chan_iax2.c.

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

12812 {
12813    struct iax2_peer *peer = obj;
12814 
12815    ast_set_flag64(peer, IAX_DELME);
12816 
12817    return 0;
12818 }

static void peer_destructor ( void *  obj  )  [static]

Definition at line 12243 of file chan_iax2.c.

References ast_dnsmgr_release(), ast_event_unsubscribe(), ast_free_ha(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_free_memory, iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::ha, iax2_destroy(), iaxsl, iax2_peer::mwi_event_sub, and register_peer_exten().

Referenced by build_peer().

12244 {
12245    struct iax2_peer *peer = obj;
12246    int callno = peer->callno;
12247 
12248    ast_free_ha(peer->ha);
12249 
12250    if (callno > 0) {
12251       ast_mutex_lock(&iaxsl[callno]);
12252       iax2_destroy(callno);
12253       ast_mutex_unlock(&iaxsl[callno]);
12254    }
12255 
12256    register_peer_exten(peer, 0);
12257 
12258    if (peer->dnsmgr)
12259       ast_dnsmgr_release(peer->dnsmgr);
12260 
12261    if (peer->mwi_event_sub)
12262       ast_event_unsubscribe(peer->mwi_event_sub);
12263 
12264    ast_string_field_free_memory(peer);
12265 }

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

References ast_str_hash(), and iax2_peer::name.

Referenced by load_module(), and load_objects().

01647 {
01648    const struct iax2_peer *peer = obj;
01649 
01650    return ast_str_hash(peer->name);
01651 }

static struct iax2_peer* peer_ref ( struct iax2_peer peer  )  [static]

Definition at line 1703 of file chan_iax2.c.

References ao2_ref.

Referenced by __iax2_poke_noanswer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), iax2_poke_peer(), reg_source_db(), socket_process(), and update_registry().

01704 {
01705    ao2_ref(peer, +1);
01706    return peer;
01707 }

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

Definition at line 14288 of file chan_iax2.c.

References iax2_peer::sockfd.

Referenced by load_module().

14289 {
14290    struct iax2_peer *peer = obj;
14291 
14292    if (peer->sockfd < 0)
14293       peer->sockfd = defaultsockfd;
14294 
14295    return 0;
14296 }

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

References ast_debug, ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_sockaddr_to_sin, ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, io, LOG_WARNING, iax2_peer::name, netsock, outsock, qos, socket_read(), iax2_peer::sockfd, and strsep().

Referenced by build_peer().

12170 {
12171    struct sockaddr_in sin;
12172    struct ast_sockaddr sin_tmp;
12173    int nonlocal = 1;
12174    int port = IAX_DEFAULT_PORTNO;
12175    int sockfd = defaultsockfd;
12176    char *tmp;
12177    char *addr;
12178    char *portstr;
12179 
12180    if (!(tmp = ast_strdupa(srcaddr)))
12181       return -1;
12182 
12183    addr = strsep(&tmp, ":");
12184    portstr = tmp;
12185 
12186    if (portstr) {
12187       port = atoi(portstr);
12188       if (port < 1)
12189          port = IAX_DEFAULT_PORTNO;
12190    }
12191    
12192    if (!ast_get_ip(&sin_tmp, addr)) {
12193       struct ast_netsock *sock;
12194       int res;
12195 
12196       ast_sockaddr_to_sin(&sin_tmp, &sin);
12197       sin.sin_port = 0;
12198       sin.sin_family = AF_INET;
12199       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12200       if (res == 0) {
12201          /* ip address valid. */
12202          sin.sin_port = htons(port);
12203          if (!(sock = ast_netsock_find(netsock, &sin)))
12204             sock = ast_netsock_find(outsock, &sin);
12205          if (sock) {
12206             sockfd = ast_netsock_sockfd(sock);
12207             nonlocal = 0;
12208          } else {
12209             unsigned int orig_saddr = sin.sin_addr.s_addr;
12210             /* INADDR_ANY matches anyway! */
12211             sin.sin_addr.s_addr = INADDR_ANY;
12212             if (ast_netsock_find(netsock, &sin)) {
12213                sin.sin_addr.s_addr = orig_saddr;
12214                sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12215                if (sock) {
12216                   sockfd = ast_netsock_sockfd(sock);
12217                   ast_netsock_unref(sock);
12218                   nonlocal = 0;
12219                } else {
12220                   nonlocal = 2;
12221                }
12222             }
12223          }
12224       }
12225    }
12226       
12227    peer->sockfd = sockfd;
12228 
12229    if (nonlocal == 1) {
12230       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12231          srcaddr, peer->name);
12232       return -1;
12233         } else if (nonlocal == 2) {
12234       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12235          srcaddr, peer->name);
12236          return -1;
12237    } else {
12238       ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12239       return 0;
12240    }
12241 }

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

peer_status: Report Peer status in character string

Definition at line 3702 of file chan_iax2.c.

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

Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), function_iaxpeer(), function_sippeer(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), and peers_data_provider_get().

03703 {
03704    int res = 0;
03705    if (peer->maxms) {
03706       if (peer->lastms < 0) {
03707          ast_copy_string(status, "UNREACHABLE", statuslen);
03708       } else if (peer->lastms > peer->maxms) {
03709          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03710          res = 1;
03711       } else if (peer->lastms) {
03712          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03713          res = 1;
03714       } else {
03715          ast_copy_string(status, "UNKNOWN", statuslen);
03716       }
03717    } else { 
03718       ast_copy_string(status, "Unmonitored", statuslen);
03719       res = -1;
03720    }
03721    return res;
03722 }

static struct iax2_peer* peer_unref ( struct iax2_peer peer  )  [inline, static]

Definition at line 1709 of file chan_iax2.c.

References ao2_ref.

Referenced by __expire_registry(), __iax2_poke_noanswer(), __iax2_poke_peer_s(), __iax2_show_peers(), authenticate_reply(), build_peer(), calltoken_required(), complete_iax2_peers(), complete_iax2_unregister(), create_addr(), function_iaxpeer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_peer(), handle_cli_iax2_unregister(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), manager_iax2_show_peer_list(), peers_data_provider_get(), poke_all_peers(), prune_peers(), reg_source_db(), registry_authrequest(), requirecalltoken_mark_auto(), set_config(), socket_process(), unlink_peer(), and update_registry().

01710 {
01711    ao2_ref(peer, -1);
01712    return NULL;
01713 }

static int peercnt_add ( struct sockaddr_in *  sin  )  [static]

Definition at line 2332 of file chan_iax2.c.

References peercnt::addr, ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_debug, ast_inet_ntoa(), ast_log(), LOG_ERROR, OBJ_POINTER, peercnts, and set_peercnt_limit().

Referenced by __find_callno(), and complete_transfer().

02333 {
02334    struct peercnt *peercnt;
02335    unsigned long addr = sin->sin_addr.s_addr;
02336    int res = 0;
02337    struct peercnt tmp = {
02338       .addr = addr,
02339    };
02340 
02341    /* Reasoning for peercnts container lock:  Two identical ip addresses
02342     * could be added by different threads at the "same time". Without the container
02343     * lock, both threads could alloc space for the same object and attempt
02344     * to link to table.  With the lock, one would create the object and link
02345     * to table while the other would find the already created peercnt object
02346     * rather than creating a new one. */
02347    ao2_lock(peercnts);
02348    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02349       ao2_lock(peercnt);
02350    } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02351       ao2_lock(peercnt);
02352       /* create and set defaults */
02353       peercnt->addr = addr;
02354       set_peercnt_limit(peercnt);
02355       /* guarantees it does not go away after unlocking table
02356        * ao2_find automatically adds this */
02357       ao2_link(peercnts, peercnt);
02358    } else {
02359       ao2_unlock(peercnts);
02360       return -1;
02361    }
02362 
02363    /* check to see if the address has hit its callno limit.  If not increment cur. */
02364    if (peercnt->limit > peercnt->cur) {
02365       peercnt->cur++;
02366       ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02367    } else { /* max num call numbers for this peer has been reached! */
02368       ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02369       res = -1;
02370    }
02371 
02372    /* clean up locks and ref count */
02373    ao2_unlock(peercnt);
02374    ao2_unlock(peercnts);
02375    ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */
02376 
02377    return res;
02378 }

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

Definition at line 2162 of file chan_iax2.c.

References peercnt::addr, CMP_MATCH, and CMP_STOP.

Referenced by load_objects().

02163 {
02164    struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02165    return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02166 }

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

Definition at line 2156 of file chan_iax2.c.

References peercnt::addr.

Referenced by load_objects().

02157 {
02158    const struct peercnt *peercnt = obj;
02159    return abs((int) peercnt->addr);
02160 }

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

Definition at line 2299 of file chan_iax2.c.

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

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

02300 {
02301    /* this function turns off and on custom callno limits set by peer registration */
02302    struct peercnt *peercnt;
02303    struct peercnt tmp = {
02304       .addr = 0,
02305    };
02306    struct sockaddr_in sin;
02307 
02308    ast_sockaddr_to_sin(sockaddr, &sin);
02309 
02310    tmp.addr = sin.sin_addr.s_addr;
02311 
02312    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02313       peercnt->reg = reg;
02314       if (limit) {
02315          peercnt->limit = limit;
02316       } else {
02317          set_peercnt_limit(peercnt);
02318       }
02319       ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg);
02320       ao2_ref(peercnt, -1); /* decrement ref from find */
02321    }
02322 }

static void peercnt_remove ( struct peercnt peercnt  )  [static]

Definition at line 2384 of file chan_iax2.c.

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

Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().

02385 {
02386    struct sockaddr_in sin = {
02387       .sin_addr.s_addr = peercnt->addr,
02388    };
02389 
02390    if (peercnt) {
02391       /* Container locked here since peercnt may be unlinked from list.  If left unlocked,
02392        * peercnt_add could try and grab this entry from the table and modify it at the
02393        * "same time" this thread attemps to unlink it.*/
02394       ao2_lock(peercnts);
02395       peercnt->cur--;
02396       ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02397       /* if this was the last connection from the peer remove it from table */
02398       if (peercnt->cur == 0) {
02399          ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */
02400       }
02401       ao2_unlock(peercnts);
02402    }
02403 }

static int peercnt_remove_by_addr ( struct sockaddr_in *  sin  )  [static]

Definition at line 2423 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

02424 {
02425    struct peercnt *peercnt;
02426    struct peercnt tmp = {
02427       .addr = sin->sin_addr.s_addr,
02428    };
02429 
02430    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02431       peercnt_remove(peercnt);
02432       ao2_ref(peercnt, -1); /* decrement ref from find */
02433    }
02434    return 0;
02435 }

static int peercnt_remove_cb ( const void *  obj  )  [static]

Definition at line 2409 of file chan_iax2.c.

References ao2_ref, and peercnt_remove().

Referenced by sched_delay_remove().

02410 {
02411    struct peercnt *peercnt = (struct peercnt *) obj;
02412 
02413    peercnt_remove(peercnt);
02414    ao2_ref(peercnt, -1); /* decrement ref from scheduler */
02415 
02416    return 0;
02417 }

static int peers_data_provider_get ( const struct ast_data_search search,
struct ast_data data_root 
) [static]

Definition at line 14422 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_host(), ast_str_alloca, ast_str_buffer(), ast_test_flag64, iax2_peer::capability, iax2_peer::encmethods, encmethods_to_str(), IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, peer_status(), peer_unref(), peers, and status.

14424 {
14425    struct ast_data *data_peer;
14426    struct iax2_peer *peer;
14427    struct ao2_iterator i;
14428    char status[20];
14429    struct ast_str *encmethods = ast_str_alloca(256);
14430 
14431    i = ao2_iterator_init(peers, 0);
14432    while ((peer = ao2_iterator_next(&i))) {
14433       data_peer = ast_data_add_node(data_root, "peer");
14434       if (!data_peer) {
14435          peer_unref(peer);
14436          continue;
14437       }
14438 
14439       ast_data_add_structure(iax2_peer, data_peer, peer);
14440 
14441       ast_data_add_codecs(data_peer, "codecs", peer->capability);
14442 
14443       peer_status(peer, status, sizeof(status));
14444       ast_data_add_str(data_peer, "status", status);
14445 
14446       ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14447 
14448       ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14449 
14450       ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14451 
14452       ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14453 
14454       ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14455 
14456       encmethods_to_str(peer->encmethods, encmethods);
14457       ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14458 
14459       peer_unref(peer);
14460 
14461       if (!ast_data_search_match(search, data_peer)) {
14462          ast_data_remove_node(data_root, data_peer);
14463       }
14464    }
14465    ao2_iterator_destroy(&i);
14466 
14467    return 0;
14468 }

static void poke_all_peers ( void   )  [static]

Definition at line 13377 of file chan_iax2.c.

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

Referenced by reload_config().

13378 {
13379    struct ao2_iterator i;
13380    struct iax2_peer *peer;
13381 
13382    i = ao2_iterator_init(peers, 0);
13383    while ((peer = ao2_iterator_next(&i))) {
13384       iax2_poke_peer(peer, 0);
13385       peer_unref(peer);
13386    }
13387    ao2_iterator_destroy(&i);
13388 }

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

Definition at line 2288 of file chan_iax2.c.

References CMP_MATCH, and addr_range::delme.

Referenced by reload_config().

02289 {
02290    struct addr_range *addr_range = obj;
02291 
02292    return addr_range->delme ? CMP_MATCH : 0;
02293 }

static void prune_peers ( void   )  [static]

Definition at line 12874 of file chan_iax2.c.

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

12875 {
12876    struct iax2_peer *peer;
12877    struct ao2_iterator i;
12878 
12879    i = ao2_iterator_init(peers, 0);
12880    while ((peer = ao2_iterator_next(&i))) {
12881       if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
12882          unlink_peer(peer);
12883       }
12884       peer_unref(peer);
12885    }
12886    ao2_iterator_destroy(&i);
12887 }

static void prune_users ( void   )  [static]

Definition at line 12858 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_prune_realtime(), and reload_config().

12859 {
12860    struct iax2_user *user;
12861    struct ao2_iterator i;
12862 
12863    i = ao2_iterator_init(users, 0);
12864    while ((user = ao2_iterator_next(&i))) {
12865       if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
12866          ao2_unlink(users, user);
12867       }
12868       user_unref(user);
12869    }
12870    ao2_iterator_destroy(&i);
12871 }

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

Definition at line 14305 of file chan_iax2.c.

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

14306 {
14307    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14308 
14309    /* The frames_received field is used to hold whether we're matching
14310     * against a full frame or not ... */
14311 
14312    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
14313       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14314 }

static void pvt_destructor ( void *  obj  )  [static]

Definition at line 1866 of file chan_iax2.c.

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, iax2_trunk_peer::list, iax2_trunk_peer::next, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, sched_delay_remove(), chan_iax2_pvt::signaling_queue, and chan_iax2_pvt::vars.

01867 {
01868    struct chan_iax2_pvt *pvt = obj;
01869    struct iax_frame *cur = NULL;
01870    struct signaling_queue_entry *s = NULL;
01871 
01872    ast_mutex_lock(&iaxsl[pvt->callno]);
01873 
01874    iax2_destroy_helper(pvt);
01875 
01876    sched_delay_remove(&pvt->addr, pvt->callno_entry);
01877    pvt->callno_entry = NULL;
01878 
01879    /* Already gone */
01880    ast_set_flag64(pvt, IAX_ALREADYGONE);
01881 
01882    AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) {
01883       /* Cancel any pending transmissions */
01884       cur->retries = -1;
01885    }
01886 
01887    ast_mutex_unlock(&iaxsl[pvt->callno]);
01888 
01889    while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01890       free_signaling_queue_entry(s);
01891    }
01892 
01893    if (pvt->reg) {
01894       pvt->reg->callno = 0;
01895    }
01896 
01897    if (!pvt->owner) {
01898       jb_frame frame;
01899       if (pvt->vars) {
01900           ast_variables_destroy(pvt->vars);
01901           pvt->vars = NULL;
01902       }
01903 
01904       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01905          iax2_frame_free(frame.data);
01906       }
01907 
01908       jb_destroy(pvt->jb);
01909       ast_string_field_free_memory(pvt);
01910    }
01911 }

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

Definition at line 14298 of file chan_iax2.c.

References chan_iax2_pvt::peercallno.

14299 {
14300    const struct chan_iax2_pvt *pvt = obj;
14301 
14302    return pvt->peercallno;
14303 }

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

References ast_calloc, AST_FRAME_IAX, AST_LIST_INSERT_TAIL, f, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_trunk_peer::next, and chan_iax2_pvt::signaling_queue.

Referenced by __send_command().

01843 {
01844    struct signaling_queue_entry *new;
01845 
01846    if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01847       return 1; /* do not queue this frame */
01848    } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01849       return -1;  /* out of memory */
01850    }
01851 
01852    memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */
01853 
01854    if (new->f.datalen) { /* if there is data in this frame copy it over as well */
01855       if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
01856          free_signaling_queue_entry(new);
01857          return -1;
01858       }
01859       memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
01860    }
01861    AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
01862 
01863    return 0;
01864 }

static int raw_hangup ( struct sockaddr_in *  sin,
unsigned short  src,
unsigned short  dst,
int  sockfd 
) [static]

Definition at line 7726 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_inet_ntoa(), 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, option_debug, 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().

07727 {
07728    struct ast_iax2_full_hdr fh;
07729    fh.scallno = htons(src | IAX_FLAG_FULL);
07730    fh.dcallno = htons(dst);
07731    fh.ts = 0;
07732    fh.oseqno = 0;
07733    fh.iseqno = 0;
07734    fh.type = AST_FRAME_IAX;
07735    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07736    iax_outputframe(NULL, &fh, 0, sin, 0);
07737 #if 0
07738    if (option_debug)
07739 #endif   
07740       ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07741          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07742    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07743 }

static struct iax2_peer * realtime_peer ( const char *  peername,
struct sockaddr_in *  sin 
) [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 4305 of file chan_iax2.c.

References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.

04306 {
04307    struct ast_variable *var = NULL;
04308    struct ast_variable *tmp;
04309    struct iax2_peer *peer=NULL;
04310    time_t regseconds = 0, nowtime;
04311    int dynamic=0;
04312 
04313    if (peername) {
04314       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04315       if (!var && sin)
04316          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04317    } else if (sin) {
04318       char porta[25];
04319       sprintf(porta, "%d", ntohs(sin->sin_port));
04320       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04321       if (var) {
04322          /* We'll need the peer name in order to build the structure! */
04323          for (tmp = var; tmp; tmp = tmp->next) {
04324             if (!strcasecmp(tmp->name, "name"))
04325                peername = tmp->value;
04326          }
04327       }
04328    }
04329    if (!var && peername) { /* Last ditch effort */
04330       var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04331       /*!\note
04332        * If this one loaded something, then we need to ensure that the host
04333        * field matched.  The only reason why we can't have this as a criteria
04334        * is because we only have the IP address and the host field might be
04335        * set as a name (and the reverse PTR might not match).
04336        */
04337       if (var && sin) {
04338          for (tmp = var; tmp; tmp = tmp->next) {
04339             if (!strcasecmp(tmp->name, "host")) {
04340                struct ast_hostent ahp;
04341                struct hostent *hp;
04342                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04343                   /* No match */
04344                   ast_variables_destroy(var);
04345                   var = NULL;
04346                }
04347                break;
04348             }
04349          }
04350       }
04351    }
04352    if (!var)
04353       return NULL;
04354 
04355    peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04356 
04357    if (!peer) {
04358       ast_variables_destroy(var);
04359       return NULL;
04360    }
04361 
04362    for (tmp = var; tmp; tmp = tmp->next) {
04363       /* Make sure it's not a user only... */
04364       if (!strcasecmp(tmp->name, "type")) {
04365          if (strcasecmp(tmp->value, "friend") &&
04366              strcasecmp(tmp->value, "peer")) {
04367             /* Whoops, we weren't supposed to exist! */
04368             peer = peer_unref(peer);
04369             break;
04370          } 
04371       } else if (!strcasecmp(tmp->name, "regseconds")) {
04372          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
04373       } else if (!strcasecmp(tmp->name, "ipaddr")) {
04374          ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE);
04375       } else if (!strcasecmp(tmp->name, "port")) {
04376          ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
04377       } else if (!strcasecmp(tmp->name, "host")) {
04378          if (!strcasecmp(tmp->value, "dynamic"))
04379             dynamic = 1;
04380       }
04381    }
04382 
04383    ast_variables_destroy(var);
04384 
04385    if (!peer)
04386       return NULL;
04387 
04388    if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04389       ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04390       if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
04391          if (peer->expire > -1) {
04392             if (!ast_sched_thread_del(sched, peer->expire)) {
04393                peer->expire = -1;
04394                peer_unref(peer);
04395             }
04396          }
04397          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04398          if (peer->expire == -1)
04399             peer_unref(peer);
04400       }
04401       ao2_link(peers, peer);
04402       if (ast_test_flag64(peer, IAX_DYNAMIC))
04403          reg_source_db(peer);
04404    } else {
04405       ast_set_flag64(peer, IAX_TEMPONLY);
04406    }
04407 
04408    if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04409       time(&nowtime);
04410       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04411          memset(&peer->addr, 0, sizeof(peer->addr));
04412          realtime_update_peer(peer->name, &peer->addr, 0);
04413          ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04414             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04415       }
04416       else {
04417          ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04418             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04419       }
04420    }
04421 
04422    return peer;
04423 }

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

Definition at line 4496 of file chan_iax2.c.

References ast_config_AST_SYSTEM_NAME, ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_test_flag64, ast_update_realtime(), globalflags, IAX_RTSAVE_SYSNAME, and SENTINEL.

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

04497 {
04498    char port[10];
04499    char regseconds[20];
04500    const char *sysname = ast_config_AST_SYSTEM_NAME;
04501    char *syslabel = NULL;
04502 
04503    if (ast_strlen_zero(sysname)) /* No system name, disable this */
04504       sysname = NULL;
04505    else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME))
04506       syslabel = "regserver";
04507 
04508    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04509    snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
04510    ast_update_realtime("iaxpeers", "name", peername, 
04511       "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 
04512       "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */
04513 }

static struct iax2_user * realtime_user ( const char *  username,
struct sockaddr_in *  sin 
) [static]

Definition at line 4425 of file chan_iax2.c.

References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.

04426 {
04427    struct ast_variable *var;
04428    struct ast_variable *tmp;
04429    struct iax2_user *user=NULL;
04430 
04431    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04432    if (!var)
04433       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04434    if (!var && sin) {
04435       char porta[6];
04436       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04437       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04438       if (!var)
04439          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04440    }
04441    if (!var) { /* Last ditch effort */
04442       var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04443       /*!\note
04444        * If this one loaded something, then we need to ensure that the host
04445        * field matched.  The only reason why we can't have this as a criteria
04446        * is because we only have the IP address and the host field might be
04447        * set as a name (and the reverse PTR might not match).
04448        */
04449       if (var) {
04450          for (tmp = var; tmp; tmp = tmp->next) {
04451             if (!strcasecmp(tmp->name, "host")) {
04452                struct ast_hostent ahp;
04453                struct hostent *hp;
04454                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04455                   /* No match */
04456                   ast_variables_destroy(var);
04457                   var = NULL;
04458                }
04459                break;
04460             }
04461          }
04462       }
04463    }
04464    if (!var)
04465       return NULL;
04466 
04467    tmp = var;
04468    while(tmp) {
04469       /* Make sure it's not a peer only... */
04470       if (!strcasecmp(tmp->name, "type")) {
04471          if (strcasecmp(tmp->value, "friend") &&
04472              strcasecmp(tmp->value, "user")) {
04473             return NULL;
04474          } 
04475       }
04476       tmp = tmp->next;
04477    }
04478 
04479    user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS));
04480 
04481    ast_variables_destroy(var);
04482 
04483    if (!user)
04484       return NULL;
04485 
04486    if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04487       ast_set_flag64(user, IAX_RTCACHEFRIENDS);
04488       ao2_link(users, user);
04489    } else {
04490       ast_set_flag64(user, IAX_TEMPONLY);
04491    }
04492 
04493    return user;
04494 }

static void reg_source_db ( struct iax2_peer p  )  [static]

Definition at line 8605 of file chan_iax2.c.

References iax2_peer::addr, ast_db_get(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), ast_sched_thread_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(), register_peer_exten(), and sched.

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

08606 {
08607    char data[80];
08608    char *expiry;
08609 
08610    if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08611       return;
08612    }
08613 
08614    expiry = strrchr(data, ':');
08615    if (!expiry) {
08616       ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08617    }
08618    *expiry++ = '\0';
08619 
08620    if (ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08621       ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08622       return;
08623    }
08624 
08625    p->expiry = atoi(expiry);
08626 
08627    ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08628       ast_sockaddr_stringify(&p->addr), p->expiry);
08629 
08630    iax2_poke_peer(p, 0);
08631    if (p->expire > -1) {
08632       if (!ast_sched_thread_del(sched, p->expire)) {
08633          p->expire = -1;
08634          peer_unref(p);
08635       }
08636    }
08637 
08638    ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
08639 
08640    p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08641    if (p->expire == -1) {
08642       peer_unref(p);
08643    }
08644 
08645    if (iax2_regfunk) {
08646       iax2_regfunk(p->name, 1);
08647    }
08648 
08649    register_peer_exten(p, 1);
08650 }

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

Definition at line 8524 of file chan_iax2.c.

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, iax2_peer::regexten, S_OR, and strsep().

Referenced by __expire_registry(), expire_register(), handle_response_peerpoke(), parse_register_contact(), peer_destructor(), reg_source_db(), sip_destroy_peer(), sip_poke_noanswer(), and update_registry().

08525 {
08526    char multi[256];
08527    char *stringp, *ext;
08528    if (!ast_strlen_zero(regcontext)) {
08529       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08530       stringp = multi;
08531       while((ext = strsep(&stringp, "&"))) {
08532          if (onoff) {
08533             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08534                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08535                        "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08536          } else
08537             ast_context_remove_extension(regcontext, ext, 1, NULL);
08538       }
08539    }
08540 }

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

Verify inbound registration.

Definition at line 7900 of file chan_iax2.c.

References ast_apply_ha(), ast_check_signature(), ast_clear_flag, ast_copy_string(), ast_inet_ntoa(), ast_key_get(), AST_KEY_PUBLIC, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_sockaddr_from_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, iax2_peer::authmethods, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, iaxs, iaxsl, iax2_peer::inkeys, LOG_NOTICE, LOG_WARNING, md5(), iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax_ies::password, iax_ies::refresh, iax_ies::rsa_result, iax2_peer::secret, secret, state, strsep(), and iax_ies::username.

Referenced by handle_request_register(), and socket_process().

07901 {
07902    char requeststr[256] = "";
07903    char peer[256] = "";
07904    char md5secret[256] = "";
07905    char rsasecret[256] = "";
07906    char secret[256] = "";
07907    struct iax2_peer *p = NULL;
07908    struct ast_key *key;
07909    char *keyn;
07910    int x;
07911    int expire = 0;
07912    int res = -1;
07913    struct ast_sockaddr addr;
07914 
07915    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07916    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
07917    if (ies->username)
07918       ast_copy_string(peer, ies->username, sizeof(peer));
07919    if (ies->password)
07920       ast_copy_string(secret, ies->password, sizeof(secret));
07921    if (ies->md5_result)
07922       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07923    if (ies->rsa_result)
07924       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07925    if (ies->refresh)
07926       expire = ies->refresh;
07927 
07928    if (ast_strlen_zero(peer)) {
07929       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07930       return -1;
07931    }
07932 
07933    /* SLD: first call to lookup peer during registration */
07934    ast_mutex_unlock(&iaxsl[callno]);
07935    p = find_peer(peer, 1);
07936    ast_mutex_lock(&iaxsl[callno]);
07937    if (!p || !iaxs[callno]) {
07938       if (iaxs[callno]) {
07939          int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07940          /* Anything, as long as it's non-blank */
07941          ast_string_field_set(iaxs[callno], secret, "badsecret");
07942          /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
07943           * 1. A challenge already exists indicating a AUTHREQ was already sent out.
07944           * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
07945           * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
07946           *    to be plaintext, indicating it is an authmethod used by other peers on the system. 
07947           *
07948           * If none of these cases exist, res will be returned as 0 without authentication indicating
07949           * an AUTHREQ needs to be sent out. */
07950 
07951          if (ast_strlen_zero(iaxs[callno]->challenge) &&
07952             !(!ast_strlen_zero(secret) && plaintext)) {
07953             /* by setting res to 0, an REGAUTH will be sent */
07954             res = 0;
07955          }
07956       }
07957       if (authdebug && !p)
07958          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07959       goto return_unref;
07960    }
07961 
07962    if (!ast_test_flag64(p, IAX_DYNAMIC)) {
07963       if (authdebug)
07964          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07965       goto return_unref;
07966    }
07967 
07968    ast_sockaddr_from_sin(&addr, sin);
07969    if (!ast_apply_ha(p->ha, &addr)) {
07970       if (authdebug)
07971          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07972       goto return_unref;
07973    }
07974    ast_string_field_set(iaxs[callno], secret, p->secret);
07975    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
07976    /* Check secret against what we have on file */
07977    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07978       if (!ast_strlen_zero(p->inkeys)) {
07979          char tmpkeys[256];
07980          char *stringp=NULL;
07981          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
07982          stringp=tmpkeys;
07983          keyn = strsep(&stringp, ":");
07984          while(keyn) {
07985             key = ast_key_get(keyn, AST_KEY_PUBLIC);
07986             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
07987                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07988                break;
07989             } else if (!key)
07990                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
07991             keyn = strsep(&stringp, ":");
07992          }
07993          if (!keyn) {
07994             if (authdebug)
07995                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
07996             goto return_unref;
07997          }
07998       } else {
07999          if (authdebug)
08000             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
08001          goto return_unref;
08002       }
08003    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08004       struct MD5Context md5;
08005       unsigned char digest[16];
08006       char *tmppw, *stringp;
08007 
08008       tmppw = ast_strdupa(p->secret);
08009       stringp = tmppw;
08010       while((tmppw = strsep(&stringp, ";"))) {
08011          MD5Init(&md5);
08012          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
08013          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08014          MD5Final(digest, &md5);
08015          for (x=0;x<16;x++)
08016             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
08017          if (!strcasecmp(requeststr, md5secret))
08018             break;
08019       }
08020       if (tmppw) {
08021          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08022       } else {
08023          if (authdebug)
08024             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
08025          goto return_unref;
08026       }
08027    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
08028       /* They've provided a plain text password and we support that */
08029       if (strcmp(secret, p->secret)) {
08030          if (authdebug)
08031             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08032          goto return_unref;
08033       } else
08034          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08035    } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
08036       /* if challenge has been sent, but no challenge response if given, reject. */
08037       goto return_unref;
08038    }
08039    ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
08040 
08041    /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
08042    res = 0;
08043 
08044 return_unref:
08045    if (iaxs[callno]) {
08046       ast_string_field_set(iaxs[callno], peer, peer);
08047 
08048       /* Choose lowest expiry number */
08049       if (expire && (expire < iaxs[callno]->expiry)) {
08050          iaxs[callno]->expiry = expire;
08051       }
08052    }
08053 
08054    if (p) {
08055       peer_unref(p);
08056    }
08057    return res;
08058 }

static int registry_authrequest ( int  callno  )  [static]

Definition at line 8826 of file chan_iax2.c.

References AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::authmethods, iax2_peer::authmethods, find_peer(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, 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, peer_unref(), and send_command().

Referenced by socket_process().

08827 {
08828    struct iax_ie_data ied;
08829    struct iax2_peer *p;
08830    char challenge[10];
08831    const char *peer_name;
08832    int sentauthmethod;
08833 
08834    peer_name = ast_strdupa(iaxs[callno]->peer);
08835 
08836    /* SLD: third call to find_peer in registration */
08837    ast_mutex_unlock(&iaxsl[callno]);
08838    if ((p = find_peer(peer_name, 1))) {
08839       last_authmethod = p->authmethods;
08840    }
08841 
08842    ast_mutex_lock(&iaxsl[callno]);
08843    if (!iaxs[callno])
08844       goto return_unref;
08845 
08846    memset(&ied, 0, sizeof(ied));
08847    /* The selection of which delayed reject is sent may leak information,
08848     * if it sets a static response.  For example, if a host is known to only
08849     * use MD5 authentication, then an RSA response would indicate that the
08850     * peer does not exist, and vice-versa.
08851     * Therefore, we use whatever the last peer used (which may vary over the
08852     * course of a server, which should leak minimal information). */
08853    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08854    if (!p) {
08855       iaxs[callno]->authmethods = sentauthmethod;
08856    }
08857    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08858    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08859       /* Build the challenge */
08860       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08861       ast_string_field_set(iaxs[callno], challenge, challenge);
08862       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08863    }
08864    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08865 
08866 return_unref:
08867    if (p) {
08868       peer_unref(p);
08869    }
08870 
08871    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08872 }

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

Definition at line 8874 of file chan_iax2.c.

References add_empty_calltoken_ie(), iax2_registry::addr, ast_copy_string(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_sockaddr_to_sin, ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.

Referenced by socket_process().

08875 {
08876    struct iax2_registry *reg;
08877    /* Start pessimistic */
08878    struct iax_ie_data ied;
08879    char peer[256] = "";
08880    char challenge[256] = "";
08881    int res;
08882    int authmethods = 0;
08883    if (ies->authmethods)
08884       authmethods = ies->authmethods;
08885    if (ies->username)
08886       ast_copy_string(peer, ies->username, sizeof(peer));
08887    if (ies->challenge)
08888       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08889    memset(&ied, 0, sizeof(ied));
08890    reg = iaxs[callno]->reg;
08891    if (reg) {
08892       struct sockaddr_in reg_addr;
08893 
08894       ast_sockaddr_to_sin(&reg->addr, &reg_addr);
08895 
08896       if (inaddrcmp(&reg_addr, sin)) {
08897          ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08898          return -1;
08899       }
08900       if (ast_strlen_zero(reg->secret)) {
08901          ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08902          reg->regstate = REG_STATE_NOAUTH;
08903          return -1;
08904       }
08905       iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08906       iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08907       if (reg->secret[0] == '[') {
08908          char tmpkey[256];
08909          ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08910          tmpkey[strlen(tmpkey) - 1] = '\0';
08911          res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08912       } else
08913          res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08914       if (!res) {
08915          reg->regstate = REG_STATE_AUTHSENT;
08916          add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
08917          return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08918       } else
08919          return -1;
08920       ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08921    } else   
08922       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08923    return -1;
08924 }

static char* regstate2str ( int  regstate  )  [static]

Definition at line 7010 of file chan_iax2.c.

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

Referenced by handle_cli_iax2_show_registry(), handle_response_register(), manager_iax2_show_registry(), manager_show_registry(), sip_reg_timeout(), and sip_show_registry().

07011 {
07012    switch(regstate) {
07013    case REG_STATE_UNREGISTERED:
07014       return "Unregistered";
07015    case REG_STATE_REGSENT:
07016       return "Request Sent";
07017    case REG_STATE_AUTHSENT:
07018       return "Auth. Sent";
07019    case REG_STATE_REGISTERED:
07020       return "Registered";
07021    case REG_STATE_REJECTED:
07022       return "Rejected";
07023    case REG_STATE_TIMEOUT:
07024       return "Timeout";
07025    case REG_STATE_NOAUTH:
07026       return "No Authentication";
07027    default:
07028       return "Unknown";
07029    }
07030 }

static int reload ( void   )  [static]

Definition at line 13438 of file chan_iax2.c.

References reload_config().

13439 {
13440    return reload_config();
13441 }

static int reload_config ( void   )  [static]

Definition at line 13389 of file chan_iax2.c.

References ao2_callback, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_unload_realtime(), callno_limits, calltoken_ignores, config, debugaddr, iax2_registry::entry, iax2_do_register(), iax_provision_reload(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, peercnts, poke_all_peers(), prune_addr_range_cb(), prune_peers(), prune_users(), reload_firmware(), set_config(), and set_peercnt_limit_all_cb().

13390 {
13391    static const char config[] = "iax.conf";
13392    struct iax2_registry *reg;
13393 
13394    if (set_config(config, 1) > 0) {
13395       prune_peers();
13396       prune_users();
13397       ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13398       ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13399       ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13400       trunk_timed = trunk_untimed = 0; 
13401       trunk_nmaxmtu = trunk_maxmtu = 0;
13402       memset(&debugaddr, '\0', sizeof(debugaddr));
13403 
13404       AST_LIST_LOCK(&registrations);
13405       AST_LIST_TRAVERSE(&registrations, reg, entry)
13406          iax2_do_register(reg);
13407       AST_LIST_UNLOCK(&registrations);
13408 
13409       /* Qualify hosts, too */
13410       poke_all_peers();
13411    }
13412    
13413    reload_firmware(0);
13414    iax_provision_reload(1);
13415    ast_unload_realtime("iaxpeers");
13416 
13417    return 0;
13418 }

static void reload_firmware ( int  unload  )  [static]

Definition at line 3200 of file chan_iax2.c.

References ast_config_AST_DATA_DIR, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verb, iax_firmware::dead, destroy_firmware(), errno, iax2_trunk_peer::list, LOG_WARNING, and try_firmware().

Referenced by __unload_module(), load_module(), and reload_config().

03201 {
03202    struct iax_firmware *cur = NULL;
03203    DIR *fwd;
03204    struct dirent *de;
03205    char dir[256], fn[256];
03206 
03207    AST_LIST_LOCK(&firmwares);
03208 
03209    /* Mark all as dead */
03210    AST_LIST_TRAVERSE(&firmwares, cur, list)
03211       cur->dead = 1;
03212 
03213    /* Now that we have marked them dead... load new ones */
03214    if (!unload) {
03215       snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03216       fwd = opendir(dir);
03217       if (fwd) {
03218          while((de = readdir(fwd))) {
03219             if (de->d_name[0] != '.') {
03220                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03221                if (!try_firmware(fn)) {
03222                   ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03223                }
03224             }
03225          }
03226          closedir(fwd);
03227       } else 
03228          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03229    }
03230 
03231    /* Clean up leftovers */
03232    AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03233       if (!cur->dead)
03234          continue;
03235       AST_LIST_REMOVE_CURRENT(list);
03236       destroy_firmware(cur);
03237    }
03238    AST_LIST_TRAVERSE_SAFE_END;
03239 
03240    AST_LIST_UNLOCK(&firmwares);
03241 }

static void remove_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2123 of file chan_iax2.c.

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

02124 {
02125    if (!pvt->peercallno) {
02126       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02127       return;
02128    }
02129 
02130    ao2_unlink(iax_peercallno_pvts, pvt);
02131 }

static void remove_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2104 of file chan_iax2.c.

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

Referenced by complete_transfer(), and iax2_destroy().

02105 {
02106    if (!pvt->transfercallno) {
02107       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02108       return;
02109    }
02110 
02111    ao2_unlink(iax_transfercallno_pvts, pvt);
02112 }

static int replace_callno ( const void *  obj  )  [static]

Definition at line 2632 of file chan_iax2.c.

References ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_log(), callno_entry::callno, LOG_ERROR, TRUNK_CALL_START, and callno_entry::validated.

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

02633 {
02634    struct callno_entry *callno_entry = (struct callno_entry *) obj;
02635 
02636    /* the callno_pool container is locked here primarily to ensure thread
02637     * safety of the total_nonval_callno_used check and decrement */
02638    ao2_lock(callno_pool);
02639 
02640    if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02641       total_nonval_callno_used--;
02642    } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02643       ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02644    }
02645 
02646    if (callno_entry->callno < TRUNK_CALL_START) {
02647       ao2_link(callno_pool, callno_entry);
02648    } else {
02649       ao2_link(callno_pool_trunk, callno_entry);
02650    }
02651    ao2_ref(callno_entry, -1); /* only container ref remains */
02652 
02653    ao2_unlock(callno_pool);
02654    return 0;
02655 }

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

Definition at line 4801 of file chan_iax2.c.

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

Referenced by handle_call_token().

04802 {
04803    struct iax2_user *user = NULL;
04804    struct iax2_peer *peer = NULL;
04805 
04806    if (ast_strlen_zero(name)) {
04807       return; /* no username given */
04808    }
04809 
04810    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04811       user->calltoken_required = CALLTOKEN_YES;
04812    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04813       peer->calltoken_required = CALLTOKEN_YES;
04814    }
04815 
04816    if (peer) {
04817       peer_unref(peer);
04818    }
04819    if (user) {
04820       user_unref(user);
04821    }
04822 }

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

Definition at line 4719 of file chan_iax2.c.

References chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_LIST_REMOVE, iax_ie_data::buf, chan_iax2_pvt::calltoken_ie_len, f, frame_queue, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, remove_by_peercallno(), chan_iax2_pvt::rseqno, and send_command().

Referenced by socket_process().

04720 {
04721    struct chan_iax2_pvt *pvt = iaxs[callno];
04722    int frametype = f->af.frametype;
04723    int subclass = f->af.subclass.integer;
04724    struct {
04725       struct ast_iax2_full_hdr fh;
04726       struct iax_ie_data ied;
04727    } data = {
04728       .ied.buf = { 0 },
04729       .ied.pos = 0,
04730    };
04731    /* total len - header len gives us the frame's IE len */
04732    int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04733 
04734    if (!pvt) {
04735       return;  /* this should not be possible if called from socket_process() */
04736    }
04737 
04738    /* 
04739     * Check to make sure last frame sent is valid for call token resend
04740     * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 
04741     * 2. Frame should _NOT_ already have a destination callno
04742     * 3. Frame must be a valid iax_frame subclass capable of starting dialog
04743     * 4. Pvt must have a calltoken_ie_len which represents the number of
04744     *    bytes at the end of the frame used for the previous calltoken ie.
04745     * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length
04746     * 6. Total length of f->data must be _LESS_ than size of our data struct
04747     *    because f->data must be able to fit within data. 
04748     */
04749    if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04750       || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04751       (f->datalen > sizeof(data))) {
04752 
04753       return;  /* ignore resend, token was not valid for the dialog */
04754    }
04755 
04756    /* token is valid
04757     * 1. Copy frame data over
04758     * 2. Redo calltoken IE, it will always be the last ie in the frame.
04759     *    NOTE: Having the ie always be last is not protocol specified,
04760     *    it is only an implementation choice.  Since we only expect the ie to
04761     *    be last for frames we have sent, this can no way be affected by
04762     *    another end point.
04763     * 3. Remove frame from queue
04764     * 4. Free old frame
04765     * 5. Clear previous seqnos
04766     * 6. Resend with CALLTOKEN ie.
04767     */
04768 
04769    /* ---1.--- */
04770    memcpy(&data, f->data, f->datalen);
04771    data.ied.pos = ie_data_pos;
04772 
04773    /* ---2.--- */
04774    /* move to the beginning of the calltoken ie so we can write over it */
04775    data.ied.pos -= pvt->calltoken_ie_len;
04776    iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04777 
04778    /* make sure to update token length incase it ever has to be stripped off again */
04779    pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */
04780 
04781    /* ---3.--- */
04782    AST_LIST_REMOVE(&frame_queue[callno], f, list);
04783 
04784    /* ---4.--- */
04785    iax2_frame_free(f);
04786 
04787    /* ---5.--- */
04788    pvt->oseqno = 0;
04789    pvt->rseqno = 0;
04790    pvt->iseqno = 0;
04791    pvt->aseqno = 0;
04792    if (pvt->peercallno) {
04793       remove_by_peercallno(pvt);
04794       pvt->peercallno = 0;
04795    }
04796 
04797    /* ---6.--- */
04798    send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04799 }

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

Definition at line 9355 of file chan_iax2.c.

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

09356 {
09357    int i;
09358    unsigned int length, offset = 0;
09359    char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09360 
09361    for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09362       length = ies->ospblocklength[i];
09363       if (length != 0) {
09364          if (length > IAX_MAX_OSPBLOCK_SIZE) {
09365             /* OSP token block length wrong, clear buffer */
09366             offset = 0;
09367             break;
09368          } else {
09369             memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09370             offset += length;
09371          }
09372       } else {
09373          break;
09374       }
09375    }
09376    *(full_osptoken + offset) = '\0';
09377    if (strlen(full_osptoken) != offset) {
09378       /* OSP token length wrong, clear buffer */
09379       *full_osptoken = '\0';
09380    }
09381 
09382    ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09383 }

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

Definition at line 9344 of file chan_iax2.c.

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

Referenced by socket_process().

09345 {
09346    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09347    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09348    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09349    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09350    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09351    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09352    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09353 }

static void sched_delay_remove ( struct sockaddr_in *  sin,
struct callno_entry callno_entry 
) [static]

Definition at line 2704 of file chan_iax2.c.

References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), iax2_sched_add(), MIN_REUSE_TIME, OBJ_POINTER, peercnt_remove_cb(), peercnts, replace_callno(), and sched.

Referenced by pvt_destructor().

02705 {
02706    int i;
02707    struct peercnt *peercnt;
02708    struct peercnt tmp = {
02709       .addr = sin->sin_addr.s_addr,
02710    };
02711 
02712    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02713       /* refcount is incremented with ao2_find.  keep that ref for the scheduler */
02714       ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02715       i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02716       if (i == -1) {
02717          ao2_ref(peercnt, -1);
02718       }
02719    }
02720 
02721    iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02722 }

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

References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_channel_unlock, ast_codec_get_samples(), ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_samp2tv(), ast_sched_thread_del, ast_test_flag64, ast_tv(), ast_tvadd(), ast_tvzero(), ast_channel::bridge, calc_rxstamp(), iax_frame::callno, ast_frame_subclass::codec, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_lock_owner(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, sched, ast_frame::subclass, iax_frame::ts, unwrap_timestamp(), and update_jbsched().

Referenced by socket_process(), and socket_process_meta().

04134 {
04135    int type, len;
04136    int ret;
04137    int needfree = 0;
04138    struct ast_channel *owner = NULL;
04139    struct ast_channel *bridge = NULL;
04140    
04141    /* Attempt to recover wrapped timestamps */
04142    unwrap_timestamp(fr);
04143 
04144    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
04145    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04146       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04147    else {
04148 #if 0
04149       ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04150 #endif
04151       fr->af.delivery = ast_tv(0,0);
04152    }
04153 
04154    type = JB_TYPE_CONTROL;
04155    len = 0;
04156 
04157    if(fr->af.frametype == AST_FRAME_VOICE) {
04158       type = JB_TYPE_VOICE;
04159       len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000);
04160    } else if(fr->af.frametype == AST_FRAME_CNG) {
04161       type = JB_TYPE_SILENCE;
04162    }
04163 
04164    if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04165       if (tsout)
04166          *tsout = fr->ts;
04167       __do_deliver(fr);
04168       return -1;
04169    }
04170 
04171    iax2_lock_owner(fr->callno);
04172    if (!iaxs[fr->callno]) {
04173       /* The call dissappeared so discard this frame that we could not send. */
04174       iax2_frame_free(fr);
04175       return -1;
04176    }
04177    if ((owner = iaxs[fr->callno]->owner))
04178       bridge = ast_bridged_channel(owner);
04179 
04180    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
04181     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
04182    if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04183       jb_frame frame;
04184 
04185       ast_channel_unlock(owner);
04186 
04187       /* deliver any frames in the jb */
04188       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04189          __do_deliver(frame.data);
04190          /* __do_deliver() can make the call disappear */
04191          if (!iaxs[fr->callno])
04192             return -1;
04193       }
04194 
04195       jb_reset(iaxs[fr->callno]->jb);
04196 
04197       ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04198 
04199       /* deliver this frame now */
04200       if (tsout)
04201          *tsout = fr->ts;
04202       __do_deliver(fr);
04203       return -1;
04204    }
04205    if (owner) {
04206       ast_channel_unlock(owner);
04207    }
04208 
04209    /* insert into jitterbuffer */
04210    /* TODO: Perhaps we could act immediately if it's not droppable and late */
04211    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04212          calc_rxstamp(iaxs[fr->callno],fr->ts));
04213    if (ret == JB_DROP) {
04214       needfree++;
04215    } else if (ret == JB_SCHED) {
04216       update_jbsched(iaxs[fr->callno]);
04217    }
04218    if (tsout)
04219       *tsout = fr->ts;
04220    if (needfree) {
04221       /* Free our iax frame */
04222       iax2_frame_free(fr);
04223       return -1;
04224    }
04225    return 0;
04226 }

static int scheduled_destroy ( const void *  vid  )  [static]

Definition at line 1807 of file chan_iax2.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_destroy(), iaxs, iaxsl, LOG_DEBUG, option_debug, and PTR_TO_CALLNO.

Referenced by iax2_hangup().

01808 {
01809    unsigned short callno = PTR_TO_CALLNO(vid);
01810    ast_mutex_lock(&iaxsl[callno]);
01811    if (iaxs[callno]) {
01812       if (option_debug) {
01813          ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01814       }
01815       iax2_destroy(callno);
01816    }
01817    ast_mutex_unlock(&iaxsl[callno]);
01818    return 0;
01819 }

static int send_apathetic_reply ( unsigned short  callno,
unsigned short  dcallno,
struct sockaddr_in *  sin,
int  command,
int  ts,
unsigned char  seqno,
int  sockfd,
struct iax_ie_data ied 
) [static]

Definition at line 4683 of file chan_iax2.c.

References AST_FRAME_IAX, iax_ie_data::buf, compress_subclass(), f, and iax_ie_data::pos.

Referenced by handle_call_token(), and socket_process().

04686 {
04687    struct {
04688       struct ast_iax2_full_hdr f;
04689       struct iax_ie_data ied;
04690    } data;
04691    size_t size = sizeof(struct ast_iax2_full_hdr);
04692 
04693    if (ied) {
04694       size += ied->pos;
04695       memcpy(&data.ied, ied->buf, ied->pos);
04696    }
04697 
04698    data.f.scallno = htons(0x8000 | callno);
04699    data.f.dcallno = htons(dcallno);
04700    data.f.ts = htonl(ts);
04701    data.f.iseqno = seqno;
04702    data.f.oseqno = 0;
04703    data.f.type = AST_FRAME_IAX;
04704    data.f.csub = compress_subclass(command);
04705 
04706    return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04707 }

static int send_command ( struct chan_iax2_pvt ,
char  ,
int  ,
unsigned  int,
const unsigned char *  ,
int  ,
int   
) [static]

Definition at line 7449 of file chan_iax2.c.

References __send_command().

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

07450 {
07451    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07452 }

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

References __send_command(), chan_iax2_pvt::callno, iax2_predestroy(), and iaxs.

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

07469 {
07470    int call_num = i->callno;
07471    /* It is assumed that the callno has already been locked */
07472    iax2_predestroy(i->callno);
07473    if (!iaxs[call_num])
07474       return -1;
07475    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07476 }

static int send_command_immediate ( struct chan_iax2_pvt ,
char  ,
int  ,
unsigned  int,
const unsigned char *  ,
int  ,
int   
) [static]

Definition at line 7478 of file chan_iax2.c.

References __send_command().

Referenced by iax2_vnak(), and socket_process().

07479 {
07480    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07481 }

static int send_command_locked ( unsigned short  callno,
char  ,
int  ,
unsigned  int,
const unsigned char *  ,
int  ,
int   
) [static]

Definition at line 7454 of file chan_iax2.c.

References ast_mutex_lock, ast_mutex_unlock, iaxs, iaxsl, and send_command().

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

07455 {
07456    int res;
07457    ast_mutex_lock(&iaxsl[callno]);
07458    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07459    ast_mutex_unlock(&iaxsl[callno]);
07460    return res;
07461 }

static int send_command_transfer ( struct chan_iax2_pvt ,
char  ,
int  ,
unsigned  int,
const unsigned char *  ,
int   
) [static]

Definition at line 7483 of file chan_iax2.c.

References __send_command().

Referenced by socket_process(), and try_transfer().

07484 {
07485    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07486 }

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

Definition at line 1593 of file chan_iax2.c.

References __send_lagrq(), ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, iaxs, iaxsl, chan_iax2_pvt::lagid, and schedule_action.

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

01594 {
01595    int callno = (long) data;
01596    ast_mutex_lock(&iaxsl[callno]);
01597    if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) {
01598       iaxs[callno]->lagid = -1;
01599    }
01600    ast_mutex_unlock(&iaxsl[callno]);
01601 
01602 #ifdef SCHED_MULTITHREADED
01603    if (schedule_action(__send_lagrq, data))
01604 #endif
01605       __send_lagrq(data);
01606    return 0;
01607 }

static int send_packet ( struct iax_frame f  )  [static]

Definition at line 3313 of file chan_iax2.c.

References chan_iax2_pvt::addr, ast_debug, ast_inet_ntoa(), errno, f, handle_error(), iax_showframe(), iaxs, chan_iax2_pvt::peercallno, iax2_trunk_peer::sockfd, and chan_iax2_pvt::transfer.

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

03314 {
03315    int res;
03316    int callno = f->callno;
03317 
03318    /* Don't send if there was an error, but return error instead */
03319    if (!callno || !iaxs[callno] || iaxs[callno]->error)
03320        return -1;
03321    
03322    /* Called with iaxsl held */
03323    if (iaxdebug)
03324       ast_debug(3, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port));
03325    
03326    if (f->transfer) {
03327       if (iaxdebug)
03328          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03329       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03330    } else {
03331       if (iaxdebug)
03332          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03333       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03334    }
03335    if (res < 0) {
03336       if (iaxdebug)
03337          ast_debug(1, "Received error: %s\n", strerror(errno));
03338       handle_error();
03339    } else
03340       res = 0;
03341 
03342    return res;
03343 }

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

Definition at line 1526 of file chan_iax2.c.

References __send_ping(), ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, iaxs, iaxsl, chan_iax2_pvt::pingid, and schedule_action.

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

01527 {
01528    int callno = (long) data;
01529    ast_mutex_lock(&iaxsl[callno]);
01530    if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) {
01531       iaxs[callno]->pingid = -1;
01532    }
01533    ast_mutex_unlock(&iaxsl[callno]);
01534 
01535 #ifdef SCHED_MULTITHREADED
01536    if (schedule_action(__send_ping, data))
01537 #endif
01538       __send_ping(data);
01539 
01540    return 0;
01541 }

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

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

Referenced by socket_process().

01830 {
01831    struct signaling_queue_entry *s = NULL;
01832 
01833    while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01834       iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01835       free_signaling_queue_entry(s);
01836    }
01837    pvt->hold_signaling = 0;
01838 }

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

Definition at line 9058 of file chan_iax2.c.

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

Referenced by iax2_trunk_queue(), and timing_read().

09059 {
09060    int res = 0;
09061    struct iax_frame *fr;
09062    struct ast_iax2_meta_hdr *meta;
09063    struct ast_iax2_meta_trunk_hdr *mth;
09064    int calls = 0;
09065    
09066    /* Point to frame */
09067    fr = (struct iax_frame *)tpeer->trunkdata;
09068    /* Point to meta data */
09069    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09070    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09071    if (tpeer->trunkdatalen) {
09072       /* We're actually sending a frame, so fill the meta trunk header and meta header */
09073       meta->zeros = 0;
09074       meta->metacmd = IAX_META_TRUNK;
09075       if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09076          meta->cmddata = IAX_META_TRUNK_MINI;
09077       else
09078          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09079       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09080       /* And the rest of the ast_iax2 header */
09081       fr->direction = DIRECTION_OUTGRESS;
09082       fr->retrans = -1;
09083       fr->transfer = 0;
09084       /* Any appropriate call will do */
09085       fr->data = fr->afdata;
09086       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09087       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09088       calls = tpeer->calls;
09089 #if 0
09090       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));
09091 #endif      
09092       /* Reset transmit trunk side data */
09093       tpeer->trunkdatalen = 0;
09094       tpeer->calls = 0;
09095    }
09096    if (res < 0)
09097       return res;
09098    return calls;
09099 }

static int set_config ( const char *  config_file,
int  reload 
) [static]

Load configuration.

Definition at line 12906 of file chan_iax2.c.

References add_calltoken_ignore(), ao2_link, ast_category_browse(), ast_cdr_amaflags2int(), 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_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_test_flag64, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, build_callno_limits(), build_peer(), build_user(), capability, CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), globalflags, iax2_register(), IAX_ALLOWFWDOWNLOAD, 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_FORCEJITTERBUF, 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, iaxmaxthreadcount, iaxthreadcount, io, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_TRUNK_MTU, MAX_TRUNKDATA, ast_variable::name, netsock, network_change_event_subscribe(), network_change_event_unsubscribe(), ast_variable::next, outsock, peer_unref(), peers, prefs, qos, reg_source_db(), secret, set_config_destroy(), socket_read(), user, user_unref(), users, and ast_variable::value.

Referenced by load_module(), reload(), and reload_config().

12907 {
12908    struct ast_config *cfg, *ucfg;
12909    format_t capability = iax2_capability;
12910    struct ast_variable *v;
12911    char *cat;
12912    const char *utype;
12913    const char *tosval;
12914    int format;
12915    int portno = IAX_DEFAULT_PORTNO;
12916    int  x;
12917    int mtuv;
12918    int subscribe_network_change = 1;
12919    struct iax2_user *user;
12920    struct iax2_peer *peer;
12921    struct ast_netsock *ns;
12922    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
12923 #if 0
12924    static unsigned short int last_port=0;
12925 #endif
12926 
12927    cfg = ast_config_load(config_file, config_flags);
12928 
12929    if (!cfg) {
12930       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
12931       return -1;
12932    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
12933       ucfg = ast_config_load("users.conf", config_flags);
12934       if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
12935          return 0;
12936       /* Otherwise we need to reread both files */
12937       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12938       if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
12939          ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config_file);
12940          ast_config_destroy(ucfg);
12941          return 0;
12942       }
12943    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
12944       ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config_file);
12945       return 0;
12946    } else { /* iax.conf changed, gotta reread users.conf, too */
12947       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12948       if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
12949          ast_log(LOG_ERROR, "Config file users.conf is in an invalid format.  Aborting.\n");
12950          ast_config_destroy(cfg);
12951          return 0;
12952       }
12953    }
12954 
12955    if (reload) {
12956       set_config_destroy();
12957    }
12958 
12959    /* Reset global codec prefs */
12960    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
12961 
12962    /* Reset Global Flags */
12963    memset(&globalflags, 0, sizeof(globalflags));
12964    ast_set_flag64(&globalflags, IAX_RTUPDATE);
12965    ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
12966 
12967 #ifdef SO_NO_CHECK
12968    nochecksums = 0;
12969 #endif
12970    /* Reset default parking lot */
12971    default_parkinglot[0] = '\0';
12972 
12973    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12974    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12975    global_max_trunk_mtu = MAX_TRUNK_MTU;
12976    global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
12977    global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
12978 
12979    maxauthreq = 3;
12980 
12981    srvlookup = 0;
12982 
12983    v = ast_variable_browse(cfg, "general");
12984 
12985    /* Seed initial tos value */
12986    tosval = ast_variable_retrieve(cfg, "general", "tos");
12987    if (tosval) {
12988       if (ast_str2tos(tosval, &qos.tos))
12989          ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
12990    }
12991    /* Seed initial cos value */
12992    tosval = ast_variable_retrieve(cfg, "general", "cos");
12993    if (tosval) {
12994       if (ast_str2cos(tosval, &qos.cos))
12995          ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
12996    }
12997    while(v) {
12998       if (!strcasecmp(v->name, "bindport")){ 
12999          if (reload)
13000             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13001          else
13002             portno = atoi(v->value);
13003       } else if (!strcasecmp(v->name, "pingtime")) 
13004          ping_time = atoi(v->value);
13005       else if (!strcasecmp(v->name, "iaxthreadcount")) {
13006          if (reload) {
13007             if (atoi(v->value) != iaxthreadcount)
13008                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13009          } else {
13010             iaxthreadcount = atoi(v->value);
13011             if (iaxthreadcount < 1) {
13012                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13013                iaxthreadcount = 1;
13014             } else if (iaxthreadcount > 256) {
13015                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13016                iaxthreadcount = 256;
13017             }
13018          }
13019       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13020          if (reload) {
13021             AST_LIST_LOCK(&dynamic_list);
13022             iaxmaxthreadcount = atoi(v->value);
13023             AST_LIST_UNLOCK(&dynamic_list);
13024          } else {
13025             iaxmaxthreadcount = atoi(v->value);
13026             if (iaxmaxthreadcount < 0) {
13027                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13028                iaxmaxthreadcount = 0;
13029             } else if (iaxmaxthreadcount > 256) {
13030                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13031                iaxmaxthreadcount = 256;
13032             }
13033          }
13034       } else if (!strcasecmp(v->name, "nochecksums")) {
13035 #ifdef SO_NO_CHECK
13036          if (ast_true(v->value))
13037             nochecksums = 1;
13038          else
13039             nochecksums = 0;
13040 #else
13041          if (ast_true(v->value))
13042             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13043 #endif
13044       }
13045       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
13046          maxjitterbuffer = atoi(v->value);
13047       else if (!strcasecmp(v->name, "resyncthreshold")) 
13048          resyncthreshold = atoi(v->value);
13049       else if (!strcasecmp(v->name, "maxjitterinterps")) 
13050          maxjitterinterps = atoi(v->value);
13051       else if (!strcasecmp(v->name, "jittertargetextra"))
13052          jittertargetextra = atoi(v->value);
13053       else if (!strcasecmp(v->name, "lagrqtime")) 
13054          lagrq_time = atoi(v->value);
13055       else if (!strcasecmp(v->name, "maxregexpire")) 
13056          max_reg_expire = atoi(v->value);
13057       else if (!strcasecmp(v->name, "minregexpire")) 
13058          min_reg_expire = atoi(v->value);
13059       else if (!strcasecmp(v->name, "bindaddr")) {
13060          if (reload) {
13061             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13062          } else {
13063             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13064                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13065             } else {
13066                   if (strchr(v->value, ':'))
13067                   ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13068                   else
13069                   ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13070                if (defaultsockfd < 0) 
13071                   defaultsockfd = ast_netsock_sockfd(ns);
13072                ast_netsock_unref(ns);
13073             }
13074          }
13075       } else if (!strcasecmp(v->name, "authdebug")) {
13076          authdebug = ast_true(v->value);
13077       } else if (!strcasecmp(v->name, "encryption")) {
13078             iax2_encryption |= get_encrypt_methods(v->value);
13079             if (!iax2_encryption) {
13080                ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13081             }
13082       } else if (!strcasecmp(v->name, "forceencryption")) {
13083          if (ast_false(v->value)) {
13084             ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13085          } else {
13086             iax2_encryption |= get_encrypt_methods(v->value);
13087             if (iax2_encryption) {
13088                ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13089             }
13090          }
13091       } else if (!strcasecmp(v->name, "transfer")) {
13092          if (!strcasecmp(v->value, "mediaonly")) {
13093             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13094          } else if (ast_true(v->value)) {
13095             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13096          } else
13097             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13098       } else if (!strcasecmp(v->name, "codecpriority")) {
13099          if(!strcasecmp(v->value, "caller"))
13100             ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13101          else if(!strcasecmp(v->value, "disabled"))
13102             ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13103          else if(!strcasecmp(v->value, "reqonly")) {
13104             ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13105             ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13106          }
13107       } else if (!strcasecmp(v->name, "jitterbuffer"))
13108          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13109       else if (!strcasecmp(v->name, "forcejitterbuffer"))
13110          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13111       else if (!strcasecmp(v->name, "delayreject"))
13112          delayreject = ast_true(v->value);
13113       else if (!strcasecmp(v->name, "allowfwdownload"))
13114          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13115       else if (!strcasecmp(v->name, "rtcachefriends"))
13116          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13117       else if (!strcasecmp(v->name, "rtignoreregexpire"))
13118          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13119       else if (!strcasecmp(v->name, "rtupdate"))
13120          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13121       else if (!strcasecmp(v->name, "rtsavesysname"))
13122          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13123       else if (!strcasecmp(v->name, "trunktimestamps"))
13124          ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13125       else if (!strcasecmp(v->name, "rtautoclear")) {
13126          int i = atoi(v->value);
13127          if(i > 0)
13128             global_rtautoclear = i;
13129          else
13130             i = 0;
13131          ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13132       } else if (!strcasecmp(v->name, "trunkfreq")) {
13133          trunkfreq = atoi(v->value);
13134          if (trunkfreq < 10)
13135             trunkfreq = 10;
13136       } else if (!strcasecmp(v->name, "trunkmtu")) {
13137          mtuv = atoi(v->value);
13138          if (mtuv  == 0 )
13139             global_max_trunk_mtu = 0;
13140          else if (mtuv >= 172 && mtuv < 4000)
13141             global_max_trunk_mtu = mtuv;
13142          else
13143             ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13144                mtuv, v->lineno);
13145       } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13146          trunkmaxsize = atoi(v->value);
13147          if (trunkmaxsize == 0)
13148             trunkmaxsize = MAX_TRUNKDATA;
13149       } else if (!strcasecmp(v->name, "autokill")) {
13150          if (sscanf(v->value, "%30d", &x) == 1) {
13151             if (x >= 0)
13152                autokill = x;
13153             else
13154                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13155          } else if (ast_true(v->value)) {
13156             autokill = DEFAULT_MAXMS;
13157          } else {
13158             autokill = 0;
13159          }
13160       } else if (!strcasecmp(v->name, "bandwidth")) {
13161          if (!strcasecmp(v->value, "low")) {
13162             capability = IAX_CAPABILITY_LOWBANDWIDTH;
13163          } else if (!strcasecmp(v->value, "medium")) {
13164             capability = IAX_CAPABILITY_MEDBANDWIDTH;
13165          } else if (!strcasecmp(v->value, "high")) {
13166             capability = IAX_CAPABILITY_FULLBANDWIDTH;
13167          } else
13168             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13169       } else if (!strcasecmp(v->name, "allow")) {
13170          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13171       } else if (!strcasecmp(v->name, "disallow")) {
13172          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13173       } else if (!strcasecmp(v->name, "register")) {
13174          iax2_register(v->value, v->lineno);
13175       } else if (!strcasecmp(v->name, "iaxcompat")) {
13176          iaxcompat = ast_true(v->value);
13177       } else if (!strcasecmp(v->name, "regcontext")) {
13178          ast_copy_string(regcontext, v->value, sizeof(regcontext));
13179          /* Create context if it doesn't exist already */
13180          ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13181       } else if (!strcasecmp(v->name, "tos")) {
13182          if (ast_str2tos(v->value, &qos.tos))
13183             ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13184       } else if (!strcasecmp(v->name, "cos")) {
13185          if (ast_str2cos(v->value, &qos.cos))
13186             ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13187       } else if (!strcasecmp(v->name, "parkinglot")) {
13188          ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13189       } else if (!strcasecmp(v->name, "accountcode")) {
13190          ast_copy_string(accountcode, v->value, sizeof(accountcode));
13191       } else if (!strcasecmp(v->name, "mohinterpret")) {
13192          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13193       } else if (!strcasecmp(v->name, "mohsuggest")) {
13194          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13195       } else if (!strcasecmp(v->name, "amaflags")) {
13196          format = ast_cdr_amaflags2int(v->value);
13197          if (format < 0) {
13198             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13199          } else {
13200             amaflags = format;
13201          }
13202       } else if (!strcasecmp(v->name, "language")) {
13203          ast_copy_string(language, v->value, sizeof(language));
13204       } else if (!strcasecmp(v->name, "maxauthreq")) {
13205          maxauthreq = atoi(v->value);
13206          if (maxauthreq < 0)
13207             maxauthreq = 0;
13208       } else if (!strcasecmp(v->name, "adsi")) {
13209          adsi = ast_true(v->value);
13210       } else if (!strcasecmp(v->name, "srvlookup")) {
13211          srvlookup = ast_true(v->value);
13212       } else if (!strcasecmp(v->name, "connectedline")) {
13213          if (ast_true(v->value)) {
13214             ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13215          } else if (!strcasecmp(v->value, "send")) {
13216             ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13217             ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13218          } else if (!strcasecmp(v->value, "receive")) {
13219             ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13220             ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13221          } else {
13222             ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13223          }
13224       } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13225          if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13226             ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number.  %s is not valid at line %d\n", v->value, v->lineno);
13227          }
13228       } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13229          if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13230             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);
13231          }
13232       } else if (!strcasecmp(v->name, "calltokenoptional")) {
13233          if (add_calltoken_ignore(v->value)) {
13234             ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13235          }
13236       } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13237          if (ast_true(v->value)) {
13238             subscribe_network_change = 1;
13239          } else if (ast_false(v->value)) {
13240             subscribe_network_change = 0;
13241          } else {
13242             ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13243          }
13244       } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13245          if (ast_true(v->value)) {
13246             ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13247          } else if (ast_false(v->value)) {
13248             ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13249          } else {
13250             ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13251          }
13252       }/*else if (strcasecmp(v->name,"type")) */
13253       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13254       v = v->next;
13255    }
13256 
13257    if (subscribe_network_change) {
13258       network_change_event_subscribe();
13259    } else {
13260       network_change_event_unsubscribe();
13261    }
13262 
13263    if (defaultsockfd < 0) {
13264       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13265          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13266       } else {
13267          ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13268          defaultsockfd = ast_netsock_sockfd(ns);
13269          ast_netsock_unref(ns);
13270       }
13271    }
13272    if (reload) {
13273       ast_netsock_release(outsock);
13274       outsock = ast_netsock_list_alloc();
13275       if (!outsock) {
13276          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13277          return -1;
13278       }
13279       ast_netsock_init(outsock);
13280    }
13281 
13282    if (min_reg_expire > max_reg_expire) {
13283       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13284          min_reg_expire, max_reg_expire, max_reg_expire);
13285       min_reg_expire = max_reg_expire;
13286    }
13287    iax2_capability = capability;
13288    
13289    if (ucfg) {
13290       struct ast_variable *gen;
13291       int genhasiax;
13292       int genregisteriax;
13293       const char *hasiax, *registeriax;
13294       
13295       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13296       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13297       gen = ast_variable_browse(ucfg, "general");
13298       cat = ast_category_browse(ucfg, NULL);
13299       while (cat) {
13300          if (strcasecmp(cat, "general")) {
13301             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13302             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13303             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13304                /* Start with general parameters, then specific parameters, user and peer */
13305                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13306                if (user) {
13307                   ao2_link(users, user);
13308                   user = user_unref(user);
13309                }
13310                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13311                if (peer) {
13312                   if (ast_test_flag64(peer, IAX_DYNAMIC))
13313                      reg_source_db(peer);
13314                   ao2_link(peers, peer);
13315                   peer = peer_unref(peer);
13316                }
13317             }
13318             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13319                char tmp[256];
13320                const char *host = ast_variable_retrieve(ucfg, cat, "host");
13321                const char *username = ast_variable_retrieve(ucfg, cat, "username");
13322                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13323                if (!host)
13324                   host = ast_variable_retrieve(ucfg, "general", "host");
13325                if (!username)
13326                   username = ast_variable_retrieve(ucfg, "general", "username");
13327                if (!secret)
13328                   secret = ast_variable_retrieve(ucfg, "general", "secret");
13329                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13330                   if (!ast_strlen_zero(secret))
13331                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13332                   else
13333                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13334                   iax2_register(tmp, 0);
13335                }
13336             }
13337          }
13338          cat = ast_category_browse(ucfg, cat);
13339       }
13340       ast_config_destroy(ucfg);
13341    }
13342    
13343    cat = ast_category_browse(cfg, NULL);
13344    while(cat) {
13345       if (strcasecmp(cat, "general")) {
13346          utype = ast_variable_retrieve(cfg, cat, "type");
13347          if (!strcasecmp(cat, "callnumberlimits")) {
13348             build_callno_limits(ast_variable_browse(cfg, cat));
13349          } else if (utype) {
13350             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13351                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13352                if (user) {
13353                   ao2_link(users, user);
13354                   user = user_unref(user);
13355                }
13356             }
13357             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13358                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13359                if (peer) {
13360                   if (ast_test_flag64(peer, IAX_DYNAMIC))
13361                      reg_source_db(peer);
13362                   ao2_link(peers, peer);
13363                   peer = peer_unref(peer);
13364                }
13365             } else if (strcasecmp(utype, "user")) {
13366                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13367             }
13368          } else
13369             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13370       }
13371       cat = ast_category_browse(cfg, cat);
13372    }
13373    ast_config_destroy(cfg);
13374    return 1;
13375 }

static void set_config_destroy ( void   )  [static]

Definition at line 12889 of file chan_iax2.c.

References addr_range_delme_cb(), ao2_callback, ast_clear_flag64, callno_limits, calltoken_ignores, delete_users(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, MAX_TRUNKDATA, and OBJ_NODATA.

Referenced by set_config().

static void set_hangup_source_and_cause ( int  callno,
unsigned char  causecode 
) [static]

Definition at line 9780 of file chan_iax2.c.

References ast_channel_unlock, ast_set_hangupsource(), ast_channel::hangupcause, iax2_lock_owner(), iaxs, and chan_iax2_pvt::owner.

Referenced by socket_process().

09781 {
09782    iax2_lock_owner(callno);
09783    if (iaxs[callno] && iaxs[callno]->owner) {
09784       if (causecode) {
09785          iaxs[callno]->owner->hangupcause = causecode;
09786       }
09787       ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0);
09788       ast_channel_unlock(iaxs[callno]->owner);
09789    }
09790 }

static void set_peercnt_limit ( struct peercnt peercnt  )  [static]

Definition at line 2248 of file chan_iax2.c.

References peercnt::addr, addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), callno_limits, addr_range::limit, peercnt::limit, and peercnt::reg.

Referenced by peercnt_add(), peercnt_modify(), and set_peercnt_limit_all_cb().

02249 {
02250    uint16_t limit = global_maxcallno;
02251    struct addr_range *addr_range;
02252    struct sockaddr_in sin = {
02253       .sin_addr.s_addr = peercnt->addr,
02254    };
02255 
02256 
02257    if (peercnt->reg && peercnt->limit) {
02258       return; /* this peercnt has a custom limit set by a registration */
02259    }
02260 
02261    if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02262       limit = addr_range->limit;
02263       ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02264       ao2_ref(addr_range, -1);
02265    }
02266 
02267    peercnt->limit = limit;
02268 }

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

Definition at line 2274 of file chan_iax2.c.

References ast_debug, and set_peercnt_limit().

Referenced by reload_config().

02275 {
02276    struct peercnt *peercnt = obj;
02277 
02278    set_peercnt_limit(peercnt);
02279    ast_debug(1, "Reset limits for peercnts table\n");
02280 
02281    return 0;
02282 }

static void signal_condition ( ast_mutex_t lock,
ast_cond_t cond 
) [static]

Definition at line 1047 of file chan_iax2.c.

References ast_cond_signal, ast_mutex_lock, and ast_mutex_unlock.

Referenced by __schedule_action(), cleanup_thread_list(), iax2_process_thread(), and socket_read().

01048 {
01049    ast_mutex_lock(lock);
01050    ast_cond_signal(cond);
01051    ast_mutex_unlock(lock);
01052 }

static int socket_process ( struct iax2_thread thread  )  [static]

Definition at line 9792 of file chan_iax2.c.

References ast_aes_set_decrypt_key(), ast_async_goto(), ast_best_codec(), ast_bridged_channel(), ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_channel_datastore_add(), ast_channel_unlock, ast_clear_flag, ast_clear_flag64, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), ast_connected_line_parse_data(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, 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_getformatname(), ast_getformatname_multiple(), ast_iax2_new(), ast_inet_ntoa(), 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_manager_event, ast_mutex_lock, ast_mutex_unlock, ast_parking_ext_valid(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_id_presentation(), ast_sched_thread_del, ast_set_callerid(), ast_set_flag, ast_set_flag64, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, 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(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax_ies::called_number, chan_iax2_pvt::calling_pres, iax_ies::callno, iax2_peer::callno, iax2_dpcache::callno, chan_iax2_pvt::callno, iax_ies::calltoken, iax_ies::calltokendata, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, check_access(), check_provisioning(), cid_name, cid_num, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), connected, construct_rr(), ast_channel::context, context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, decrypt_frame(), iax_ies::devicetype, dp_lookup(), iax_ies::encmethods, ast_var_t::entries, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, format, frame_queue, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, globalflags, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_allow_new(), iax2_destroy(), iax2_dprequest(), iax2_lock_owner(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_variable_datastore_info, iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, 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_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_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, IAX_RECVCONNECTEDLINE, IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), iaxs, iaxsl, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event, iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, iax_ies::musiconhold, iax2_peer::name, ast_channel::name, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, iax_frame::oseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, iax_ies::provver, iax_ies::provverpres, raw_hangup(), iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rseqno, S_COR, S_OR, save_osptoken(), save_rr(), sched, schedule_delivery(), 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(), stop_stuff(), store_by_peercallno(), thread, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), iax_frame::ts, uncompress_subclass(), update_registry(), iax_ies::username, var, iax_ies::vars, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.

Referenced by handle_deferred_full_frames().

09793 {
09794    struct sockaddr_in sin;
09795    int res;
09796    int updatehistory=1;
09797    int new = NEW_PREVENT;
09798    int dcallno = 0;
09799    char decrypted = 0;
09800    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09801    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09802    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09803    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09804    struct iax_frame *fr;
09805    struct iax_frame *cur;
09806    struct ast_frame f = { 0, };
09807    struct ast_channel *c = NULL;
09808    struct iax2_dpcache *dp;
09809    struct iax2_peer *peer;
09810    struct iax_ies ies;
09811    struct iax_ie_data ied0, ied1;
09812    format_t format;
09813    int fd;
09814    int exists;
09815    int minivid = 0;
09816    char empty[32]="";      /* Safety measure */
09817    struct iax_frame *duped_fr;
09818    char host_pref_buf[128];
09819    char caller_pref_buf[128];
09820    struct ast_codec_pref pref;
09821    char *using_prefs = "mine";
09822 
09823    /* allocate an iax_frame with 4096 bytes of data buffer */
09824    fr = alloca(sizeof(*fr) + 4096);
09825    memset(fr, 0, sizeof(*fr));
09826    fr->afdatalen = 4096; /* From alloca() above */
09827 
09828    /* Copy frequently used parameters to the stack */
09829    res = thread->buf_len;
09830    fd = thread->iofd;
09831    memcpy(&sin, &thread->iosin, sizeof(sin));
09832 
09833    if (res < sizeof(*mh)) {
09834       ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09835       return 1;
09836    }
09837    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09838       if (res < sizeof(*vh)) {
09839          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
09840          return 1;
09841       }
09842 
09843       /* This is a video frame, get call number */
09844       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09845       minivid = 1;
09846    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09847       return socket_process_meta(res, meta, &sin, fd, fr);
09848 
09849 #ifdef DEBUG_SUPPORT
09850    if (res >= sizeof(*fh))
09851       iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09852 #endif
09853    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09854       if (res < sizeof(*fh)) {
09855          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
09856          return 1;
09857       }
09858 
09859       /* Get the destination call number */
09860       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09861 
09862 
09863       /* check to make sure this full frame isn't encrypted before we attempt
09864        * to look inside of it. If it is encrypted, decrypt it first. Its ok if the
09865        * callno is not found here, that just means one hasn't been allocated for
09866        * this connection yet. */
09867       if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09868          ast_mutex_lock(&iaxsl[fr->callno]);
09869          if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
09870             if (decrypt_frame(fr->callno, fh, &f, &res)) {
09871                ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09872                ast_mutex_unlock(&iaxsl[fr->callno]);
09873                return 1;
09874             }
09875             decrypted = 1;
09876          }
09877          ast_mutex_unlock(&iaxsl[fr->callno]);
09878       }
09879 
09880       /* Retrieve the type and subclass */
09881       f.frametype = fh->type;
09882       if (f.frametype == AST_FRAME_VIDEO) {
09883          f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09884       } else if (f.frametype == AST_FRAME_VOICE) {
09885          f.subclass.codec = uncompress_subclass(fh->csub);
09886       } else {
09887          f.subclass.integer = uncompress_subclass(fh->csub);
09888       }
09889 
09890       /* Deal with POKE/PONG without allocating a callno */
09891       if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
09892          /* Reply back with a PONG, but don't care about the result. */
09893          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09894          return 1;
09895       } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
09896          /* Ignore */
09897          return 1;
09898       }
09899 
09900       f.datalen = res - sizeof(*fh);
09901       if (f.datalen) {
09902          if (f.frametype == AST_FRAME_IAX) {
09903             if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09904                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09905                ast_variables_destroy(ies.vars);
09906                return 1;
09907             }
09908             f.data.ptr = NULL;
09909             f.datalen = 0;
09910          } else {
09911             f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09912             memset(&ies, 0, sizeof(ies));
09913          }
09914       } else {
09915          if (f.frametype == AST_FRAME_IAX)
09916             f.data.ptr = NULL;
09917          else
09918             f.data.ptr = empty;
09919          memset(&ies, 0, sizeof(ies));
09920       }
09921 
09922       if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
09923          /* only set NEW_ALLOW if calltoken checks out */
09924          if (handle_call_token(fh, &ies, &sin, fd)) {
09925             ast_variables_destroy(ies.vars);
09926             return 1;
09927          }
09928 
09929          if (ies.calltoken && ies.calltokendata) {
09930             /* if we've gotten this far, and the calltoken ie data exists,
09931              * then calltoken validation _MUST_ have taken place.  If calltoken
09932              * data is provided, it is always validated reguardless of any
09933              * calltokenoptional or requirecalltoken options */
09934             new = NEW_ALLOW_CALLTOKEN_VALIDATED;
09935          } else {
09936             new = NEW_ALLOW;
09937          }
09938       }
09939    } else {
09940       /* Don't know anything about it yet */
09941       f.frametype = AST_FRAME_NULL;
09942       f.subclass.integer = 0;
09943       memset(&ies, 0, sizeof(ies));
09944    }
09945 
09946    if (!fr->callno) {
09947       int check_dcallno = 0;
09948 
09949       /*
09950        * We enforce accurate destination call numbers for ACKs.  This forces the other
09951        * end to know the destination call number before call setup can complete.
09952        *
09953        * Discussed in the following thread:
09954        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
09955        */
09956 
09957       if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
09958          check_dcallno = 1;
09959       }
09960 
09961       if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
09962          if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
09963             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09964          } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
09965             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09966          }
09967          ast_variables_destroy(ies.vars);
09968          return 1;
09969       }
09970    }
09971 
09972    if (fr->callno > 0)
09973       ast_mutex_lock(&iaxsl[fr->callno]);
09974 
09975    if (!fr->callno || !iaxs[fr->callno]) {
09976       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
09977          frame, reply with an inval */
09978       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09979          /* We can only raw hangup control frames */
09980          if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
09981              (f.subclass.integer != IAX_COMMAND_TXCNT) &&
09982              (f.subclass.integer != IAX_COMMAND_TXACC) &&
09983              (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
09984              (f.frametype != AST_FRAME_IAX))
09985             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
09986             fd);
09987       }
09988       if (fr->callno > 0) 
09989          ast_mutex_unlock(&iaxsl[fr->callno]);
09990       ast_variables_destroy(ies.vars);
09991       return 1;
09992    }
09993    if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
09994       if (decrypt_frame(fr->callno, fh, &f, &res)) {
09995          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09996          ast_variables_destroy(ies.vars);
09997          ast_mutex_unlock(&iaxsl[fr->callno]);
09998          return 1;
09999       }
10000       decrypted = 1;
10001    }
10002 
10003 #ifdef DEBUG_SUPPORT
10004    if (decrypted) {
10005       iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10006    }
10007 #endif
10008 
10009 
10010    /* count this frame */
10011    iaxs[fr->callno]->frames_received++;
10012 
10013    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10014       f.subclass.integer != IAX_COMMAND_TXCNT &&      /* for attended transfer */
10015       f.subclass.integer != IAX_COMMAND_TXACC) {      /* for attended transfer */
10016       unsigned short new_peercallno;
10017       
10018       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10019       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10020          if (iaxs[fr->callno]->peercallno) {
10021             remove_by_peercallno(iaxs[fr->callno]);
10022          }
10023          iaxs[fr->callno]->peercallno = new_peercallno;
10024          store_by_peercallno(iaxs[fr->callno]);
10025       }
10026    }
10027    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10028       if (iaxdebug)
10029          ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10030       /* Check if it's out of order (and not an ACK or INVAL) */
10031       fr->oseqno = fh->oseqno;
10032       fr->iseqno = fh->iseqno;
10033       fr->ts = ntohl(fh->ts);
10034 #ifdef IAXTESTS
10035       if (test_resync) {
10036          ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10037          fr->ts += test_resync;
10038       }
10039 #endif /* IAXTESTS */
10040 #if 0
10041       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10042            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10043                         (f.subclass == IAX_COMMAND_NEW ||
10044                          f.subclass == IAX_COMMAND_AUTHREQ ||
10045                          f.subclass == IAX_COMMAND_ACCEPT ||
10046                          f.subclass == IAX_COMMAND_REJECT))      ) )
10047 #endif
10048       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10049          updatehistory = 0;
10050       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10051          (iaxs[fr->callno]->iseqno ||
10052             ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10053             (f.subclass.integer != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
10054             (f.subclass.integer != IAX_COMMAND_TXREL) &&    /* for attended transfer */
10055             (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
10056             (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10057             (f.frametype != AST_FRAME_IAX))) {
10058          if (
10059           ((f.subclass.integer != IAX_COMMAND_ACK) &&
10060            (f.subclass.integer != IAX_COMMAND_INVAL) &&
10061            (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10062            (f.subclass.integer != IAX_COMMAND_TXREADY) &&      /* for attended transfer */
10063            (f.subclass.integer != IAX_COMMAND_TXREL) &&     /* for attended transfer */
10064            (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
10065            (f.subclass.integer != IAX_COMMAND_TXACC) &&
10066            (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10067            (f.frametype != AST_FRAME_IAX)) {
10068             /* If it's not an ACK packet, it's out of order. */
10069             ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
10070                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10071             /* Check to see if we need to request retransmission,
10072              * and take sequence number wraparound into account */
10073             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10074                /* If we've already seen it, ack it XXX There's a border condition here XXX */
10075                if ((f.frametype != AST_FRAME_IAX) || 
10076                      ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10077                   ast_debug(1, "Acking anyway\n");
10078                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
10079                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
10080                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10081                }
10082             } else {
10083                /* Send a VNAK requesting retransmission */
10084                iax2_vnak(fr->callno);
10085             }
10086             ast_variables_destroy(ies.vars);
10087             ast_mutex_unlock(&iaxsl[fr->callno]);
10088             return 1;
10089          }
10090       } else {
10091          /* Increment unless it's an ACK or VNAK */
10092          if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10093              (f.subclass.integer != IAX_COMMAND_INVAL) &&
10094              (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10095              (f.subclass.integer != IAX_COMMAND_TXACC) &&
10096             (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10097              (f.frametype != AST_FRAME_IAX))
10098             iaxs[fr->callno]->iseqno++;
10099       }
10100       /* Ensure text frames are NULL-terminated */
10101       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10102          if (res < thread->buf_size)
10103             thread->buf[res++] = '\0';
10104          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
10105             thread->buf[res - 1] = '\0';
10106       }
10107 
10108       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
10109          from the real peer, not the transfer peer */
10110       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
10111           ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10112            (f.frametype != AST_FRAME_IAX))) {
10113          unsigned char x;
10114          int call_to_destroy;
10115          /* First we have to qualify that the ACKed value is within our window */
10116          if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10117             x = fr->iseqno;
10118          else 
10119             x = iaxs[fr->callno]->oseqno;
10120          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10121             /* The acknowledgement is within our window.  Time to acknowledge everything
10122                that it says to */
10123             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10124                /* Ack the packet with the given timestamp */
10125                if (iaxdebug)
10126                   ast_debug(1, "Cancelling transmission of packet %d\n", x);
10127                call_to_destroy = 0;
10128                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10129                   /* If it's our call, and our timestamp, mark -1 retries */
10130                   if (x == cur->oseqno) {
10131                      cur->retries = -1;
10132                      /* Destroy call if this is the end */
10133                      if (cur->final)
10134                         call_to_destroy = fr->callno;
10135                   }
10136                }
10137                if (call_to_destroy) {
10138                   if (iaxdebug)
10139                      ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10140                   ast_mutex_lock(&iaxsl[call_to_destroy]);
10141                   iax2_destroy(call_to_destroy);
10142                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
10143                }
10144             }
10145             /* Note how much we've received acknowledgement for */
10146             if (iaxs[fr->callno])
10147                iaxs[fr->callno]->rseqno = fr->iseqno;
10148             else {
10149                /* Stop processing now */
10150                ast_variables_destroy(ies.vars);
10151                ast_mutex_unlock(&iaxsl[fr->callno]);
10152                return 1;
10153             }
10154          } else {
10155             ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10156          }
10157       }
10158       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
10159          ((f.frametype != AST_FRAME_IAX) || 
10160           ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10161            (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10162          /* Only messages we accept from a transfer host are TXACC and TXCNT */
10163          ast_variables_destroy(ies.vars);
10164          ast_mutex_unlock(&iaxsl[fr->callno]);
10165          return 1;
10166       }
10167 
10168       /* when we receive the first full frame for a new incoming channel,
10169          it is safe to start the PBX on the channel because we have now
10170          completed a 3-way handshake with the peer */
10171       if ((f.frametype == AST_FRAME_VOICE) ||
10172           (f.frametype == AST_FRAME_VIDEO) ||
10173           (f.frametype == AST_FRAME_IAX)) {
10174          if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10175             ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10176             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
10177                ast_variables_destroy(ies.vars);
10178                ast_mutex_unlock(&iaxsl[fr->callno]);
10179                return 1;
10180             }
10181          }
10182 
10183          if (ies.vars) {
10184             struct ast_datastore *variablestore = NULL;
10185             struct ast_variable *var, *prev = NULL;
10186             AST_LIST_HEAD(, ast_var_t) *varlist;
10187 
10188             iax2_lock_owner(fr->callno);
10189             if (!iaxs[fr->callno]) {
10190                ast_variables_destroy(ies.vars);
10191                ast_mutex_unlock(&iaxsl[fr->callno]);
10192                return 1;
10193             }
10194             if ((c = iaxs[fr->callno]->owner)) {
10195                varlist = ast_calloc(1, sizeof(*varlist));
10196                variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10197 
10198                if (variablestore && varlist) {
10199                   variablestore->data = varlist;
10200                   variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10201                   AST_LIST_HEAD_INIT(varlist);
10202                   ast_debug(1, "I can haz IAX vars?\n");
10203                   for (var = ies.vars; var; var = var->next) {
10204                      struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10205                      if (prev) {
10206                         ast_free(prev);
10207                      }
10208                      prev = var;
10209                      if (!newvar) {
10210                         /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
10211                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10212                      } else {
10213                         AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10214                      }
10215                   }
10216                   if (prev) {
10217                      ast_free(prev);
10218                   }
10219                   ies.vars = NULL;
10220                   ast_channel_datastore_add(c, variablestore);
10221                } else {
10222                   ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10223                   if (variablestore) {
10224                      ast_datastore_free(variablestore);
10225                   }
10226                   if (varlist) {
10227                      ast_free(varlist);
10228                   }
10229                }
10230                ast_channel_unlock(c);
10231             } else {
10232                /* No channel yet, so transfer the variables directly over to the pvt,
10233                 * for later inheritance. */
10234                ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10235                for (var = ies.vars; var && var->next; var = var->next);
10236                if (var) {
10237                   var->next = iaxs[fr->callno]->iaxvars;
10238                   iaxs[fr->callno]->iaxvars = ies.vars;
10239                   ies.vars = NULL;
10240                }
10241             }
10242          }
10243 
10244          if (ies.vars) {
10245             ast_debug(1, "I have IAX variables, but they were not processed\n");
10246          }
10247       }
10248 
10249       /* once we receive our first IAX Full Frame that is not CallToken related, send all
10250        * queued signaling frames that were being held. */
10251       if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10252          send_signaling(iaxs[fr->callno]);
10253       }
10254 
10255       if (f.frametype == AST_FRAME_VOICE) {
10256          if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10257                iaxs[fr->callno]->voiceformat = f.subclass.codec;
10258                ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10259                if (iaxs[fr->callno]->owner) {
10260                   iax2_lock_owner(fr->callno);
10261                   if (iaxs[fr->callno]) {
10262                      if (iaxs[fr->callno]->owner) {
10263                         format_t orignative;
10264 
10265                         orignative = iaxs[fr->callno]->owner->nativeformats;
10266                         iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10267                         if (iaxs[fr->callno]->owner->readformat)
10268                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10269                         iaxs[fr->callno]->owner->nativeformats = orignative;
10270                         ast_channel_unlock(iaxs[fr->callno]->owner);
10271                      }
10272                   } else {
10273                      ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10274                      /* Free remote variables (if any) */
10275                      if (ies.vars) {
10276                         ast_variables_destroy(ies.vars);
10277                         ast_debug(1, "I can haz iaxvars, but they is no good.  :-(\n");
10278                         ies.vars = NULL;
10279                      }
10280                      ast_mutex_unlock(&iaxsl[fr->callno]);
10281                      return 1;
10282                   }
10283                }
10284          }
10285       }
10286       if (f.frametype == AST_FRAME_VIDEO) {
10287          if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10288             ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10289             iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10290          }
10291       }
10292       if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10293          if (f.subclass.integer == AST_CONTROL_BUSY) {
10294             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10295          } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
10296             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10297          }
10298       }
10299       if (f.frametype == AST_FRAME_IAX) {
10300          ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10301          /* Handle the IAX pseudo frame itself */
10302          if (iaxdebug)
10303             ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10304 
10305                         /* Update last ts unless the frame's timestamp originated with us. */
10306          if (iaxs[fr->callno]->last < fr->ts &&
10307                             f.subclass.integer != IAX_COMMAND_ACK &&
10308                             f.subclass.integer != IAX_COMMAND_PONG &&
10309                             f.subclass.integer != IAX_COMMAND_LAGRP) {
10310             iaxs[fr->callno]->last = fr->ts;
10311             if (iaxdebug)
10312                ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10313          }
10314          iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10315          if (!iaxs[fr->callno]->first_iax_message) {
10316             iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10317          }
10318          switch(f.subclass.integer) {
10319          case IAX_COMMAND_ACK:
10320             /* Do nothing */
10321             break;
10322          case IAX_COMMAND_QUELCH:
10323             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10324                     /* Generate Manager Hold event, if necessary*/
10325                if (iaxs[fr->callno]->owner) {
10326                   ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10327                      "Status: On\r\n"
10328                      "Channel: %s\r\n"
10329                      "Uniqueid: %s\r\n",
10330                      iaxs[fr->callno]->owner->name,
10331                      iaxs[fr->callno]->owner->uniqueid);
10332                }
10333 
10334                ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10335                if (ies.musiconhold) {
10336                   iax2_lock_owner(fr->callno);
10337                   if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10338                      break;
10339                   }
10340                   if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10341                      const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10342 
10343                      /*
10344                       * We already hold the owner lock so we do not
10345                       * need to check iaxs[fr->callno] after it returns.
10346                       */
10347                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
10348                         S_OR(moh_suggest, NULL),
10349                         !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10350                   }
10351                   ast_channel_unlock(iaxs[fr->callno]->owner);
10352                }
10353             }
10354             break;
10355          case IAX_COMMAND_UNQUELCH:
10356             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10357                iax2_lock_owner(fr->callno);
10358                if (!iaxs[fr->callno]) {
10359                   break;
10360                }
10361                /* Generate Manager Unhold event, if necessary */
10362                if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10363                   ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10364                      "Status: Off\r\n"
10365                      "Channel: %s\r\n"
10366                      "Uniqueid: %s\r\n",
10367                      iaxs[fr->callno]->owner->name,
10368                      iaxs[fr->callno]->owner->uniqueid);
10369                }
10370 
10371                ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10372                if (!iaxs[fr->callno]->owner) {
10373                   break;
10374                }
10375                if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10376                   /*
10377                    * We already hold the owner lock so we do not
10378                    * need to check iaxs[fr->callno] after it returns.
10379                    */
10380                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10381                }
10382                ast_channel_unlock(iaxs[fr->callno]->owner);
10383             }
10384             break;
10385          case IAX_COMMAND_TXACC:
10386             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10387                /* Ack the packet with the given timestamp */
10388                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10389                   /* Cancel any outstanding txcnt's */
10390                   if (cur->transfer) {
10391                      cur->retries = -1;
10392                   }
10393                }
10394                memset(&ied1, 0, sizeof(ied1));
10395                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10396                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10397                iaxs[fr->callno]->transferring = TRANSFER_READY;
10398             }
10399             break;
10400          case IAX_COMMAND_NEW:
10401             /* Ignore if it's already up */
10402             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10403                break;
10404             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10405                ast_mutex_unlock(&iaxsl[fr->callno]);
10406                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10407                ast_mutex_lock(&iaxsl[fr->callno]);
10408                if (!iaxs[fr->callno]) {
10409                   break;
10410                }
10411             }
10412             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
10413             if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10414                int new_callno;
10415                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10416                   fr->callno = new_callno;
10417             }
10418             /* For security, always ack immediately */
10419             if (delayreject)
10420                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10421             if (check_access(fr->callno, &sin, &ies)) {
10422                /* They're not allowed on */
10423                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10424                if (authdebug)
10425                   ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
10426                break;
10427             }
10428             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10429                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10430                ast_log(LOG_WARNING, "Rejected connect attempt.  No secret present while force encrypt enabled.\n");
10431                break;
10432             }
10433             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10434                const char *context, *exten, *cid_num;
10435 
10436                context = ast_strdupa(iaxs[fr->callno]->context);
10437                exten = ast_strdupa(iaxs[fr->callno]->exten);
10438                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10439 
10440                /* This might re-enter the IAX code and need the lock */
10441                ast_mutex_unlock(&iaxsl[fr->callno]);
10442                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10443                ast_mutex_lock(&iaxsl[fr->callno]);
10444 
10445                if (!iaxs[fr->callno]) {
10446                   break;
10447                }
10448             } else
10449                exists = 0;
10450             /* Get OSP token if it does exist */
10451             save_osptoken(fr, &ies);
10452             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10453                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10454                   memset(&ied0, 0, sizeof(ied0));
10455                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10456                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10457                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10458                   if (!iaxs[fr->callno]) {
10459                      break;
10460                   }
10461                   if (authdebug)
10462                      ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
10463                } else {
10464                   /* Select an appropriate format */
10465 
10466                   if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10467                      if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10468                         using_prefs = "reqonly";
10469                      } else {
10470                         using_prefs = "disabled";
10471                      }
10472                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10473                      memset(&pref, 0, sizeof(pref));
10474                      strcpy(caller_pref_buf, "disabled");
10475                      strcpy(host_pref_buf, "disabled");
10476                   } else {
10477                      using_prefs = "mine";
10478                      /* If the information elements are in here... use them */
10479                      if (ies.codec_prefs)
10480                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10481                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10482                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
10483                         if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10484                            pref = iaxs[fr->callno]->rprefs;
10485                            using_prefs = "caller";
10486                         } else {
10487                            pref = iaxs[fr->callno]->prefs;
10488                         }
10489                      } else
10490                         pref = iaxs[fr->callno]->prefs;
10491 
10492                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10493                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10494                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10495                   }
10496                   if (!format) {
10497                      if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10498                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10499                      if (!format) {
10500                         memset(&ied0, 0, sizeof(ied0));
10501                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10502                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10503                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10504                         if (!iaxs[fr->callno]) {
10505                            break;
10506                         }
10507                         if (authdebug) {
10508                            char tmp[256], tmp2[256], tmp3[256];
10509                            if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10510                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10511                                  ast_inet_ntoa(sin.sin_addr),
10512                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10513                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10514                            } else {
10515                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10516                                  ast_inet_ntoa(sin.sin_addr),
10517                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10518                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10519                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10520                            }
10521                         }
10522                      } else {
10523                         /* Pick one... */
10524                         if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10525                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10526                               format = 0;
10527                         } else {
10528                            if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10529                               using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10530                               memset(&pref, 0, sizeof(pref));
10531                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10532                               strcpy(caller_pref_buf,"disabled");
10533                               strcpy(host_pref_buf,"disabled");
10534                            } else {
10535                               using_prefs = "mine";
10536                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10537                                  /* Do the opposite of what we tried above. */
10538                                  if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10539                                     pref = iaxs[fr->callno]->prefs;
10540                                  } else {
10541                                     pref = iaxs[fr->callno]->rprefs;
10542                                     using_prefs = "caller";
10543                                  }
10544                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10545                               } else /* if no codec_prefs IE do it the old way */
10546                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10547                            }
10548                         }
10549 
10550                         if (!format) {
10551                            char tmp[256], tmp2[256], tmp3[256];
10552                            memset(&ied0, 0, sizeof(ied0));
10553                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10554                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10555                            ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10556                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10557                            if (!iaxs[fr->callno]) {
10558                               break;
10559                            }
10560                            if (authdebug) {
10561                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10562                                  ast_inet_ntoa(sin.sin_addr),
10563                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10564                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10565                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10566                            }
10567                            ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10568                            break;
10569                         }
10570                      }
10571                   }
10572                   if (format) {
10573                      /* No authentication required, let them in */
10574                      memset(&ied1, 0, sizeof(ied1));
10575                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10576                      iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10577                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10578                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10579                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10580                         ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10581                                     "%srequested format = %s,\n"
10582                                     "%srequested prefs = %s,\n"
10583                                     "%sactual format = %s,\n"
10584                                     "%shost prefs = %s,\n"
10585                                     "%spriority = %s\n",
10586                                     ast_inet_ntoa(sin.sin_addr), 
10587                                     VERBOSE_PREFIX_4,
10588                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
10589                                     VERBOSE_PREFIX_4,
10590                                     caller_pref_buf,
10591                                     VERBOSE_PREFIX_4,
10592                                     ast_getformatname(format), 
10593                                     VERBOSE_PREFIX_4,
10594                                     host_pref_buf, 
10595                                     VERBOSE_PREFIX_4,
10596                                     using_prefs);
10597 
10598                         iaxs[fr->callno]->chosenformat = format;
10599                         ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10600                      } else {
10601                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10602                         /* If this is a TBD call, we're ready but now what...  */
10603                         ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10604                      }
10605                   }
10606                }
10607                break;
10608             }
10609             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10610                merge_encryption(iaxs[fr->callno],ies.encmethods);
10611             else
10612                iaxs[fr->callno]->encmethods = 0;
10613             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10614                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10615             break;
10616          case IAX_COMMAND_DPREQ:
10617             /* Request status in the dialplan */
10618             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10619                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10620                if (iaxcompat) {
10621                   /* Spawn a thread for the lookup */
10622                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10623                } else {
10624                   /* Just look it up */
10625                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10626                }
10627             }
10628             break;
10629          case IAX_COMMAND_HANGUP:
10630             ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10631             ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10632             /* Set hangup cause according to remote and hangupsource */
10633             if (iaxs[fr->callno]->owner) {
10634                set_hangup_source_and_cause(fr->callno, ies.causecode);
10635                if (!iaxs[fr->callno]) {
10636                   break;
10637                }
10638             }
10639 
10640             /* Send ack immediately, before we destroy */
10641             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10642             iax2_destroy(fr->callno);
10643             break;
10644          case IAX_COMMAND_REJECT:
10645             /* Set hangup cause according to remote and hangup source */
10646             if (iaxs[fr->callno]->owner) {
10647                set_hangup_source_and_cause(fr->callno, ies.causecode);
10648                if (!iaxs[fr->callno]) {
10649                   break;
10650                }
10651             }
10652 
10653             if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10654                if (iaxs[fr->callno]->owner && authdebug)
10655                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10656                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10657                      ies.cause ? ies.cause : "<Unknown>");
10658                ast_debug(1, "Immediately destroying %d, having received reject\n",
10659                   fr->callno);
10660             }
10661             /* Send ack immediately, before we destroy */
10662             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10663                          fr->ts, NULL, 0, fr->iseqno);
10664             if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10665                iaxs[fr->callno]->error = EPERM;
10666             iax2_destroy(fr->callno);
10667             break;
10668          case IAX_COMMAND_TRANSFER:
10669          {
10670             struct ast_channel *bridged_chan;
10671             struct ast_channel *owner;
10672 
10673             iax2_lock_owner(fr->callno);
10674             if (!iaxs[fr->callno]) {
10675                /* Initiating call went away before we could transfer. */
10676                break;
10677             }
10678             owner = iaxs[fr->callno]->owner;
10679             bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10680             if (bridged_chan && ies.called_number) {
10681                ast_mutex_unlock(&iaxsl[fr->callno]);
10682 
10683                /* Set BLINDTRANSFER channel variables */
10684                pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10685                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10686 
10687                if (ast_parking_ext_valid(ies.called_number, c, iaxs[fr->callno]->context)) {
10688                   ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10689                   if (iax_park(bridged_chan, owner, ies.called_number)) {
10690                      ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10691                         bridged_chan->name);
10692                   }
10693                   ast_mutex_lock(&iaxsl[fr->callno]);
10694                } else {
10695                   ast_mutex_lock(&iaxsl[fr->callno]);
10696 
10697                   if (iaxs[fr->callno]) {
10698                      if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context,
10699                         ies.called_number, 1)) {
10700                         ast_log(LOG_WARNING,
10701                            "Async goto of '%s' to '%s@%s' failed\n",
10702                            bridged_chan->name, ies.called_number,
10703                            iaxs[fr->callno]->context);
10704                      } else {
10705                         ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10706                            bridged_chan->name, ies.called_number,
10707                            iaxs[fr->callno]->context);
10708                      }
10709                   } else {
10710                      /* Initiating call went away before we could transfer. */
10711                   }
10712                }
10713             } else {
10714                ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10715             }
10716             if (owner) {
10717                ast_channel_unlock(owner);
10718             }
10719 
10720             break;
10721          }
10722          case IAX_COMMAND_ACCEPT:
10723             /* Ignore if call is already up or needs authentication or is a TBD */
10724             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10725                break;
10726             if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10727                /* Send ack immediately, before we destroy */
10728                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10729                iax2_destroy(fr->callno);
10730                break;
10731             }
10732             if (ies.format) {
10733                iaxs[fr->callno]->peerformat = ies.format;
10734             } else {
10735                if (iaxs[fr->callno]->owner)
10736                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10737                else
10738                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10739             }
10740             ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
10741             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10742                memset(&ied0, 0, sizeof(ied0));
10743                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10744                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10745                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10746                if (!iaxs[fr->callno]) {
10747                   break;
10748                }
10749                if (authdebug) {
10750                   char tmp1[256], tmp2[256];
10751                   ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
10752                      ast_inet_ntoa(sin.sin_addr),
10753                      ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10754                      ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10755                }
10756             } else {
10757                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10758                iax2_lock_owner(fr->callno);
10759                if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10760                   /* Switch us to use a compatible format */
10761                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10762                   ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10763 
10764                   /* Setup read/write formats properly. */
10765                   if (iaxs[fr->callno]->owner->writeformat)
10766                      ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
10767                   if (iaxs[fr->callno]->owner->readformat)
10768                      ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
10769                   ast_channel_unlock(iaxs[fr->callno]->owner);
10770                }
10771             }
10772             if (iaxs[fr->callno]) {
10773                AST_LIST_LOCK(&dpcache);
10774                AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10775                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10776                      iax2_dprequest(dp, fr->callno);
10777                AST_LIST_UNLOCK(&dpcache);
10778             }
10779             break;
10780          case IAX_COMMAND_POKE:
10781             /* Send back a pong packet with the original timestamp */
10782             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10783             break;
10784          case IAX_COMMAND_PING:
10785          {
10786             struct iax_ie_data pingied;
10787             construct_rr(iaxs[fr->callno], &pingied);
10788             /* Send back a pong packet with the original timestamp */
10789             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10790          }
10791             break;
10792          case IAX_COMMAND_PONG:
10793             /* Calculate ping time */
10794             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10795             /* save RR info */
10796             save_rr(fr, &ies);
10797 
10798             /* Good time to write jb stats for this call */
10799             log_jitterstats(fr->callno);
10800 
10801             if (iaxs[fr->callno]->peerpoke) {
10802                peer = iaxs[fr->callno]->peerpoke;
10803                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
10804                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10805                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10806                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
10807                      ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */
10808                   }
10809                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10810                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
10811                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10812                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
10813                      ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
10814                   }
10815                }
10816                peer->lastms = iaxs[fr->callno]->pingtime;
10817                if (peer->smoothing && (peer->lastms > -1))
10818                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10819                else if (peer->smoothing && peer->lastms < 0)
10820                   peer->historicms = (0 + peer->historicms) / 2;
10821                else              
10822                   peer->historicms = iaxs[fr->callno]->pingtime;
10823 
10824                /* Remove scheduled iax2_poke_noanswer */
10825                if (peer->pokeexpire > -1) {
10826                   if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10827                      peer_unref(peer);
10828                      peer->pokeexpire = -1;
10829                   }
10830                }
10831                /* Schedule the next cycle */
10832                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
10833                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10834                else
10835                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10836                if (peer->pokeexpire == -1)
10837                   peer_unref(peer);
10838                /* and finally send the ack */
10839                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10840                /* And wrap up the qualify call */
10841                iax2_destroy(fr->callno);
10842                peer->callno = 0;
10843                ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10844             }
10845             break;
10846          case IAX_COMMAND_LAGRQ:
10847          case IAX_COMMAND_LAGRP:
10848             f.src = "LAGRQ";
10849             f.mallocd = 0;
10850             f.offset = 0;
10851             f.samples = 0;
10852             iax_frame_wrap(fr, &f);
10853             if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
10854                /* Received a LAGRQ - echo back a LAGRP */
10855                fr->af.subclass.integer = IAX_COMMAND_LAGRP;
10856                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10857             } else {
10858                /* Received LAGRP in response to our LAGRQ */
10859                unsigned int ts;
10860                /* This is a reply we've been given, actually measure the difference */
10861                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10862                iaxs[fr->callno]->lag = ts - fr->ts;
10863                if (iaxdebug)
10864                   ast_debug(1, "Peer %s lag measured as %dms\n",
10865                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10866             }
10867             break;
10868          case IAX_COMMAND_AUTHREQ:
10869             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10870                ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10871                break;
10872             }
10873             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10874                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10875                         .subclass.integer = AST_CONTROL_HANGUP,
10876                };
10877                ast_log(LOG_WARNING, 
10878                   "I don't know how to authenticate %s to %s\n", 
10879                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10880                iax2_queue_frame(fr->callno, &hangup_fr);
10881             }
10882             break;
10883          case IAX_COMMAND_AUTHREP:
10884             /* For security, always ack immediately */
10885             if (delayreject)
10886                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10887             /* Ignore once we've started */
10888             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10889                ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10890                break;
10891             }
10892             if (authenticate_verify(iaxs[fr->callno], &ies)) {
10893                if (authdebug)
10894                   ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username);
10895                memset(&ied0, 0, sizeof(ied0));
10896                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10897                break;
10898             }
10899             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10900                /* This might re-enter the IAX code and need the lock */
10901                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10902             } else
10903                exists = 0;
10904             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10905                if (authdebug)
10906                   ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
10907                memset(&ied0, 0, sizeof(ied0));
10908                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10909                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10910                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10911                if (!iaxs[fr->callno]) {
10912                   break;
10913                }
10914             } else {
10915                /* Select an appropriate format */
10916                if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10917                   if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10918                      using_prefs = "reqonly";
10919                   } else {
10920                      using_prefs = "disabled";
10921                   }
10922                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10923                   memset(&pref, 0, sizeof(pref));
10924                   strcpy(caller_pref_buf, "disabled");
10925                   strcpy(host_pref_buf, "disabled");
10926                } else {
10927                   using_prefs = "mine";
10928                   if (ies.codec_prefs)
10929                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10930                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10931                      if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10932                         pref = iaxs[fr->callno]->rprefs;
10933                         using_prefs = "caller";
10934                      } else {
10935                         pref = iaxs[fr->callno]->prefs;
10936                      }
10937                   } else /* if no codec_prefs IE do it the old way */
10938                      pref = iaxs[fr->callno]->prefs;
10939                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10940                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10941                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10942                }
10943                if (!format) {
10944                   char tmp1[256], tmp2[256], tmp3[256];
10945                   if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10946                      ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
10947                         ast_getformatname(iaxs[fr->callno]->peerformat),
10948                         ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
10949                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10950                   }
10951                   if (!format) {
10952                      if (authdebug) {
10953                         if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10954                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
10955                               ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10956                               ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10957                         } else {
10958                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10959                               ast_inet_ntoa(sin.sin_addr),
10960                               ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10961                               ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10962                               ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10963                         }
10964                      }
10965                      memset(&ied0, 0, sizeof(ied0));
10966                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10967                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10968                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10969                      if (!iaxs[fr->callno]) {
10970                         break;
10971                      }
10972                   } else {
10973                      /* Pick one... */
10974                      if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10975                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10976                            format = 0;
10977                      } else {
10978                         if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10979                            using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10980                            memset(&pref, 0, sizeof(pref));
10981                            format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
10982                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10983                            strcpy(caller_pref_buf,"disabled");
10984                            strcpy(host_pref_buf,"disabled");
10985                         } else {
10986                            using_prefs = "mine";
10987                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10988                               /* Do the opposite of what we tried above. */
10989                               if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10990                                  pref = iaxs[fr->callno]->prefs;
10991                               } else {
10992                                  pref = iaxs[fr->callno]->rprefs;
10993                                  using_prefs = "caller";
10994                               }
10995                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10996                            } else /* if no codec_prefs IE do it the old way */
10997                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
10998                         }
10999                      }
11000                      if (!format) {
11001                         char tmp1[256], tmp2[256], tmp3[256];
11002                         ast_log(LOG_ERROR, "No best format in %s???\n",
11003                            ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11004                         if (authdebug) {
11005                            if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11006                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11007                                  ast_inet_ntoa(sin.sin_addr),
11008                                  ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11009                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11010                            } else {
11011                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11012                                  ast_inet_ntoa(sin.sin_addr),
11013                                  ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11014                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11015                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11016                            }
11017                         }
11018                         memset(&ied0, 0, sizeof(ied0));
11019                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11020                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11021                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11022                         if (!iaxs[fr->callno]) {
11023                            break;
11024                         }
11025                      }
11026                   }
11027                }
11028                if (format) {
11029                   /* Authentication received */
11030                   memset(&ied1, 0, sizeof(ied1));
11031                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11032                   iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11033                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11034                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11035                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11036                      ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11037                                  "%srequested format = %s,\n"
11038                                  "%srequested prefs = %s,\n"
11039                                  "%sactual format = %s,\n"
11040                                  "%shost prefs = %s,\n"
11041                                  "%spriority = %s\n", 
11042                                  ast_inet_ntoa(sin.sin_addr), 
11043                                  VERBOSE_PREFIX_4,
11044                                  ast_getformatname(iaxs[fr->callno]->peerformat),
11045                                  VERBOSE_PREFIX_4,
11046                                  caller_pref_buf,
11047                                  VERBOSE_PREFIX_4,
11048                                  ast_getformatname(format),
11049                                  VERBOSE_PREFIX_4,
11050                                  host_pref_buf,
11051                                  VERBOSE_PREFIX_4,
11052                                  using_prefs);
11053 
11054                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11055                      if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
11056                         iax2_destroy(fr->callno);
11057                      else if (ies.vars) {
11058                         struct ast_datastore *variablestore;
11059                         struct ast_variable *var, *prev = NULL;
11060                         AST_LIST_HEAD(, ast_var_t) *varlist;
11061                         varlist = ast_calloc(1, sizeof(*varlist));
11062                         variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11063                         if (variablestore && varlist) {
11064                            variablestore->data = varlist;
11065                            variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11066                            AST_LIST_HEAD_INIT(varlist);
11067                            ast_debug(1, "I can haz IAX vars? w00t\n");
11068                            for (var = ies.vars; var; var = var->next) {
11069                               struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11070                               if (prev)
11071                                  ast_free(prev);
11072                               prev = var;
11073                               if (!newvar) {
11074                                  /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11075                                  ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11076                               } else {
11077                                  AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11078                               }
11079                            }
11080                            if (prev)
11081                               ast_free(prev);
11082                            ies.vars = NULL;
11083                            ast_channel_datastore_add(c, variablestore);
11084                         } else {
11085                            ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11086                            if (variablestore)
11087                               ast_datastore_free(variablestore);
11088                            if (varlist)
11089                               ast_free(varlist);
11090                         }
11091                      }
11092                   } else {
11093                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11094                      /* If this is a TBD call, we're ready but now what...  */
11095                      ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11096                      if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11097                         goto immediatedial;
11098                      }
11099                   }
11100                }
11101             }
11102             break;
11103          case IAX_COMMAND_DIAL:
11104 immediatedial:
11105             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11106                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11107                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11108                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11109                   if (authdebug)
11110                      ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
11111                   memset(&ied0, 0, sizeof(ied0));
11112                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11113                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11114                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11115                   if (!iaxs[fr->callno]) {
11116                      break;
11117                   }
11118                } else {
11119                   char tmp[256];
11120                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11121                   ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11122                      ast_inet_ntoa(sin.sin_addr),
11123                      ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11124                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11125                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11126                   if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
11127                      iax2_destroy(fr->callno);
11128                   else if (ies.vars) {
11129                      struct ast_datastore *variablestore;
11130                      struct ast_variable *var, *prev = NULL;
11131                      AST_LIST_HEAD(, ast_var_t) *varlist;
11132                      varlist = ast_calloc(1, sizeof(*varlist));
11133                      variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11134                      ast_debug(1, "I can haz IAX vars? w00t\n");
11135                      if (variablestore && varlist) {
11136                         variablestore->data = varlist;
11137                         variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11138                         AST_LIST_HEAD_INIT(varlist);
11139                         for (var = ies.vars; var; var = var->next) {
11140                            struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11141                            if (prev)
11142                               ast_free(prev);
11143                            prev = var;
11144                            if (!newvar) {
11145                               /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11146                               ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11147                            } else {
11148                               AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11149                            }
11150                         }
11151                         if (prev)
11152                            ast_free(prev);
11153                         ies.vars = NULL;
11154                         ast_channel_datastore_add(c, variablestore);
11155                      } else {
11156                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11157                         if (variablestore)
11158                            ast_datastore_free(variablestore);
11159                         if (varlist)
11160                            ast_free(varlist);
11161                      }
11162                   }
11163                }
11164             }
11165             break;
11166          case IAX_COMMAND_INVAL:
11167             iaxs[fr->callno]->error = ENOTCONN;
11168             ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11169             iax2_destroy(fr->callno);
11170             ast_debug(1, "Destroying call %d\n", fr->callno);
11171             break;
11172          case IAX_COMMAND_VNAK:
11173             ast_debug(1, "Received VNAK: resending outstanding frames\n");
11174             /* Force retransmission */
11175             vnak_retransmit(fr->callno, fr->iseqno);
11176             break;
11177          case IAX_COMMAND_REGREQ:
11178          case IAX_COMMAND_REGREL:
11179             /* For security, always ack immediately */
11180             if (delayreject)
11181                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11182             if (register_verify(fr->callno, &sin, &ies)) {
11183                if (!iaxs[fr->callno]) {
11184                   break;
11185                }
11186                /* Send delayed failure */
11187                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11188                break;
11189             }
11190             if (!iaxs[fr->callno]) {
11191                break;
11192             }
11193             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11194                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11195 
11196                if (f.subclass.integer == IAX_COMMAND_REGREL) {
11197                   memset(&sin, 0, sizeof(sin));
11198                   sin.sin_family = AF_INET;
11199                }
11200                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11201                   ast_log(LOG_WARNING, "Registry error\n");
11202                }
11203                if (!iaxs[fr->callno]) {
11204                   break;
11205                }
11206                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11207                   ast_mutex_unlock(&iaxsl[fr->callno]);
11208                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11209                   ast_mutex_lock(&iaxsl[fr->callno]);
11210                }
11211                break;
11212             }
11213             registry_authrequest(fr->callno);
11214             break;
11215          case IAX_COMMAND_REGACK:
11216             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
11217                ast_log(LOG_WARNING, "Registration failure\n");
11218             /* Send ack immediately, before we destroy */
11219             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11220             iax2_destroy(fr->callno);
11221             break;
11222          case IAX_COMMAND_REGREJ:
11223             if (iaxs[fr->callno]->reg) {
11224                if (authdebug) {
11225                   ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>", ast_inet_ntoa(sin.sin_addr));
11226                   manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
11227                }
11228                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11229             }
11230             /* Send ack immediately, before we destroy */
11231             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11232             iax2_destroy(fr->callno);
11233             break;
11234          case IAX_COMMAND_REGAUTH:
11235             /* Authentication request */
11236             if (registry_rerequest(&ies, fr->callno, &sin)) {
11237                memset(&ied0, 0, sizeof(ied0));
11238                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11239                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11240                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11241             }
11242             break;
11243          case IAX_COMMAND_TXREJ:
11244             iaxs[fr->callno]->transferring = 0;
11245             ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11246             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11247             if (iaxs[fr->callno]->bridgecallno) {
11248                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11249                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
11250                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11251                }
11252             }
11253             break;
11254          case IAX_COMMAND_TXREADY:
11255             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
11256                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
11257                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
11258                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11259                else
11260                   iaxs[fr->callno]->transferring = TRANSFER_READY;
11261                ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11262                if (iaxs[fr->callno]->bridgecallno) {
11263                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
11264                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
11265                      /* They're both ready, now release them. */
11266                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11267                         ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11268                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11269 
11270                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11271                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11272 
11273                         memset(&ied0, 0, sizeof(ied0));
11274                         memset(&ied1, 0, sizeof(ied1));
11275                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11276                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11277                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11278                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11279                      } else {
11280                         ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11281                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11282 
11283                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11284                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11285                         ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11286                         ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11287 
11288                         /* Stop doing lag & ping requests */
11289                         stop_stuff(fr->callno);
11290                         stop_stuff(iaxs[fr->callno]->bridgecallno);
11291 
11292                         memset(&ied0, 0, sizeof(ied0));
11293                         memset(&ied1, 0, sizeof(ied1));
11294                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11295                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11296                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11297                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11298                      }
11299 
11300                   }
11301                }
11302             }
11303             break;
11304          case IAX_COMMAND_TXREQ:
11305             try_transfer(iaxs[fr->callno], &ies);
11306             break;
11307          case IAX_COMMAND_TXCNT:
11308             if (iaxs[fr->callno]->transferring)
11309                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11310             break;
11311          case IAX_COMMAND_TXREL:
11312             /* Send ack immediately, rather than waiting until we've changed addresses */
11313             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11314             complete_transfer(fr->callno, &ies);
11315             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
11316             break;   
11317          case IAX_COMMAND_TXMEDIA:
11318             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11319                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11320                   /* Cancel any outstanding frames and start anew */
11321                   if (cur->transfer) {
11322                      cur->retries = -1;
11323                   }
11324                }
11325                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
11326                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11327             }
11328             break;
11329          case IAX_COMMAND_RTKEY:
11330             if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11331                ast_log(LOG_WARNING, 
11332                   "we've been told to rotate our encryption key, "
11333                   "but this isn't an encrypted call. bad things will happen.\n"
11334                );
11335                break;
11336             }
11337 
11338             IAX_DEBUGDIGEST("Receiving", ies.challenge);
11339 
11340             ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11341             break;
11342          case IAX_COMMAND_DPREP:
11343             complete_dpreply(iaxs[fr->callno], &ies);
11344             break;
11345          case IAX_COMMAND_UNSUPPORT:
11346             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11347             break;
11348          case IAX_COMMAND_FWDOWNL:
11349             /* Firmware download */
11350             if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11351                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11352                break;
11353             }
11354             memset(&ied0, 0, sizeof(ied0));
11355             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11356             if (res < 0)
11357                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11358             else if (res > 0)
11359                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11360             else
11361                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11362             break;
11363          case IAX_COMMAND_CALLTOKEN:
11364          {
11365             struct iax_frame *cur;
11366             /* find last sent frame */
11367             if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11368                resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11369             }
11370             break;
11371          }
11372          default:
11373             ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11374             memset(&ied0, 0, sizeof(ied0));
11375             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11376             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11377          }
11378          /* Free remote variables (if any) */
11379          if (ies.vars) {
11380             ast_variables_destroy(ies.vars);
11381             ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11382             ies.vars = NULL;
11383          }
11384 
11385          /* Don't actually pass these frames along */
11386          if ((f.subclass.integer != IAX_COMMAND_ACK) && 
11387            (f.subclass.integer != IAX_COMMAND_TXCNT) && 
11388            (f.subclass.integer != IAX_COMMAND_TXACC) && 
11389            (f.subclass.integer != IAX_COMMAND_INVAL) &&
11390            (f.subclass.integer != IAX_COMMAND_VNAK)) { 
11391             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11392                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11393          }
11394          ast_mutex_unlock(&iaxsl[fr->callno]);
11395          return 1;
11396       }
11397       /* Unless this is an ACK or INVAL frame, ack it */
11398       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11399          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11400    } else if (minivid) {
11401       f.frametype = AST_FRAME_VIDEO;
11402       if (iaxs[fr->callno]->videoformat > 0) 
11403          f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11404       else {
11405          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11406          iax2_vnak(fr->callno);
11407          ast_variables_destroy(ies.vars);
11408          ast_mutex_unlock(&iaxsl[fr->callno]);
11409          return 1;
11410       }
11411       f.datalen = res - sizeof(*vh);
11412       if (f.datalen)
11413          f.data.ptr = thread->buf + sizeof(*vh);
11414       else
11415          f.data.ptr = NULL;
11416 #ifdef IAXTESTS
11417       if (test_resync) {
11418          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11419       } else
11420 #endif /* IAXTESTS */
11421          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11422    } else {
11423       /* A mini frame */
11424       f.frametype = AST_FRAME_VOICE;
11425       if (iaxs[fr->callno]->voiceformat > 0)
11426          f.subclass.codec = iaxs[fr->callno]->voiceformat;
11427       else {
11428          ast_debug(1, "Received mini frame before first full voice frame\n");
11429          iax2_vnak(fr->callno);
11430          ast_variables_destroy(ies.vars);
11431          ast_mutex_unlock(&iaxsl[fr->callno]);
11432          return 1;
11433       }
11434       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11435       if (f.datalen < 0) {
11436          ast_log(LOG_WARNING, "Datalen < 0?\n");
11437          ast_variables_destroy(ies.vars);
11438          ast_mutex_unlock(&iaxsl[fr->callno]);
11439          return 1;
11440       }
11441       if (f.datalen)
11442          f.data.ptr = thread->buf + sizeof(*mh);
11443       else
11444          f.data.ptr = NULL;
11445 #ifdef IAXTESTS
11446       if (test_resync) {
11447          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11448       } else
11449 #endif /* IAXTESTS */
11450       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11451       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
11452    }
11453    /* Don't pass any packets until we're started */
11454    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11455       ast_variables_destroy(ies.vars);
11456       ast_mutex_unlock(&iaxsl[fr->callno]);
11457       return 1;
11458    }
11459    /* Don't allow connected line updates unless we are configured to */
11460    if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) {
11461       struct ast_party_connected_line connected;
11462 
11463       if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11464          ast_variables_destroy(ies.vars);
11465          ast_mutex_unlock(&iaxsl[fr->callno]);
11466          return 1;
11467       }
11468 
11469       /* Initialize defaults */
11470       ast_party_connected_line_init(&connected);
11471       connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11472       connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11473 
11474       if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11475          ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11476          ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11477          iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11478 
11479          if (iaxs[fr->callno]->owner) {
11480             ast_set_callerid(iaxs[fr->callno]->owner,
11481                S_COR(connected.id.number.valid, connected.id.number.str, ""),
11482                S_COR(connected.id.name.valid, connected.id.name.str, ""),
11483                NULL);
11484             iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11485             iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11486          }
11487       }
11488       ast_party_connected_line_free(&connected);
11489    }
11490    /* Common things */
11491    f.src = "IAX2";
11492    f.mallocd = 0;
11493    f.offset = 0;
11494    f.len = 0;
11495    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11496       f.samples = ast_codec_get_samples(&f);
11497       /* We need to byteswap incoming slinear samples from network byte order */
11498       if (f.subclass.codec == AST_FORMAT_SLINEAR)
11499          ast_frame_byteswap_be(&f);
11500    } else
11501       f.samples = 0;
11502    iax_frame_wrap(fr, &f);
11503 
11504    /* If this is our most recent packet, use it as our basis for timestamping */
11505    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11506       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
11507       fr->outoforder = 0;
11508    } else {
11509       if (iaxdebug && iaxs[fr->callno])
11510          ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last);
11511       fr->outoforder = -1;
11512    }
11513    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11514    duped_fr = iaxfrdup2(fr);
11515    if (duped_fr) {
11516       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11517    }
11518    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11519       iaxs[fr->callno]->last = fr->ts;
11520 #if 1
11521       if (iaxdebug)
11522          ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11523 #endif
11524    }
11525 
11526    /* Always run again */
11527    ast_variables_destroy(ies.vars);
11528    ast_mutex_unlock(&iaxsl[fr->callno]);
11529    return 1;
11530 }

static int socket_process_meta ( int  packet_len,
struct ast_iax2_meta_hdr meta,
struct sockaddr_in *  sin,
int  sockfd,
struct iax_frame fr 
) [static]

Definition at line 9582 of file chan_iax2.c.

References ast_codec_get_samples(), AST_FRAME_VOICE, ast_inet_ntoa(), ast_log(), ast_mutex_unlock, ast_test_flag, ast_tvnow(), ast_tvzero(), iax_frame::callno, ast_iax2_mini_hdr::callno, f, find_callno_locked(), find_tpeer(), fix_peerts(), 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_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, NEW_PREVENT, iax_frame::outoforder, iax2_trunk_peer::rxtrunktime, schedule_delivery(), iax2_trunk_peer::trunkact, iax_frame::ts, ast_iax2_mini_hdr::ts, and chan_iax2_pvt::voiceformat.

Referenced by socket_process().

09584 {
09585    unsigned char metatype;
09586    struct ast_iax2_meta_trunk_mini *mtm;
09587    struct ast_iax2_meta_trunk_hdr *mth;
09588    struct ast_iax2_meta_trunk_entry *mte;
09589    struct iax2_trunk_peer *tpeer;
09590    unsigned int ts;
09591    void *ptr;
09592    struct timeval rxtrunktime;
09593    struct ast_frame f = { 0, };
09594 
09595    if (packet_len < sizeof(*meta)) {
09596       ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 
09597          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09598       return 1;
09599    }
09600 
09601    if (meta->metacmd != IAX_META_TRUNK)
09602       return 1;
09603 
09604    if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09605       ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09606          (int) (sizeof(*meta) + sizeof(*mth)));
09607       return 1;
09608    }
09609    mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09610    ts = ntohl(mth->ts);
09611    metatype = meta->cmddata;
09612    packet_len -= (sizeof(*meta) + sizeof(*mth));
09613    ptr = mth->data;
09614    tpeer = find_tpeer(sin, sockfd);
09615    if (!tpeer) {
09616       ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 
09617          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09618       return 1;
09619    }
09620    tpeer->trunkact = ast_tvnow();
09621    if (!ts || ast_tvzero(tpeer->rxtrunktime))
09622       tpeer->rxtrunktime = tpeer->trunkact;
09623    rxtrunktime = tpeer->rxtrunktime;
09624    ast_mutex_unlock(&tpeer->lock);
09625    while (packet_len >= sizeof(*mte)) {
09626       /* Process channels */
09627       unsigned short callno, trunked_ts, len;
09628 
09629       if (metatype == IAX_META_TRUNK_MINI) {
09630          mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09631          ptr += sizeof(*mtm);
09632          packet_len -= sizeof(*mtm);
09633          len = ntohs(mtm->len);
09634          callno = ntohs(mtm->mini.callno);
09635          trunked_ts = ntohs(mtm->mini.ts);
09636       } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09637          mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09638          ptr += sizeof(*mte);
09639          packet_len -= sizeof(*mte);
09640          len = ntohs(mte->len);
09641          callno = ntohs(mte->callno);
09642          trunked_ts = 0;
09643       } else {
09644          ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09645          break;
09646       }
09647       /* Stop if we don't have enough data */
09648       if (len > packet_len)
09649          break;
09650       fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09651       if (!fr->callno)
09652          continue;
09653 
09654       /* If it's a valid call, deliver the contents.  If not, we
09655          drop it, since we don't have a scallno to use for an INVAL */
09656       /* Process as a mini frame */
09657       memset(&f, 0, sizeof(f));
09658       f.frametype = AST_FRAME_VOICE;
09659       if (!iaxs[fr->callno]) {
09660          /* drop it */
09661       } else if (iaxs[fr->callno]->voiceformat == 0) {
09662          ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09663          iax2_vnak(fr->callno);
09664       } else {
09665          f.subclass.codec = iaxs[fr->callno]->voiceformat;
09666          f.datalen = len;
09667          if (f.datalen >= 0) {
09668             if (f.datalen)
09669                f.data.ptr = ptr;
09670             else
09671                f.data.ptr = NULL;
09672             if (trunked_ts)
09673                fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09674             else
09675                fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09676             /* Don't pass any packets until we're started */
09677             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09678                struct iax_frame *duped_fr;
09679 
09680                /* Common things */
09681                f.src = "IAX2";
09682                f.mallocd = 0;
09683                f.offset = 0;
09684                if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
09685                   f.samples = ast_codec_get_samples(&f);
09686                else
09687                   f.samples = 0;
09688                fr->outoforder = 0;
09689                iax_frame_wrap(fr, &f);
09690                duped_fr = iaxfrdup2(fr);
09691                if (duped_fr)
09692                   schedule_delivery(duped_fr, 1, 1, &fr->ts);
09693                if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09694                   iaxs[fr->callno]->last = fr->ts;
09695             }
09696          } else {
09697             ast_log(LOG_WARNING, "Datalen < 0?\n");
09698          }
09699       }
09700       ast_mutex_unlock(&iaxsl[fr->callno]);
09701       ptr += len;
09702       packet_len -= len;
09703    }
09704 
09705    return 1;
09706 }

static int socket_read ( int *  id,
int  fd,
short  events,
void *  cbdata 
) [static]

Definition at line 9503 of file chan_iax2.c.

References ast_copy_string(), ast_debug, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), 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, inaddrcmp(), iax2_thread::list, LOG_WARNING, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, thread, and ast_iax2_full_hdr::type.

Referenced by network_thread(), peer_set_srcaddr(), and set_config().

09504 {
09505    struct iax2_thread *thread;
09506    socklen_t len;
09507    time_t t;
09508    static time_t last_errtime = 0;
09509    struct ast_iax2_full_hdr *fh;
09510 
09511    if (!(thread = find_idle_thread())) {
09512       time(&t);
09513       if (t != last_errtime)
09514          ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09515       last_errtime = t;
09516       usleep(1);
09517       return 1;
09518    }
09519 
09520    len = sizeof(thread->iosin);
09521    thread->iofd = fd;
09522    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09523    thread->buf_size = sizeof(thread->readbuf);
09524    thread->buf = thread->readbuf;
09525    if (thread->buf_len < 0) {
09526       if (errno != ECONNREFUSED && errno != EAGAIN)
09527          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09528       handle_error();
09529       thread->iostate = IAX_IOSTATE_IDLE;
09530       signal_condition(&thread->lock, &thread->cond);
09531       return 1;
09532    }
09533    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
09534       thread->iostate = IAX_IOSTATE_IDLE;
09535       signal_condition(&thread->lock, &thread->cond);
09536       return 1;
09537    }
09538    
09539    /* Determine if this frame is a full frame; if so, and any thread is currently
09540       processing a full frame for the same callno from this peer, then drop this
09541       frame (and the peer will retransmit it) */
09542    fh = (struct ast_iax2_full_hdr *) thread->buf;
09543    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09544       struct iax2_thread *cur = NULL;
09545       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09546       
09547       AST_LIST_LOCK(&active_list);
09548       AST_LIST_TRAVERSE(&active_list, cur, list) {
09549          if ((cur->ffinfo.callno == callno) &&
09550              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09551             break;
09552       }
09553       if (cur) {
09554          /* we found another thread processing a full frame for this call,
09555             so queue it up for processing later. */
09556          defer_full_frame(thread, cur);
09557          AST_LIST_UNLOCK(&active_list);
09558          thread->iostate = IAX_IOSTATE_IDLE;
09559          signal_condition(&thread->lock, &thread->cond);
09560          return 1;
09561       } else {
09562          /* this thread is going to process this frame, so mark it */
09563          thread->ffinfo.callno = callno;
09564          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09565          thread->ffinfo.type = fh->type;
09566          thread->ffinfo.csub = fh->csub;
09567          AST_LIST_INSERT_HEAD(&active_list, thread, list);
09568       }
09569       AST_LIST_UNLOCK(&active_list);
09570    }
09571    
09572    /* Mark as ready and send on its way */
09573    thread->iostate = IAX_IOSTATE_READY;
09574 #ifdef DEBUG_SCHED_MULTITHREAD
09575    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09576 #endif
09577    signal_condition(&thread->lock, &thread->cond);
09578 
09579    return 1;
09580 }

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

Definition at line 9220 of file chan_iax2.c.

References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create_detached, ast_strdup, dp_lookup_thread(), and LOG_WARNING.

Referenced by socket_process().

09221 {
09222    pthread_t newthread;
09223    struct dpreq_data *dpr;
09224    
09225    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09226       return;
09227 
09228    dpr->callno = callno;
09229    ast_copy_string(dpr->context, context, sizeof(dpr->context));
09230    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09231    if (callerid)
09232       dpr->callerid = ast_strdup(callerid);
09233    if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09234       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09235    }
09236 }

static int start_network_thread ( void   )  [static]

Definition at line 12084 of file chan_iax2.c.

References ast_calloc, ast_cond_destroy, ast_cond_init, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, ast_pthread_create_background, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, iax2_thread::list, LOG_WARNING, and thread.

Referenced by load_module().

12085 {
12086    struct iax2_thread *thread;
12087    int threadcount = 0;
12088    int x;
12089    for (x = 0; x < iaxthreadcount; x++) {
12090       thread = ast_calloc(1, sizeof(*thread));
12091       if (thread) {
12092          thread->type = IAX_THREAD_TYPE_POOL;
12093          thread->threadnum = ++threadcount;
12094          ast_mutex_init(&thread->lock);
12095          ast_cond_init(&thread->cond, NULL);
12096          ast_mutex_init(&thread->init_lock);
12097          ast_cond_init(&thread->init_cond, NULL);
12098          if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12099             ast_log(LOG_WARNING, "Failed to create new thread!\n");
12100             ast_mutex_destroy(&thread->lock);
12101             ast_cond_destroy(&thread->cond);
12102             ast_mutex_destroy(&thread->init_lock);
12103             ast_cond_destroy(&thread->init_cond);
12104             ast_free(thread);
12105             thread = NULL;
12106             continue;
12107          }
12108          AST_LIST_LOCK(&idle_list);
12109          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12110          AST_LIST_UNLOCK(&idle_list);
12111       }
12112    }
12113    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
12114    ast_verb(2, "%d helper threads started\n", threadcount);
12115    return 0;
12116 }

static void stop_stuff ( int  callno  )  [static]

Definition at line 8926 of file chan_iax2.c.

References iax2_destroy_helper(), and iaxs.

Referenced by socket_process().

08927 {
08928    iax2_destroy_helper(iaxs[callno]);
08929 }

static void store_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2113 of file chan_iax2.c.

References ao2_link, ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.

Referenced by __find_callno(), complete_transfer(), and socket_process().

02114 {
02115    if (!pvt->peercallno) {
02116       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02117       return;
02118    }
02119 
02120    ao2_link(iax_peercallno_pvts, pvt);
02121 }

static void store_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2094 of file chan_iax2.c.

References ao2_link, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.

Referenced by try_transfer().

02095 {
02096    if (!pvt->transfercallno) {
02097       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02098       return;
02099    }
02100 
02101    ao2_link(iax_transfercallno_pvts, pvt);
02102 }

static int timing_read ( int *  id,
int  fd,
short  events,
void *  cbdata 
) [static]

Definition at line 9109 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_debug, ast_free, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_timer_ack(), ast_tvnow(), ast_verbose, iax2_trunk_expired(), iax2_trunk_peer::lock, send_trunk(), timer, totalcalls, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.

Referenced by network_thread().

09110 {
09111    int res, processed = 0, totalcalls = 0;
09112    struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09113    struct timeval now = ast_tvnow();
09114 
09115    if (iaxtrunkdebug)
09116       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09117 
09118    if (timer) { 
09119       ast_timer_ack(timer, 1);
09120    }
09121 
09122    /* For each peer that supports trunking... */
09123    AST_LIST_LOCK(&tpeers);
09124    AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09125       processed++;
09126       res = 0;
09127       ast_mutex_lock(&tpeer->lock);
09128       /* We can drop a single tpeer per pass.  That makes all this logic
09129          substantially easier */
09130       if (!drop && iax2_trunk_expired(tpeer, &now)) {
09131          /* Take it out of the list, but don't free it yet, because it
09132             could be in use */
09133          AST_LIST_REMOVE_CURRENT(list);
09134          drop = tpeer;
09135       } else {
09136          res = send_trunk(tpeer, &now);
09137          trunk_timed++; 
09138          if (iaxtrunkdebug)
09139             ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
09140       }     
09141       totalcalls += res;   
09142       res = 0;
09143       ast_mutex_unlock(&tpeer->lock);
09144    }
09145    AST_LIST_TRAVERSE_SAFE_END;
09146    AST_LIST_UNLOCK(&tpeers);
09147 
09148    if (drop) {
09149       ast_mutex_lock(&drop->lock);
09150       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
09151          because by the time they could get tpeerlock, we've already grabbed it */
09152       ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09153       if (drop->trunkdata) {
09154          ast_free(drop->trunkdata);
09155          drop->trunkdata = NULL;
09156       }
09157       ast_mutex_unlock(&drop->lock);
09158       ast_mutex_destroy(&drop->lock);
09159       ast_free(drop);
09160       
09161    }
09162 
09163    if (iaxtrunkdebug)
09164       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09165    iaxtrunkdebug = 0;
09166 
09167    return 1;
09168 }

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

Definition at line 14323 of file chan_iax2.c.

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

Referenced by load_objects().

14324 {
14325    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14326 
14327    /* The frames_received field is used to hold whether we're matching
14328     * against a full frame or not ... */
14329 
14330    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14331       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14332 }

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

Definition at line 14316 of file chan_iax2.c.

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

14317 {
14318    const struct chan_iax2_pvt *pvt = obj;
14319 
14320    return pvt->transfercallno;
14321 }

static int transmit_frame ( void *  data  )  [static]

Definition at line 4228 of file chan_iax2.c.

References AST_LIST_INSERT_TAIL, ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, frame_queue, iax2_sched_add(), iax_frame_free(), iaxs, iaxsl, iax2_trunk_peer::list, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, sched, send_packet(), and iax_frame::sentyet.

Referenced by iax2_transmit().

04229 {
04230    struct iax_frame *fr = data;
04231 
04232    ast_mutex_lock(&iaxsl[fr->callno]);
04233 
04234    fr->sentyet = 1;
04235 
04236    if (iaxs[fr->callno]) {
04237       send_packet(fr);
04238    }
04239 
04240    if (fr->retries < 0) {
04241       ast_mutex_unlock(&iaxsl[fr->callno]);
04242       /* No retransmit requested */
04243       iax_frame_free(fr);
04244    } else {
04245       /* We need reliable delivery.  Schedule a retransmission */
04246       AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04247       fr->retries++;
04248       fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04249       ast_mutex_unlock(&iaxsl[fr->callno]);
04250    }
04251 
04252    return 0;
04253 }

static int transmit_trunk ( struct iax_frame f,
struct sockaddr_in *  sin,
int  sockfd 
) [static]

Definition at line 3300 of file chan_iax2.c.

References ast_debug, errno, f, and handle_error().

Referenced by send_trunk().

03301 {
03302    int res;
03303    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03304                sizeof(*sin));
03305    if (res < 0) {
03306       ast_debug(1, "Received error: %s\n", strerror(errno));
03307       handle_error();
03308    } else
03309       res = 0;
03310    return res;
03311 }

static int try_firmware ( char *  s  )  [static]

Definition at line 3002 of file chan_iax2.c.

References ast_calloc, AST_FILE_MODE, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strlen_zero(), ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, iax2_trunk_peer::list, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), and ast_iax2_firmware_header::version.

Referenced by reload_firmware().

03003 {
03004    struct stat stbuf;
03005    struct iax_firmware *cur = NULL;
03006    int ifd, fd, res, len, chunk;
03007    struct ast_iax2_firmware_header *fwh, fwh2;
03008    struct MD5Context md5;
03009    unsigned char sum[16], buf[1024];
03010    char *s2, *last;
03011 
03012    if (!(s2 = alloca(strlen(s) + 100))) {
03013       ast_log(LOG_WARNING, "Alloca failed!\n");
03014       return -1;
03015    }
03016 
03017    last = strrchr(s, '/');
03018    if (last)
03019       last++;
03020    else
03021       last = s;
03022 
03023    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
03024 
03025    if ((res = stat(s, &stbuf) < 0)) {
03026       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03027       return -1;
03028    }
03029 
03030    /* Make sure it's not a directory */
03031    if (S_ISDIR(stbuf.st_mode))
03032       return -1;
03033    ifd = open(s, O_RDONLY);
03034    if (ifd < 0) {
03035       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03036       return -1;
03037    }
03038    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03039    if (fd < 0) {
03040       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03041       close(ifd);
03042       return -1;
03043    }
03044    /* Unlink our newly created file */
03045    unlink(s2);
03046    
03047    /* Now copy the firmware into it */
03048    len = stbuf.st_size;
03049    while(len) {
03050       chunk = len;
03051       if (chunk > sizeof(buf))
03052          chunk = sizeof(buf);
03053       res = read(ifd, buf, chunk);
03054       if (res != chunk) {
03055          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03056          close(ifd);
03057          close(fd);
03058          return -1;
03059       }
03060       res = write(fd, buf, chunk);
03061       if (res != chunk) {
03062          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03063          close(ifd);
03064          close(fd);
03065          return -1;
03066       }
03067       len -= chunk;
03068    }
03069    close(ifd);
03070    /* Return to the beginning */
03071    lseek(fd, 0, SEEK_SET);
03072    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03073       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03074       close(fd);
03075       return -1;
03076    }
03077    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03078       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03079       close(fd);
03080       return -1;
03081    }
03082    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03083       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03084       close(fd);
03085       return -1;
03086    }
03087    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03088       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03089       close(fd);
03090       return -1;
03091    }
03092    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
03093    if (fwh == MAP_FAILED) {
03094       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03095       close(fd);
03096       return -1;
03097    }
03098    MD5Init(&md5);
03099    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03100    MD5Final(sum, &md5);
03101    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03102       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03103       munmap((void*)fwh, stbuf.st_size);
03104       close(fd);
03105       return -1;
03106    }
03107 
03108    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03109       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03110          /* Found a candidate */
03111          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03112             /* The version we have on loaded is older, load this one instead */
03113             break;
03114          /* This version is no newer than what we have.  Don't worry about it.
03115             We'll consider it a proper load anyhow though */
03116          munmap((void*)fwh, stbuf.st_size);
03117          close(fd);
03118          return 0;
03119       }
03120    }
03121    
03122    if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03123       cur->fd = -1;
03124       AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03125    }
03126    
03127    if (cur) {
03128       if (cur->fwh)
03129          munmap((void*)cur->fwh, cur->mmaplen);
03130       if (cur->fd > -1)
03131          close(cur->fd);
03132       cur->fwh = fwh;
03133       cur->fd = fd;
03134       cur->mmaplen = stbuf.st_size;
03135       cur->dead = 0;
03136    }
03137    
03138    return 0;
03139 }

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

Definition at line 8254 of file chan_iax2.c.

References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, inet_aton(), LOG_WARNING, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, TRANSFER_NONE, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.

Referenced by socket_process().

08255 {
08256    int newcall = 0;
08257    char newip[256];
08258    struct iax_ie_data ied;
08259    struct sockaddr_in new;
08260    
08261    
08262    memset(&ied, 0, sizeof(ied));
08263    if (ies->apparent_addr)
08264       memmove(&new, ies->apparent_addr, sizeof(new));
08265    if (ies->callno)
08266       newcall = ies->callno;
08267    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08268       ast_log(LOG_WARNING, "Invalid transfer request\n");
08269       return -1;
08270    }
08271    pvt->transfercallno = newcall;
08272    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08273    inet_aton(newip, &pvt->transfer.sin_addr);
08274    pvt->transfer.sin_family = AF_INET;
08275    pvt->transferid = ies->transferid;
08276    /* only store by transfercallno if this is a new transfer,
08277     * just in case we get a duplicate TXREQ */
08278    if (pvt->transferring == TRANSFER_NONE) {
08279       store_by_transfercallno(pvt);
08280    }
08281    pvt->transferring = TRANSFER_BEGIN;
08282 
08283    if (ies->transferid)
08284       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08285    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08286    return 0;
08287 }

static format_t uncompress_subclass ( unsigned char  csub  )  [static]

Definition at line 1629 of file chan_iax2.c.

References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

Referenced by decode_frame(), handle_call_token(), and socket_process().

01630 {
01631    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01632    if (csub & IAX_FLAG_SC_LOG) {
01633       /* special case for 'compressed' -1 */
01634       if (csub == 0xff)
01635          return -1;
01636       else
01637          return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01638    }
01639    else
01640       return csub;
01641 }

static void unlink_peer ( struct iax2_peer peer  )  [static]

Definition at line 8543 of file chan_iax2.c.

References ao2_unlink, ast_sched_thread_del, iax2_peer::expire, peer_unref(), peers, iax2_peer::pokeexpire, and sched.

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

08544 {
08545    if (peer->expire > -1) {
08546       if (!ast_sched_thread_del(sched, peer->expire)) {
08547          peer->expire = -1;
08548          peer_unref(peer);
08549       }
08550    }
08551 
08552    if (peer->pokeexpire > -1) {
08553       if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08554          peer->pokeexpire = -1;
08555          peer_unref(peer);
08556       }
08557    }
08558 
08559    ao2_unlink(peers, peer);
08560 }

static int unload_module ( void   )  [static]

Definition at line 14281 of file chan_iax2.c.

References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.

static void unlock_both ( unsigned short  callno0,
unsigned short  callno1 
) [static]

Definition at line 5420 of file chan_iax2.c.

References ast_mutex_unlock, and iaxsl.

Referenced by iax2_bridge().

05421 {
05422    ast_mutex_unlock(&iaxsl[callno1]);
05423    ast_mutex_unlock(&iaxsl[callno0]);
05424 }

static void unwrap_timestamp ( struct iax_frame fr  )  [static]

Definition at line 3990 of file chan_iax2.c.

References iax_frame::af, ast_debug, AST_FRAME_VIDEO, iax_frame::callno, ast_frame::frametype, iaxs, chan_iax2_pvt::last, and iax_frame::ts.

Referenced by schedule_delivery().

03991 {
03992    /* Video mini frames only encode the lower 15 bits of the session
03993     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
03994    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03995    const int lower_mask = (1 << ts_shift) - 1;
03996    const int upper_mask = ~lower_mask;
03997    const int last_upper = iaxs[fr->callno]->last & upper_mask;
03998 
03999    if ( (fr->ts & upper_mask) == last_upper ) {
04000       const int x = fr->ts - iaxs[fr->callno]->last;
04001       const int threshold = (ts_shift == 15) ? 25000 : 50000;
04002 
04003       if (x < -threshold) {
04004          /* Sudden big jump backwards in timestamp:
04005             What likely happened here is that miniframe timestamp has circled but we haven't
04006             gotten the update from the main packet.  We'll just pretend that we did, and
04007             update the timestamp appropriately. */
04008          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04009          if (iaxdebug)
04010             ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04011       } else if (x > threshold) {
04012          /* Sudden apparent big jump forwards in timestamp:
04013             What's likely happened is this is an old miniframe belonging to the previous
04014             top 15 or 16-bit timestamp that has turned up out of order.
04015             Adjust the timestamp appropriately. */
04016          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04017          if (iaxdebug)
04018             ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04019       }
04020    }
04021 }

static void update_jbsched ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 4025 of file chan_iax2.c.

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, chan_iax2_pvt::rxcore, and sched.

Referenced by __get_from_jb(), and schedule_delivery().

04026 {
04027    int when;
04028    
04029    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04030    
04031    when = jb_next(pvt->jb) - when;
04032 
04033    if (when <= 0) {
04034       /* XXX should really just empty until when > 0.. */
04035       when = 1;
04036    }
04037    
04038    pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 
04039       CALLNO_TO_PTR(pvt->callno));
04040 }

static void update_max_nontrunk ( void   )  [static]

Definition at line 2021 of file chan_iax2.c.

References ast_debug, iaxs, and TRUNK_CALL_START.

Referenced by __find_callno(), and make_trunk().

02022 {
02023    int max = 1;
02024    int x;
02025    /* XXX Prolly don't need locks here XXX */
02026    for (x=1;x<TRUNK_CALL_START - 1; x++) {
02027       if (iaxs[x])
02028          max = x + 1;
02029    }
02030    maxnontrunkcall = max;
02031    if (iaxdebug)
02032       ast_debug(1, "New max nontrunk callno is %d\n", max);
02033 }

static void update_max_trunk ( void   )  [static]

Definition at line 2004 of file chan_iax2.c.

References ARRAY_LEN, ast_debug, iaxs, and TRUNK_CALL_START.

Referenced by iax2_destroy(), and make_trunk().

02005 {
02006    int max = TRUNK_CALL_START;
02007    int x;
02008 
02009    /* XXX Prolly don't need locks here XXX */
02010    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
02011       if (iaxs[x]) {
02012          max = x + 1;
02013       }
02014    }
02015 
02016    maxtrunkcall = max;
02017    if (iaxdebug)
02018       ast_debug(1, "New max trunk callno is %d\n", max);
02019 }

static int update_packet ( struct iax_frame f  )  [static]

Definition at line 3438 of file chan_iax2.c.

References build_rand_pad(), ast_iax2_full_hdr::dcallno, decode_frame(), encrypt_frame(), f, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, and chan_iax2_pvt::iseqno.

Referenced by __attempt_transmit().

03439 {
03440    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
03441    struct ast_iax2_full_hdr *fh = f->data;
03442    struct ast_frame af;
03443 
03444    /* if frame is encrypted. decrypt before updating it. */
03445    if (f->encmethods) {
03446       decode_frame(&f->mydcx, fh, &af, &f->datalen);
03447    }
03448    /* Mark this as a retransmission */
03449    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03450    /* Update iseqno */
03451    f->iseqno = iaxs[f->callno]->iseqno;
03452    fh->iseqno = f->iseqno;
03453 
03454    /* Now re-encrypt the frame */
03455    if (f->encmethods) {
03456    /* since this is a retransmit frame, create a new random padding
03457     * before re-encrypting. */
03458       build_rand_pad(f->semirand, sizeof(f->semirand));
03459       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03460    }
03461    return 0;
03462 }

static int update_registry ( struct sockaddr_in *  sin,
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 8658 of file chan_iax2.c.

References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, ast_sockaddr_cmp(), ast_sockaddr_from_sin, ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_verb, iax2_peer::cid_name, iax2_peer::cid_num, context, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, 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, mailbox, iax2_peer::mailbox, manager_event, iax2_peer::maxcallno, iax2_peer::name, peer_ref(), peer_unref(), peercnt_modify(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, state, strsep(), version, and iax2_peer::zonetag.

Referenced by socket_process().

08659 {
08660    /* Called from IAX thread only, with proper iaxsl lock */
08661    struct iax_ie_data ied = {
08662       .pos = 0,
08663    };
08664    struct iax2_peer *p;
08665    int msgcount;
08666    char data[80];
08667    int version;
08668    const char *peer_name;
08669    int res = -1;
08670    struct ast_sockaddr sockaddr;
08671 
08672    ast_sockaddr_from_sin(&sockaddr, sin);
08673 
08674    peer_name = ast_strdupa(iaxs[callno]->peer);
08675 
08676    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
08677    ast_mutex_unlock(&iaxsl[callno]);
08678    if (!(p = find_peer(peer_name, 1))) {
08679       ast_mutex_lock(&iaxsl[callno]);
08680       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08681       return -1;
08682    }
08683    ast_mutex_lock(&iaxsl[callno]);
08684    if (!iaxs[callno])
08685       goto return_unref;
08686 
08687    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08688       if (sin->sin_addr.s_addr) {
08689          time_t nowtime;
08690          time(&nowtime);
08691          realtime_update_peer(peer_name, &sockaddr, nowtime);
08692       } else {
08693          realtime_update_peer(peer_name, &sockaddr, 0);
08694       }
08695    }
08696 
08697    if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08698       if (iax2_regfunk) {
08699          iax2_regfunk(p->name, 1);
08700       }
08701 
08702       /* modify entry in peercnts table as _not_ registered */
08703       peercnt_modify(0, 0, &p->addr);
08704 
08705       /* Stash the IP address from which they registered */
08706       ast_sockaddr_from_sin(&p->addr, sin);
08707 
08708       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08709       if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08710          ast_db_put("IAX/Registry", p->name, data);
08711          ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08712                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08713          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08714          register_peer_exten(p, 1);
08715          ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
08716       } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08717          ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08718                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08719          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08720          register_peer_exten(p, 0);
08721          ast_db_del("IAX/Registry", p->name);
08722          ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */
08723       }
08724       /* Update the host */
08725       /* Verify that the host is really there */
08726       iax2_poke_peer(p, callno);
08727    }
08728 
08729    /* modify entry in peercnts table as registered */
08730    if (p->maxcallno) {
08731       peercnt_modify(1, p->maxcallno, &p->addr);
08732    }
08733 
08734    /* Make sure our call still exists, an INVAL at the right point may make it go away */
08735    if (!iaxs[callno]) {
08736       res = -1;
08737       goto return_unref;
08738    }
08739 
08740    /* Store socket fd */
08741    p->sockfd = fd;
08742    /* Setup the expiry */
08743    if (p->expire > -1) {
08744       if (!ast_sched_thread_del(sched, p->expire)) {
08745          p->expire = -1;
08746          peer_unref(p);
08747       }
08748    }
08749    /* treat an unspecified refresh interval as the minimum */
08750    if (!refresh)
08751       refresh = min_reg_expire;
08752    if (refresh > max_reg_expire) {
08753       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08754          p->name, max_reg_expire, refresh);
08755       p->expiry = max_reg_expire;
08756    } else if (refresh < min_reg_expire) {
08757       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08758          p->name, min_reg_expire, refresh);
08759       p->expiry = min_reg_expire;
08760    } else {
08761       p->expiry = refresh;
08762    }
08763    if (p->expiry && sin->sin_addr.s_addr) {
08764       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08765       if (p->expire == -1)
08766          peer_unref(p);
08767    }
08768    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08769    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08770    if (sin->sin_addr.s_addr) {
08771       struct sockaddr_in peer_addr;
08772 
08773       ast_sockaddr_to_sin(&p->addr, &peer_addr);
08774 
08775       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08776       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08777       if (!ast_strlen_zero(p->mailbox)) {
08778          struct ast_event *event;
08779          int new, old;
08780          char *mailbox, *context;
08781 
08782          context = mailbox = ast_strdupa(p->mailbox);
08783          strsep(&context, "@");
08784          if (ast_strlen_zero(context))
08785             context = "default";
08786 
08787          event = ast_event_get_cached(AST_EVENT_MWI,
08788             AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08789             AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08790             AST_EVENT_IE_END);
08791          if (event) {
08792             new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08793             old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08794             ast_event_destroy(event);
08795          } else { /* Fall back on checking the mailbox directly */
08796             ast_app_inboxcount(p->mailbox, &new, &old);
08797          }
08798 
08799          if (new > 255) {
08800             new = 255;
08801          }
08802          if (old > 255) {
08803             old = 255;
08804          }
08805          msgcount = (old << 8) | new;
08806 
08807          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08808       }
08809       if (ast_test_flag64(p, IAX_HASCALLERID)) {
08810          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08811          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08812       }
08813    }
08814    version = iax_check_version(devtype);
08815    if (version) 
08816       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08817 
08818    res = 0;
08819 
08820 return_unref:
08821    peer_unref(p);
08822 
08823    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08824 }

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

References CMP_MATCH, CMP_STOP, and user.

Referenced by load_objects().

01677 {
01678    struct iax2_user *user = obj, *user2 = arg;
01679 
01680    return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01681 }

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

Definition at line 12820 of file chan_iax2.c.

References ast_set_flag64, IAX_DELME, and user.

Referenced by delete_users().

12821 {
12822    struct iax2_user *user = obj;
12823 
12824    ast_set_flag64(user, IAX_DELME);
12825 
12826    return 0;
12827 }

static void user_destructor ( void *  obj  )  [static]

Definition at line 12545 of file chan_iax2.c.

References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), free_context(), and user.

Referenced by build_user().

12546 {
12547    struct iax2_user *user = obj;
12548 
12549    ast_free_ha(user->ha);
12550    free_context(user->contexts);
12551    if(user->vars) {
12552       ast_variables_destroy(user->vars);
12553       user->vars = NULL;
12554    }
12555    ast_string_field_free_memory(user);
12556 }

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

References ast_str_hash(), and user.

Referenced by load_objects().

01667 {
01668    const struct iax2_user *user = obj;
01669 
01670    return ast_str_hash(user->name);
01671 }

static struct iax2_user* user_ref ( struct iax2_user user  )  [inline, static]

Definition at line 1723 of file chan_iax2.c.

References ao2_ref, and user.

01724 {
01725    ao2_ref(user, +1);
01726    return user;
01727 }

static struct iax2_user* user_unref ( struct iax2_user user  )  [inline, static]

Definition at line 1729 of file chan_iax2.c.

References ao2_ref, and user.

Referenced by authenticate_request(), authenticate_verify(), build_user(), calltoken_required(), check_access(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), prune_users(), requirecalltoken_mark_auto(), set_config(), and users_data_provider_get().

01730 {
01731    ao2_ref(user, -1);
01732    return NULL;
01733 }

static int users_data_provider_get ( const struct ast_data_search search,
struct ast_data data_root 
) [static]

Definition at line 14486 of file chan_iax2.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cdr_flags2str(), ast_copy_string(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_password(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_strlen_zero(), ast_test_flag64, DEFAULT_CONTEXT, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, user, user_unref(), and users.

14488 {
14489    struct ast_data *data_user, *data_authmethods, *data_enum_node;
14490    struct iax2_user *user;
14491    struct ao2_iterator i;
14492    char auth[90];
14493    char *pstr = "";
14494 
14495    i = ao2_iterator_init(users, 0);
14496    while ((user = ao2_iterator_next(&i))) {
14497       data_user = ast_data_add_node(data_root, "user");
14498       if (!data_user) {
14499          user_unref(user);
14500          continue;
14501       }
14502 
14503       ast_data_add_structure(iax2_user, data_user, user);
14504 
14505       ast_data_add_codecs(data_user, "codecs", user->capability);
14506 
14507       if (!ast_strlen_zero(user->secret)) {
14508          ast_copy_string(auth, user->secret, sizeof(auth));
14509       } else if (!ast_strlen_zero(user->inkeys)) {
14510          snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14511       } else {
14512          ast_copy_string(auth, "no secret", sizeof(auth));
14513       }
14514       ast_data_add_password(data_user, "secret", auth);
14515 
14516       ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14517 
14518       /* authmethods */
14519       data_authmethods = ast_data_add_node(data_user, "authmethods");
14520       if (!data_authmethods) {
14521          ast_data_remove_node(data_root, data_user);
14522          continue;
14523       }
14524       ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14525       ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14526       ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14527 
14528       /* amaflags */
14529       data_enum_node = ast_data_add_node(data_user, "amaflags");
14530       if (!data_enum_node) {
14531          ast_data_remove_node(data_root, data_user);
14532          continue;
14533       }
14534       ast_data_add_int(data_enum_node, "value", user->amaflags);
14535       ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14536 
14537       ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14538 
14539       if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14540          pstr = "REQ only";
14541       } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14542          pstr = "disabled";
14543       } else {
14544          pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14545       }
14546       ast_data_add_str(data_user, "codec-preferences", pstr);
14547 
14548       user_unref(user);
14549 
14550       if (!ast_data_search_match(search, data_user)) {
14551          ast_data_remove_node(data_root, data_user);
14552       }
14553    }
14554    ao2_iterator_destroy(&i);
14555 
14556    return 0;
14557 }

static void vnak_retransmit ( int  callno,
int  last 
) [static]

Definition at line 9027 of file chan_iax2.c.

References AST_LIST_TRAVERSE, f, frame_queue, iax_frame::list, and send_packet().

Referenced by socket_process().

09028 {
09029    struct iax_frame *f;
09030 
09031    AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09032       /* Send a copy immediately */
09033       if (((unsigned char) (f->oseqno - last) < 128) &&
09034             (f->retries >= 0)) {
09035          send_packet(f);
09036       }
09037    }
09038 }

static int wait_for_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Note:
expects the pvt to be locked

Definition at line 5240 of file chan_iax2.c.

References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, iaxs, iaxsl, and chan_iax2_pvt::peercallno.

Referenced by iax2_indicate(), and iax2_setoption().

05241 {
05242    unsigned short callno = pvt->callno;
05243 
05244    if (!pvt->peercallno) {
05245       /* We don't know the remote side's call number, yet.  :( */
05246       int count = 10;
05247       while (count-- && pvt && !pvt->peercallno) {
05248          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05249          pvt = iaxs[callno];
05250       }
05251       if (!pvt->peercallno) {
05252          return -1;
05253       }
05254    }
05255 
05256    return 0;
05257 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", } [static]

Definition at line 14698 of file chan_iax2.c.

char accountcode[AST_MAX_ACCOUNT_CODE] [static]

Definition at line 378 of file chan_iax2.c.

Referenced by __ast_channel_alloc_ap(), __oh323_new(), ast_call_forward(), ast_cdr_setaccount(), ast_cel_fabricate_channel_from_event(), ast_do_masquerade(), ast_set_owners_and_peers(), begin_dial_channel(), build_peer(), check_peer_ok(), create_addr_from_peer(), dahdi_new(), do_forward(), findmeexec(), func_channel_write_real(), gtalk_new(), jingle_new(), local_call(), mgcp_new(), sip_new(), skinny_new(), and tds_log().

int adsi = 0 [static]

Definition at line 382 of file chan_iax2.c.

int amaflags = 0 [static]

Definition at line 381 of file chan_iax2.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 14698 of file chan_iax2.c.

int authdebug = 1 [static]

Definition at line 289 of file chan_iax2.c.

int autokill = 0 [static]

Definition at line 290 of file chan_iax2.c.

struct ao2_container* callno_limits [static]

Table containing custom callno limit rules for a range of ip addresses.

Definition at line 889 of file chan_iax2.c.

Referenced by __unload_module(), build_callno_limits(), load_objects(), reload_config(), set_config_destroy(), and set_peercnt_limit().

struct ao2_container* callno_pool [static]

table of available call numbers

Definition at line 844 of file chan_iax2.c.

const unsigned int CALLNO_POOL_BUCKETS = 2699 [static]

Definition at line 849 of file chan_iax2.c.

struct ao2_container* callno_pool_trunk [static]

table of available trunk call numbers

Definition at line 847 of file chan_iax2.c.

struct ao2_container* calltoken_ignores [static]

Table containing ip addresses not requiring calltoken validation

Definition at line 892 of file chan_iax2.c.

Referenced by __unload_module(), add_calltoken_ignore(), calltoken_required(), load_objects(), reload_config(), and set_config_destroy().

struct ast_cli_entry cli_iax2[] [static]

Definition at line 14027 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

unsigned int cos

Definition at line 300 of file chan_iax2.c.

struct sockaddr_in debugaddr [static]

Definition at line 1096 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_debug(), iax_outputframe(), reload_config(), sip_debug_test_addr(), sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer().

uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048 [static]

Definition at line 894 of file chan_iax2.c.

uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static]

Definition at line 896 of file chan_iax2.c.

char default_parkinglot[AST_MAX_CONTEXT] [static]

Definition at line 267 of file chan_iax2.c.

Referenced by load_config(), park_exec_full(), park_space_reserve(), and sip_alloc().

int defaultsockfd = -1 [static]

Definition at line 312 of file chan_iax2.c.

int delayreject = 0 [static]

Definition at line 383 of file chan_iax2.c.

struct iax_frame* first

Definition at line 860 of file chan_iax2.c.

struct { ... } frame_queue[IAX_MAX_CALLS + 1] [static]

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

int global_max_trunk_mtu [static]

Maximum MTU, 0 if not used

Definition at line 262 of file chan_iax2.c.

uint16_t global_maxcallno [static]

Definition at line 898 of file chan_iax2.c.

uint16_t global_maxcallno_nonval [static]

Total num of call numbers allowed to be allocated without calltoken validation

Definition at line 901 of file chan_iax2.c.

int global_rtautoclear = 120 [static]

Definition at line 434 of file chan_iax2.c.

struct ast_flags64 globalflags = { 0 } [static]

Definition at line 386 of file chan_iax2.c.

format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static]

Definition at line 364 of file chan_iax2.c.

struct ast_data_entry iax2_data_providers[] [static]

Initial value:

 {
   AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
   AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
}

Definition at line 14569 of file chan_iax2.c.

Referenced by load_module().

int iax2_encryption = 0 [static]

Definition at line 384 of file chan_iax2.c.

int(*) iax2_regfunk(const char *username, int onoff) = NULL [static]

Definition at line 314 of file chan_iax2.c.

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

struct ast_switch iax2_switch [static]

Definition at line 13913 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

struct ast_channel_tech iax2_tech [static]

Definition at line 1214 of file chan_iax2.c.

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

struct ast_datastore_info iax2_variable_datastore_info [static]

Initial value:

 {
   .type = "IAX2_VARIABLE",
   .duplicate = iax2_dup_variable_datastore,
   .destroy = iax2_free_variable_datastore,
}

Definition at line 1332 of file chan_iax2.c.

Referenced by acf_iaxvar_read(), acf_iaxvar_write(), ast_iax2_new(), authenticate_reply(), iax2_call(), and socket_process().

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

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_peercallno(), and store_by_peercallno().

struct ao2_container* iax_transfercallno_pvts [static]

Another container of iax2_pvt structures.

*

Active IAX2 pvt stucts used during transfering a call are stored here.

Definition at line 1089 of file chan_iax2.c.

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_transfercallno(), and store_by_transfercallno().

int iaxactivethreadcount = 0 [static]

Definition at line 633 of file chan_iax2.c.

Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().

int iaxcompat = 0 [static]

Definition at line 291 of file chan_iax2.c.

int iaxdebug = 0 [static]

Definition at line 366 of file chan_iax2.c.

int iaxdefaultdpcache = 10 * 60 [static]

Definition at line 294 of file chan_iax2.c.

int iaxdefaulttimeout = 5 [static]

Definition at line 296 of file chan_iax2.c.

int iaxdynamicthreadcount = 0 [static]

Definition at line 631 of file chan_iax2.c.

Referenced by find_idle_thread().

int iaxdynamicthreadnum = 0 [static]

Definition at line 632 of file chan_iax2.c.

Referenced by find_idle_thread().

int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static]

Definition at line 630 of file chan_iax2.c.

Referenced by find_idle_thread(), and set_config().

struct ast_custom_function iaxpeer_function [static]

Initial value:

 {
   .name = "IAXPEER",
   .read = function_iaxpeer,
}

Definition at line 13833 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS+1] [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 1062 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_answer(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_lock_owner(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queryoption(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_setoption(), iax2_start_transfer(), iax2_vnak(), iax2_write(), 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_lagrq(), send_packet(), send_ping(), set_hangup_source_and_cause(), socket_process(), socket_process_meta(), stop_stuff(), transmit_frame(), unwrap_timestamp(), update_max_nontrunk(), update_max_trunk(), update_packet(), update_registry(), and wait_for_peercallno().

ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static]

chan_iax2_pvt structure locks

These locks are used when accessing a pvt structure in the iaxs array. The index used here is the same as used in the iaxs array. It is the local call number for the associated pvt struct.

Definition at line 1082 of file chan_iax2.c.

Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __find_callno(), __get_from_jb(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), __unload_module(), acf_channel_read(), ast_cli_netstats(), ast_iax2_new(), auth_reject(), authenticate_reply(), auto_hangup(), cache_get_callno_locked(), delete_users(), dp_lookup(), find_cache(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_stats(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_destroy_helper(), iax2_do_register(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_key_rotate(), iax2_lock_owner(), iax2_poke_peer(), iax2_provision(), iax2_queryoption(), iax2_request(), iax2_setoption(), iax2_write(), load_module(), lock_both(), log_jitterstats(), make_trunk(), peer_destructor(), pvt_destructor(), register_verify(), registry_authrequest(), scheduled_destroy(), send_command_locked(), send_lagrq(), send_ping(), socket_process(), socket_process_meta(), transmit_frame(), unlock_both(), update_registry(), and wait_for_peercallno().

int iaxthreadcount = DEFAULT_THREAD_COUNT [static]

Definition at line 629 of file chan_iax2.c.

Referenced by handle_cli_iax2_show_threads(), set_config(), and start_network_thread().

int iaxtrunkdebug = 0 [static]

Definition at line 368 of file chan_iax2.c.

struct ast_custom_function iaxvar_function [static]

Initial value:

 {
   .name = "IAXVAR",
   .read = acf_iaxvar_read,
   .write = acf_iaxvar_write,
}

Definition at line 9774 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct io_context* io [static]

Definition at line 359 of file chan_iax2.c.

int jittertargetextra = 40 [static]

Definition at line 282 of file chan_iax2.c.

int lagrq_time = 10 [static]

Definition at line 278 of file chan_iax2.c.

char language[MAX_LANGUAGE] = "" [static]

Definition at line 269 of file chan_iax2.c.

struct iax_frame* last

Definition at line 860 of file chan_iax2.c.

int last_authmethod = 0 [static]

Definition at line 292 of file chan_iax2.c.

const time_t MAX_CALLTOKEN_DELAY = 10 [static]

Definition at line 866 of file chan_iax2.c.

int max_reg_expire [static]

Definition at line 304 of file chan_iax2.c.

int max_retries = 4 [static]

Definition at line 276 of file chan_iax2.c.

int maxauthreq = 3 [static]

Definition at line 275 of file chan_iax2.c.

int maxjitterbuffer = 1000 [static]

Definition at line 279 of file chan_iax2.c.

int maxjitterinterps = 10 [static]

Definition at line 281 of file chan_iax2.c.

int maxnontrunkcall = 1 [static]

Definition at line 1163 of file chan_iax2.c.

int maxtrunkcall = TRUNK_CALL_START [static]

Definition at line 1162 of file chan_iax2.c.

int min_reg_expire [static]

Definition at line 303 of file chan_iax2.c.

char mohinterpret[MAX_MUSICCLASS] [static]

Definition at line 379 of file chan_iax2.c.

char mohsuggest[MAX_MUSICCLASS] [static]

Definition at line 380 of file chan_iax2.c.

Referenced by build_peer(), check_peer_ok(), create_addr_from_peer(), set_peer_defaults(), and sip_alloc().

struct ast_netsock_list* netsock [static]

Definition at line 310 of file chan_iax2.c.

Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().

pthread_t netthreadid = AST_PTHREADT_NULL [static]

Definition at line 388 of file chan_iax2.c.

int network_change_event_sched_id = -1 [static]

Definition at line 273 of file chan_iax2.c.

Referenced by network_change_event_cb(), and network_change_event_sched_cb().

struct ast_event_sub* network_change_event_subscription [static]

subscription id for network change events

Definition at line 272 of file chan_iax2.c.

Referenced by network_change_event_subscribe(), and network_change_event_unsubscribe().

struct ast_netsock_list* outsock [static]

used if sourceaddress specified and bindaddr == INADDR_ANY

Definition at line 311 of file chan_iax2.c.

Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().

char* papp = "IAX2Provision" [static]

Definition at line 11791 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

struct ao2_container* peercnts [static]

Table containing peercnt objects for every ip address consuming a callno

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

struct ao2_container* peers [static]

Definition at line 880 of file chan_iax2.c.

Referenced by __iax2_show_peers(), __unload_module(), authenticate_reply(), build_peer(), complete_iax2_peers(), complete_iax2_unregister(), delete_users(), find_peer(), handle_cli_iax2_unregister(), iax2_getpeername(), iax2_getpeertrunk(), load_module(), load_objects(), manager_iax2_show_peer_list(), peers_data_provider_get(), poke_all_peers(), prune_peers(), set_config(), and unlink_peer().

struct ast_data_handler peers_data_provider [static]

Initial value:

Definition at line 14559 of file chan_iax2.c.

int ping_time = 21 [static]

Definition at line 277 of file chan_iax2.c.

struct ast_codec_pref prefs [static]

Definition at line 253 of file chan_iax2.c.

Referenced by ast_best_codec(), ast_rtp_codecs_packetization_set(), build_peer(), build_user(), check_access(), create_addr(), gtalk_create_member(), gtalk_load_config(), jingle_create_member(), jingle_load_config(), new_iax(), set_config(), set_local_capabilities(), and set_peer_capabilities().

struct { ... } qos [static]

Referenced by config_load(), config_parse_variables(), peer_set_srcaddr(), reload_config(), set_config(), and start_rtp().

int randomcalltokendata [static]

Definition at line 864 of file chan_iax2.c.

char regcontext[AST_MAX_CONTEXT] = "" [static]

Definition at line 270 of file chan_iax2.c.

int resyncthreshold = 1000 [static]

Definition at line 280 of file chan_iax2.c.

struct ast_sched_thread* sched [static]

Definition at line 360 of file chan_iax2.c.

int srvlookup = 0 [static]

Definition at line 306 of file chan_iax2.c.

Referenced by build_peer().

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

Definition at line 255 of file chan_iax2.c.

int test_losspct = 0 [static]

Definition at line 370 of file chan_iax2.c.

struct ast_timer* timer [static]

Definition at line 308 of file chan_iax2.c.

Referenced by __unload_module(), build_peer(), build_user(), check_timer(), find_timer(), kqueue_timer_hash(), kqueue_timer_open(), load_module(), network_thread(), pthread_timer_ack(), pthread_timer_close(), pthread_timer_destructor(), pthread_timer_disable_continuous(), pthread_timer_enable_continuous(), pthread_timer_get_event(), pthread_timer_hash(), pthread_timer_open(), pthread_timer_set_rate(), read_pipe(), run_timer(), softmix_bridge_create(), softmix_bridge_thread(), timer_destroy(), timerfd_timer_hash(), timerfd_timer_open(), timing_read(), timing_test(), and write_byte().

unsigned int tos

Definition at line 299 of file chan_iax2.c.

uint16_t total_nonval_callno_used = 0 [static]

Definition at line 903 of file chan_iax2.c.

struct ast_taskprocessor* transmit_processor [static]

Definition at line 862 of file chan_iax2.c.

int trunk_maxmtu [static]

Definition at line 263 of file chan_iax2.c.

int trunk_nmaxmtu [static]

Trunk MTU statistics

Definition at line 263 of file chan_iax2.c.

int trunk_timed [static]

Definition at line 263 of file chan_iax2.c.

int trunk_untimed [static]

Definition at line 263 of file chan_iax2.c.

int trunkfreq = 20 [static]

Definition at line 286 of file chan_iax2.c.

int trunkmaxsize = MAX_TRUNKDATA [static]

Definition at line 287 of file chan_iax2.c.

struct ao2_container* users [static]

Definition at line 883 of file chan_iax2.c.

Referenced by __unload_module(), authenticate_request(), authenticate_verify(), build_user(), check_access(), delete_users(), find_user(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), load_module(), load_objects(), pp_each_user_helper(), prune_users(), set_config(), unload_module(), and users_data_provider_get().

struct ast_data_handler users_data_provider [static]

Initial value:

Definition at line 14564 of file chan_iax2.c.


Generated on Wed Apr 6 11:29:57 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7