Mon Jun 27 16:51:05 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 14403 of file chan_iax2.c.

#define DATA_EXPORT_IAX2_USER ( MEMBER   ) 

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

08942 {
08943    /* Called from IAX thread only, without iaxs lock */
08944    int callno = (int)(long)(nothing);
08945    struct iax_ie_data ied;
08946    ast_mutex_lock(&iaxsl[callno]);
08947    if (iaxs[callno]) {
08948       memset(&ied, 0, sizeof(ied));
08949       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08950          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08951          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08952       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08953          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08954          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08955       }
08956       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08957    }
08958    ast_mutex_unlock(&iaxsl[callno]);
08959 }

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

08991 {
08992    /* Called from IAX thread only, without iaxs lock */
08993    int callno = (int)(long)(nothing);
08994    struct iax_ie_data ied;
08995    ast_mutex_lock(&iaxsl[callno]);
08996    if (iaxs[callno]) {
08997       memset(&ied, 0, sizeof(ied));
08998       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
08999       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09000       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09001    }
09002    ast_mutex_unlock(&iaxsl[callno]);
09003 }

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

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

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

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

08249 {
08250    struct iax2_registry *reg = (struct iax2_registry *)data;
08251    reg->expire = -1;
08252    iax2_do_register(reg);
08253 }

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

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

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

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

Definition at line 9050 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

09051 {
09052    struct iax2_peer *peer = (struct iax2_peer *)data;
09053    iax2_poke_peer(peer, 0);
09054    peer_unref(peer);
09055 }

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

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

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

static void __reg_module ( void   )  [static]

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

07442 {
07443    struct ast_frame f = { 0, };
07444    int res = 0;
07445 
07446    f.frametype = type;
07447    f.subclass.integer = command;
07448    f.datalen = datalen;
07449    f.src = __FUNCTION__;
07450    f.data.ptr = (void *) data;
07451 
07452    if ((res = queue_signalling(i, &f)) <= 0) {
07453       return res;
07454    }
07455 
07456    return iax2_send(i, &f, ts, seqno, now, transfer, final);
07457 }

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

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

static void __unreg_module ( void   )  [static]

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

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

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

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

09719 {
09720    struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09721    AST_LIST_HEAD(, ast_var_t) *varlist;
09722    struct ast_var_t *var;
09723 
09724    if (!variablestore) {
09725       *buf = '\0';
09726       return 0;
09727    }
09728    varlist = variablestore->data;
09729 
09730    AST_LIST_LOCK(varlist);
09731    AST_LIST_TRAVERSE(varlist, var, entries) {
09732       if (strcmp(var->name, data) == 0) {
09733          ast_copy_string(buf, var->value, len);
09734          break;
09735       }
09736    }
09737    AST_LIST_UNLOCK(varlist);
09738    return 0;
09739 }

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

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

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

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

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

Referenced by check_access().

07499 {
07500    while(con) {
07501       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07502          return -1;
07503       con = con->next;
07504    }
07505    return 0;
07506 }

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

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

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

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

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

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

08976 {
08977    /* Schedule sending the authentication failure in one second, to prevent
08978       guessing */
08979    if (iaxs[callno]) {
08980       iaxs[callno]->authfail = failcode;
08981       if (delayreject) {
08982          iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 
08983             sched, 1000, auth_reject, (void *)(long)callno);
08984       } else
08985          auth_reject((void *)(long)callno);
08986    }
08987    return 0;
08988 }

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

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

08962 {
08963    int callno = (int)(long)(data);
08964    ast_mutex_lock(&iaxsl[callno]);
08965    if (iaxs[callno])
08966       iaxs[callno]->authid = -1;
08967    ast_mutex_unlock(&iaxsl[callno]);
08968 #ifdef SCHED_MULTITHREADED
08969    if (schedule_action(__auth_reject, data))
08970 #endif      
08971       __auth_reject(data);
08972    return 0;
08973 }

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

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

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

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

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

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

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

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

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

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

09006 {
09007    int callno = (int)(long)(data);
09008    ast_mutex_lock(&iaxsl[callno]);
09009    if (iaxs[callno]) {
09010       iaxs[callno]->autoid = -1;
09011    }
09012    ast_mutex_unlock(&iaxsl[callno]);
09013 #ifdef SCHED_MULTITHREADED
09014    if (schedule_action(__auto_hangup, data))
09015 #endif      
09016       __auto_hangup(data);
09017    return 0;
09018 }

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

References ast_calloc, and ast_copy_string().

Referenced by build_user().

12129 {
12130    struct iax2_context *con;
12131 
12132    if ((con = ast_calloc(1, sizeof(*con))))
12133       ast_copy_string(con->context, context, sizeof(con->context));
12134    
12135    return con;
12136 }

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

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

06156 {
06157    /* it is required to hold the corresponding decrypt key to our encrypt key
06158     * in the pvt struct because queued frames occasionally need to be decrypted and
06159     * re-encrypted when updated for a retransmission */
06160    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06161    ast_aes_set_encrypt_key(digest, &pvt->ecx);
06162    ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06163 }

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

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

06150 {
06151    build_ecx_key(digest, pvt);
06152    ast_aes_set_decrypt_key(digest, &pvt->dcx);
06153 }

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

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

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

Definition at line 6139 of file chan_iax2.c.

References ast_random().

Referenced by build_ecx_key(), and update_packet().

06140 {
06141    long tmp;
06142    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06143       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06144       buf += sizeof(tmp);
06145       len -= sizeof(tmp);
06146    }
06147 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 9325 of file chan_iax2.c.

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

Referenced by socket_process().

09326 {
09327    unsigned int ourver;
09328    char rsi[80];
09329    snprintf(rsi, sizeof(rsi), "si-%s", si);
09330    if (iax_provision_version(&ourver, rsi, 1))
09331       return 0;
09332    ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09333    if (ourver != ver) 
09334       iax2_provision(sin, sockfd, NULL, rsi, 1);
09335    return 0;
09336 }

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

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

Referenced by peer_set_srcaddr().

12155 {
12156    int sd;
12157    int res;
12158    
12159    sd = socket(AF_INET, SOCK_DGRAM, 0);
12160    if (sd < 0) {
12161       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12162       return -1;
12163    }
12164 
12165    res = bind(sd, sa, salen);
12166    if (res < 0) {
12167       ast_debug(1, "Can't bind: %s\n", strerror(errno));
12168       close(sd);
12169       return 1;
12170    }
12171 
12172    close(sd);
12173    return 0;
12174 }

static void cleanup_thread_list ( void *  head  )  [static]

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

14189 {
14190    AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14191    struct iax2_thread_list *list_head = head;
14192    struct iax2_thread *thread;
14193 
14194    AST_LIST_LOCK(list_head);
14195    while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
14196       pthread_t thread_id = thread->threadid;
14197 
14198       thread->stop = 1;
14199       signal_condition(&thread->lock, &thread->cond);
14200 
14201       AST_LIST_UNLOCK(list_head);
14202       pthread_join(thread_id, NULL);
14203       AST_LIST_LOCK(list_head);
14204    }
14205    AST_LIST_UNLOCK(list_head);
14206 }

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

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

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

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

06863 {
06864    int which = 0;
06865    struct iax2_peer *p = NULL;
06866    char *res = NULL;
06867    int wordlen = strlen(word);
06868 
06869    /* 0 - iax2; 1 - unregister; 2 - <peername> */
06870    if (pos == 2) {
06871       struct ao2_iterator i = ao2_iterator_init(peers, 0);
06872       while ((p = ao2_iterator_next(&i))) {
06873          if (!strncasecmp(p->name, word, wordlen) && 
06874             ++which > state && p->expire > 0) {
06875             res = ast_strdup(p->name);
06876             peer_unref(p);
06877             break;
06878          }
06879          peer_unref(p);
06880       }
06881       ao2_iterator_destroy(&i);
06882    }
06883 
06884    return res;
06885 }

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

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

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

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

09339 {
09340    jb_info stats;
09341    jb_getinfo(pvt->jb, &stats);
09342    
09343    memset(iep, 0, sizeof(*iep));
09344 
09345    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09346    if(stats.frames_in == 0) stats.frames_in = 1;
09347    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09348    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09349    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09350    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09351    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09352 }

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

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

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

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

06302 {
06303    int res=-1;
06304    if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06305       /* Search for possible keys, given secrets */
06306       struct MD5Context md5;
06307       unsigned char digest[16];
06308       char *tmppw, *stringp;
06309       
06310       tmppw = ast_strdupa(iaxs[callno]->secret);
06311       stringp = tmppw;
06312       while ((tmppw = strsep(&stringp, ";"))) {
06313          MD5Init(&md5);
06314          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06315          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06316          MD5Final(digest, &md5);
06317          build_encryption_keys(digest, iaxs[callno]);
06318          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06319          if (!res) {
06320             ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06321             break;
06322          }
06323       }
06324    } else 
06325       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06326    return res;
06327 }

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

09486 {
09487    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09488    struct ast_iax2_full_hdr *fh, *cur_fh;
09489 
09490    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09491       return;
09492 
09493    pkt_buf->len = from_here->buf_len;
09494    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09495 
09496    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09497    ast_mutex_lock(&to_here->lock);
09498    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09499       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09500       if (fh->oseqno < cur_fh->oseqno) {
09501          AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09502          break;
09503       }
09504    }
09505    AST_LIST_TRAVERSE_SAFE_END
09506 
09507    if (!cur_pkt_buf)
09508       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09509    
09510    ast_mutex_unlock(&to_here->lock);
09511 }

static void delete_users ( void   )  [static]

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

12840 {
12841    struct iax2_registry *reg;
12842 
12843    ao2_callback(users, 0, user_delme_cb, NULL);
12844 
12845    AST_LIST_LOCK(&registrations);
12846    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
12847       if (sched) {
12848          ast_sched_thread_del(sched, reg->expire);
12849       }
12850       if (reg->callno) {
12851          int callno = reg->callno;
12852          ast_mutex_lock(&iaxsl[callno]);
12853          if (iaxs[callno]) {
12854             iaxs[callno]->reg = NULL;
12855             iax2_destroy(callno);
12856          }
12857          ast_mutex_unlock(&iaxsl[callno]);
12858       }
12859       if (reg->dnsmgr)
12860          ast_dnsmgr_release(reg->dnsmgr);
12861       ast_free(reg);
12862    }
12863    AST_LIST_UNLOCK(&registrations);
12864 
12865    ao2_callback(peers, 0, peer_delme_cb, NULL);
12866 }

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

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

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

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

09220 {
09221    /* Look up for dpreq */
09222    struct dpreq_data *dpr = data;
09223    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09224    if (dpr->callerid)
09225       ast_free(dpr->callerid);
09226    ast_free(dpr);
09227    return NULL;
09228 }

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

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

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

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

08605 {
08606 #ifdef SCHED_MULTITHREADED
08607    if (schedule_action(__expire_registry, data))
08608 #endif      
08609       __expire_registry(data);
08610    return 0;
08611 }

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

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

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

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

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

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

Referenced by socket_process_meta().

05844 {
05845    long ms; /* NOT unsigned */
05846    if (ast_tvzero(iaxs[callno]->rxcore)) {
05847       /* Initialize rxcore time if appropriate */
05848       iaxs[callno]->rxcore = ast_tvnow();
05849       /* Round to nearest 20ms so traces look pretty */
05850       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05851    }
05852    /* Calculate difference between trunk and channel */
05853    ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05854    /* Return as the sum of trunk time and the difference between trunk and real time */
05855    return ms + ts;
05856 }

static void free_context ( struct iax2_context con  )  [static]

Definition at line 11988 of file chan_iax2.c.

References ast_free, and iax2_context::next.

Referenced by build_user(), and user_destructor().

11989 {
11990    struct iax2_context *conl;
11991    while(con) {
11992       conl = con;
11993       con = con->next;
11994       ast_free(conl);
11995    }
11996 }

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

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

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

Definition at line 12138 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

12139 {
12140    int methods = 0;
12141    if (strstr(value, "rsa"))
12142       methods |= IAX_AUTH_RSA;
12143    if (strstr(value, "md5"))
12144       methods |= IAX_AUTH_MD5;
12145    if (strstr(value, "plaintext"))
12146       methods |= IAX_AUTH_PLAINTEXT;
12147    return methods;
12148 }

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

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

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

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

13431 {
13432    switch (cmd) {
13433    case CLI_INIT:
13434       e->command = "iax2 reload";
13435       e->usage =
13436          "Usage: iax2 reload\n"
13437          "       Reloads IAX configuration from iax.conf\n";
13438       return NULL;
13439    case CLI_GENERATE:
13440       return NULL;
13441    }
13442 
13443    reload_config();
13444 
13445    return CLI_SUCCESS;
13446 }

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

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

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

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

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

07386 {
07387    switch (cmd) {
07388    case CLI_INIT:
07389       e->command = "iax2 set debug jb {on|off}";
07390       e->usage =
07391          "Usage: iax2 set debug jb {on|off}\n"
07392          "       Enables/Disables jitterbuffer debugging information\n";
07393       return NULL;
07394    case CLI_GENERATE:
07395       return NULL;
07396    }
07397 
07398    if (a->argc != e->args)
07399       return CLI_SHOWUSAGE;
07400    
07401    if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07402       jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07403       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07404    } else {
07405       jb_setoutput(jb_error_output, jb_warning_output, NULL);
07406       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07407    }
07408    return CLI_SUCCESS;
07409 }

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

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

07360 {
07361    switch (cmd) {
07362    case CLI_INIT:
07363       e->command = "iax2 set debug trunk {on|off}";
07364       e->usage =
07365          "Usage: iax2 set debug trunk {on|off}\n"
07366          "       Enables/Disables debugging of IAX trunking\n";
07367       return NULL;
07368    case CLI_GENERATE:
07369       return NULL;
07370    }
07371 
07372    if (a->argc != e->args)
07373       return CLI_SHOWUSAGE;
07374 
07375    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07376       iaxtrunkdebug = 1;
07377       ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07378    } else {
07379       iaxtrunkdebug = 0;
07380       ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07381    }
07382    return CLI_SUCCESS;
07383 }

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

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

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

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

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

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

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

07284 {
07285    int numchans = 0;
07286 
07287    switch (cmd) {
07288    case CLI_INIT:
07289       e->command = "iax2 show netstats";
07290       e->usage =
07291          "Usage: iax2 show netstats\n"
07292          "       Lists network status for all currently active IAX channels.\n";
07293       return NULL;
07294    case CLI_GENERATE:
07295       return NULL;
07296    }
07297    if (a->argc != 3)
07298       return CLI_SHOWUSAGE;
07299    ast_cli(a->fd, "                           -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
07300    ast_cli(a->fd, "Channel               RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts FirstMsg    LastMsg\n");
07301    numchans = ast_cli_netstats(NULL, a->fd, 1);
07302    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07303    return CLI_SUCCESS;
07304 }

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

06888 {
06889    switch (cmd) {
06890    case CLI_INIT:
06891       e->command = "iax2 show peers";
06892       e->usage =
06893          "Usage: iax2 show peers [registered] [like <pattern>]\n"
06894          "       Lists all known IAX2 peers.\n"
06895          "       Optional 'registered' argument lists only peers with known addresses.\n"
06896          "       Optional regular expression pattern is used to filter the peer list.\n";
06897       return NULL;
06898    case CLI_GENERATE:
06899       return NULL;
06900    }
06901 
06902    switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
06903    case RESULT_SHOWUSAGE:
06904       return CLI_SHOWUSAGE;
06905    case RESULT_FAILURE:
06906       return CLI_FAILURE;
06907    default:
06908       return CLI_SUCCESS;
06909    }
06910 }

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

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

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

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

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

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

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

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

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

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

static void handle_deferred_full_frames ( struct iax2_thread thread  )  [static]

Handle any deferred full frames for this thread.

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

09456 {
09457    struct iax2_pkt_buf *pkt_buf;
09458 
09459    ast_mutex_lock(&thread->lock);
09460 
09461    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09462       ast_mutex_unlock(&thread->lock);
09463 
09464       thread->buf = pkt_buf->buf;
09465       thread->buf_len = pkt_buf->len;
09466       thread->buf_size = pkt_buf->len + 1;
09467       
09468       socket_process(thread);
09469 
09470       thread->buf = NULL;
09471       ast_free(pkt_buf);
09472 
09473       ast_mutex_lock(&thread->lock);
09474    }
09475 
09476    ast_mutex_unlock(&thread->lock);
09477 }

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

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

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

05592 {
05593    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05594    ast_debug(1, "Answering IAX2 call\n");
05595    ast_mutex_lock(&iaxsl[callno]);
05596    if (iaxs[callno])
05597       iax2_ami_channelupdate(iaxs[callno]);
05598    ast_mutex_unlock(&iaxsl[callno]);
05599    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05600 }

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

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

08471 {
08472    struct iax2_registry *reg;
08473 
08474    if (!(reg = ast_calloc(1, sizeof(*reg))))
08475       return -1;
08476 
08477    if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08478       ast_free(reg);
08479       return -1;
08480    }
08481 
08482    ast_copy_string(reg->username, username, sizeof(reg->username));
08483 
08484    if (secret)
08485       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08486 
08487    reg->expire = -1;
08488    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08489    ast_sockaddr_set_port(&reg->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08490 
08491    AST_LIST_LOCK(&registrations);
08492    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
08493    AST_LIST_UNLOCK(&registrations);
08494    
08495    return 0;
08496 }

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

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

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

13680 {
13681    int res = 0;
13682    struct iax2_dpcache *dp = NULL;
13683 #if 0
13684    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13685 #endif
13686    if ((priority != 1) && (priority != 2))
13687       return 0;
13688 
13689    AST_LIST_LOCK(&dpcache);
13690    if ((dp = find_cache(chan, data, context, exten, priority))) {
13691       if (dp->flags & CACHE_FLAG_CANEXIST)
13692          res = 1;
13693    } else {
13694       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13695    }
13696    AST_LIST_UNLOCK(&dpcache);
13697 
13698    return res;
13699 }

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

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

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

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

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

Definition at line 8255 of file chan_iax2.c.

References __iax2_do_register_s(), and schedule_action.

Referenced by iax2_ack_registry(), and iax2_do_register().

08256 {
08257 #ifdef SCHED_MULTITHREADED
08258    if (schedule_action(__iax2_do_register_s, data))
08259 #endif      
08260       __iax2_do_register_s(data);
08261    return 0;
08262 }

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

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

09021 {
09022    struct iax_ie_data ied;
09023    /* Auto-hangup with 30 seconds of inactivity */
09024    iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
09025       sched, 30000, auto_hangup, (void *)(long)callno);
09026    memset(&ied, 0, sizeof(ied));
09027    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09028    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09029    dp->flags |= CACHE_FLAG_TRANSMITTED;
09030 }

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

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

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

13657 {
13658    int res = 0;
13659    struct iax2_dpcache *dp = NULL;
13660 #if 0
13661    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13662 #endif
13663    if ((priority != 1) && (priority != 2))
13664       return 0;
13665 
13666    AST_LIST_LOCK(&dpcache);
13667    if ((dp = find_cache(chan, data, context, exten, priority))) {
13668       if (dp->flags & CACHE_FLAG_EXISTS)
13669          res = 1;
13670    } else {
13671       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13672    }
13673    AST_LIST_UNLOCK(&dpcache);
13674 
13675    return res;
13676 }

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

05667 {
05668    struct iax2_peer *peer;
05669    int res = 0;
05670    struct ao2_iterator i;
05671 
05672    i = ao2_iterator_init(peers, 0);
05673    while ((peer = ao2_iterator_next(&i))) {
05674       struct sockaddr_in peer_addr;
05675 
05676       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05677 
05678       if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05679           (peer_addr.sin_port == sin.sin_port)) {
05680          res = ast_test_flag64(peer, IAX_TRUNK);
05681          peer_unref(peer);
05682          break;
05683       }
05684       peer_unref(peer);
05685    }
05686    ao2_iterator_destroy(&i);
05687 
05688    return res;
05689 }

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

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

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

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

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

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

13703 {
13704    int res = 0;
13705    struct iax2_dpcache *dp = NULL;
13706 #if 0
13707    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13708 #endif
13709    if ((priority != 1) && (priority != 2))
13710       return 0;
13711 
13712    AST_LIST_LOCK(&dpcache);
13713    if ((dp = find_cache(chan, data, context, exten, priority))) {
13714       if (dp->flags & CACHE_FLAG_MATCHMORE)
13715          res = 1;
13716    } else {
13717       ast_log(LOG_WARNING, "Unable to make DP cache\n");
13718    }
13719    AST_LIST_UNLOCK(&dpcache);
13720 
13721    return res;
13722 }

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

Definition at line 11897 of file chan_iax2.c.

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

Referenced by iax2_poke_peer().

11898 {
11899    struct iax2_peer *peer = (struct iax2_peer *)data;
11900    peer->pokeexpire = -1;
11901 #ifdef SCHED_MULTITHREADED
11902    if (schedule_action(__iax2_poke_noanswer, data))
11903 #endif      
11904       __iax2_poke_noanswer(data);
11905    peer_unref(peer);
11906    return 0;
11907 }

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

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

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

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

Definition at line 11909 of file chan_iax2.c.

References iax2_poke_peer().

Referenced by load_module().

11910 {
11911    struct iax2_peer *peer = obj;
11912 
11913    iax2_poke_peer(peer, 0);
11914 
11915    return 0;
11916 }

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

Definition at line 9057 of file chan_iax2.c.

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

Referenced by __iax2_poke_noanswer(), and socket_process().

09058 {
09059    struct iax2_peer *peer = (struct iax2_peer *)data;
09060    peer->pokeexpire = -1;
09061 #ifdef SCHED_MULTITHREADED
09062    if (schedule_action(__iax2_poke_peer_s, data))
09063 #endif      
09064       __iax2_poke_peer_s(data);
09065    return 0;
09066 }

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

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

static void iax2_process_thread_cleanup ( void *  data  )  [static]

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

11544 {
11545    struct iax2_thread *thread = data;
11546    ast_mutex_destroy(&thread->lock);
11547    ast_cond_destroy(&thread->cond);
11548    ast_mutex_destroy(&thread->init_lock);
11549    ast_cond_destroy(&thread->init_cond);
11550    ast_free(thread);
11551    ast_atomic_dec_and_test(&iaxactivethreadcount);
11552 }

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

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

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

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

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

05332 {
05333    switch (option) {
05334    case AST_OPTION_SECURE_SIGNALING:
05335    case AST_OPTION_SECURE_MEDIA:
05336    {
05337       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05338       ast_mutex_lock(&iaxsl[callno]);
05339       *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05340       ast_mutex_unlock(&iaxsl[callno]);
05341       return 0;
05342    }
05343    default:
05344       return -1;
05345    }
05346 }

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

References ast_log(), ast_null_frame, and LOG_NOTICE.

05349 {
05350    ast_log(LOG_NOTICE, "I should never be called!\n");
05351    return &ast_null_frame;
05352 }

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

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

08499 {
08500    char copy[256];
08501    char *username, *hostname, *secret;
08502    char *porta;
08503    char *stringp=NULL;
08504    
08505    if (!value)
08506       return -1;
08507 
08508    ast_copy_string(copy, value, sizeof(copy));
08509    stringp = copy;
08510    username = strsep(&stringp, "@");
08511    hostname = strsep(&stringp, "@");
08512 
08513    if (!hostname) {
08514       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08515       return -1;
08516    }
08517 
08518    stringp = username;
08519    username = strsep(&stringp, ":");
08520    secret = strsep(&stringp, ":");
08521    stringp = hostname;
08522    hostname = strsep(&stringp, ":");
08523    porta = strsep(&stringp, ":");
08524    
08525    if (porta && !atoi(porta)) {
08526       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08527       return -1;
08528    }
08529 
08530    return iax2_append_register(hostname, username, secret, porta);
08531 }

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

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

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

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

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_AUDIO_MODE, AST_OPTION_DIGIT_DETECT, AST_OPTION_FAX_DETECT, AST_OPTION_FLAG_REQUEST, AST_OPTION_OPRMODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_set_flag64, 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_OPRMODE:
05271       errno = EINVAL;
05272       return -1;
05273    case AST_OPTION_SECURE_SIGNALING:
05274    case AST_OPTION_SECURE_MEDIA:
05275    {
05276       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05277       ast_mutex_lock(&iaxsl[callno]);
05278       if ((*(int *) data)) {
05279          ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05280       } else {
05281          ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05282       }
05283       ast_mutex_unlock(&iaxsl[callno]);
05284       return 0;
05285    }
05286    /* These options are sent to the other side across the network where
05287     * they will be passed to whatever channel is bridged there. Don't
05288     * do anything silly like pass an option that transmits pointers to
05289     * memory on this machine to a remote machine to use */
05290    case AST_OPTION_TONE_VERIFY:
05291    case AST_OPTION_TDD:
05292    case AST_OPTION_RELAXDTMF:
05293    case AST_OPTION_AUDIO_MODE:
05294    case AST_OPTION_DIGIT_DETECT:
05295    case AST_OPTION_FAX_DETECT:
05296    {
05297       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05298       struct chan_iax2_pvt *pvt;
05299 
05300       ast_mutex_lock(&iaxsl[callno]);
05301       pvt = iaxs[callno];
05302 
05303       if (wait_for_peercallno(pvt)) {
05304          ast_mutex_unlock(&iaxsl[callno]);
05305          return -1;
05306       }
05307 
05308       ast_mutex_unlock(&iaxsl[callno]);
05309 
05310       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05311          return -1;
05312       }
05313 
05314       h->flag = AST_OPTION_FLAG_REQUEST;
05315       h->option = htons(option);
05316       memcpy(h->data, data, datalen);
05317       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05318                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
05319                  datalen + sizeof(*h), -1);
05320       ast_free(h);
05321       return res;
05322    }
05323    default:
05324       return -1;
05325    }
05326 
05327    /* Just in case someone does a break instead of a return */
05328    return -1;
05329 }

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

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

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

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

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

05647 {
05648    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05649    struct iax_ie_data ied = { "", };
05650    char tmp[256], *context;
05651    enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05652    ast_copy_string(tmp, dest, sizeof(tmp));
05653    context = strchr(tmp, '@');
05654    if (context) {
05655       *context = '\0';
05656       context++;
05657    }
05658    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05659    if (context)
05660       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05661    ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05662    ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05663    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05664 }

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

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

09112 {
09113    /* Drop when trunk is about 5 seconds idle */
09114    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
09115       return 1;
09116    return 0;
09117 }

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

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

06067 {
06068    struct ast_frame *f;
06069    struct iax2_trunk_peer *tpeer;
06070    void *tmp, *ptr;
06071    struct timeval now;
06072    int res; 
06073    struct ast_iax2_meta_trunk_entry *met;
06074    struct ast_iax2_meta_trunk_mini *mtm;
06075 
06076    f = &fr->af;
06077    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06078    if (tpeer) {
06079       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06080          /* Need to reallocate space */
06081          if (tpeer->trunkdataalloc < trunkmaxsize) {
06082             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06083                ast_mutex_unlock(&tpeer->lock);
06084                return -1;
06085             }
06086             
06087             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06088             tpeer->trunkdata = tmp;
06089             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);
06090          } else {
06091             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));
06092             ast_mutex_unlock(&tpeer->lock);
06093             return -1;
06094          }
06095       }
06096 
06097       /* Append to meta frame */
06098       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06099       if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06100          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06101          mtm->len = htons(f->datalen);
06102          mtm->mini.callno = htons(pvt->callno);
06103          mtm->mini.ts = htons(0xffff & fr->ts);
06104          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06105          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06106       } else {
06107          met = (struct ast_iax2_meta_trunk_entry *)ptr;
06108          /* Store call number and length in meta header */
06109          met->callno = htons(pvt->callno);
06110          met->len = htons(f->datalen);
06111          /* Advance pointers/decrease length past trunk entry header */
06112          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06113          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06114       }
06115       /* Copy actual trunk data */
06116       memcpy(ptr, f->data.ptr, f->datalen);
06117       tpeer->trunkdatalen += f->datalen;
06118 
06119       tpeer->calls++;
06120 
06121       /* track the largest mtu we actually have sent */
06122       if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 
06123          trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 
06124 
06125       /* if we have enough for a full MTU, ship it now without waiting */
06126       if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06127          now = ast_tvnow();
06128          res = send_trunk(tpeer, &now); 
06129          trunk_untimed ++; 
06130       }
06131 
06132       ast_mutex_unlock(&tpeer->lock);
06133    }
06134    return 0;
06135 }

static int iax2_vnak ( int  callno  )  [static]

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

09033 {
09034    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09035 }

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

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

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

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

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

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

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

09255 {
09256    struct ast_channel *chan1, *chan2;
09257    struct iax_dual *d;
09258    struct ast_frame *f;
09259    int ext;
09260    int res;
09261    d = stuff;
09262    chan1 = d->chan1;
09263    chan2 = d->chan2;
09264    ast_free(d);
09265    f = ast_read(chan1);
09266    if (f)
09267       ast_frfree(f);
09268    res = ast_park_call(chan1, chan2, 0, d->parkexten, &ext);
09269    ast_hangup(chan2);
09270    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09271    return NULL;
09272 }

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

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

static int load_objects ( void   )  [static]

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

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

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

Definition at line 5422 of file chan_iax2.c.

References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.

Referenced by iax2_bridge().

05423 {
05424    ast_mutex_lock(&iaxsl[callno0]);
05425    while (ast_mutex_trylock(&iaxsl[callno1])) {
05426       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05427    }
05428 }

static void log_jitterstats ( unsigned short  callno  )  [static]

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

09396 {
09397    int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09398    jb_info jbinfo;
09399 
09400    ast_mutex_lock(&iaxsl[callno]);
09401    if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09402       if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09403          jb_getinfo(iaxs[callno]->jb, &jbinfo);
09404          localjitter = jbinfo.jitter;
09405          localdelay = jbinfo.current - jbinfo.min;
09406          locallost = jbinfo.frames_lost;
09407          locallosspct = jbinfo.losspct/1000;
09408          localdropped = jbinfo.frames_dropped;
09409          localooo = jbinfo.frames_ooo;
09410          localpackets = jbinfo.frames_in;
09411       }
09412       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",
09413          iaxs[callno]->owner->name,
09414          iaxs[callno]->pingtime,
09415          localjitter,
09416          localdelay,
09417          locallost,
09418          locallosspct,
09419          localdropped,
09420          localooo,
09421          localpackets,
09422          iaxs[callno]->remote_rr.jitter,
09423          iaxs[callno]->remote_rr.delay,
09424          iaxs[callno]->remote_rr.losscnt,
09425          iaxs[callno]->remote_rr.losspct/1000,
09426          iaxs[callno]->remote_rr.dropped,
09427          iaxs[callno]->remote_rr.ooo,
09428          iaxs[callno]->remote_rr.packets);
09429       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",
09430          iaxs[callno]->owner->name,
09431          iaxs[callno]->pingtime,
09432          localjitter,
09433          localdelay,
09434          locallost,
09435          locallosspct,
09436          localdropped,
09437          localooo,
09438          localpackets,
09439          iaxs[callno]->remote_rr.jitter,
09440          iaxs[callno]->remote_rr.delay,
09441          iaxs[callno]->remote_rr.losscnt,
09442          iaxs[callno]->remote_rr.losspct/1000,
09443          iaxs[callno]->remote_rr.dropped,
09444          iaxs[callno]->remote_rr.ooo,
09445          iaxs[callno]->remote_rr.packets);
09446    }
09447    ast_mutex_unlock(&iaxsl[callno]);
09448 }

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

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

Referenced by load_module().

06913 {
06914    ast_cli_netstats(s, -1, 0);
06915    astman_append(s, "\r\n");
06916    return RESULT_SUCCESS;
06917 }

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

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

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

callback to display iax peers in manager

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

06952 {
06953    static const char * const a[] = { "iax2", "show", "peers" };
06954    const char *id = astman_get_header(m,"ActionID");
06955    char idtext[256] = "";
06956    int total = 0;
06957 
06958    if (!ast_strlen_zero(id))
06959       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06960 
06961    astman_send_listack(s, m, "Peer status list will follow", "start");
06962         /* List the peers in separate manager events */
06963    __iax2_show_peers(-1, &total, s, 3, a);
06964         /* Send final confirmation */
06965         astman_append(s,
06966         "Event: PeerlistComplete\r\n"
06967         "EventList: Complete\r\n"
06968         "ListItems: %d\r\n"
06969         "%s"
06970         "\r\n", total, idtext);
06971         return 0;
06972 }

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

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

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

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

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

Referenced by decode_frame().

06166 {
06167 #if 0
06168    /* Debug with "fake encryption" */
06169    int x;
06170    if (len % 16)
06171       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06172    for (x=0;x<len;x++)
06173       dst[x] = src[x] ^ 0xff;
06174 #else 
06175    unsigned char lastblock[16] = { 0 };
06176    int x;
06177    while(len > 0) {
06178       ast_aes_decrypt(src, dst, dcx);
06179       for (x=0;x<16;x++)
06180          dst[x] ^= lastblock[x];
06181       memcpy(lastblock, src, sizeof(lastblock));
06182       dst += 16;
06183       src += 16;
06184       len -= 16;
06185    }
06186 #endif
06187 }

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

Definition at line 6189 of file chan_iax2.c.

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

Referenced by encrypt_frame().

06190 {
06191 #if 0
06192    /* Debug with "fake encryption" */
06193    int x;
06194    if (len % 16)
06195       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06196    for (x=0;x<len;x++)
06197       dst[x] = src[x] ^ 0xff;
06198 #else
06199    unsigned char curblock[16] = { 0 };
06200    int x;
06201    while(len > 0) {
06202       for (x=0;x<16;x++)
06203          curblock[x] ^= src[x];
06204       ast_aes_encrypt(curblock, dst, ecx);
06205       memcpy(curblock, dst, sizeof(curblock)); 
06206       dst += 16;
06207       src += 16;
06208       len -= 16;
06209    }
06210 #endif
06211 }

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

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

07756 {
07757    /* Select exactly one common encryption if there are any */
07758    p->encmethods &= enc;
07759    if (p->encmethods) {
07760       if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */
07761          p->keyrotateid = -2;
07762       }
07763       if (p->encmethods & IAX_ENCRYPT_AES128)
07764          p->encmethods = IAX_ENCRYPT_AES128;
07765       else
07766          p->encmethods = 0;
07767    }
07768 }

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

12078 {
12079    if (timer) {
12080       ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12081    }
12082 
12083    for (;;) {
12084       pthread_testcancel();
12085       /* Wake up once a second just in case SIGURG was sent while
12086        * we weren't in poll(), to make sure we don't hang when trying
12087        * to unload. */
12088       ast_io_wait(io, 1000);
12089    }
12090 
12091    return NULL;
12092 }

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

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

12822 {
12823    struct iax2_peer *peer = obj;
12824 
12825    ast_set_flag64(peer, IAX_DELME);
12826 
12827    return 0;
12828 }

static void peer_destructor ( void *  obj  )  [static]

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

12254 {
12255    struct iax2_peer *peer = obj;
12256    int callno = peer->callno;
12257 
12258    ast_free_ha(peer->ha);
12259 
12260    if (callno > 0) {
12261       ast_mutex_lock(&iaxsl[callno]);
12262       iax2_destroy(callno);
12263       ast_mutex_unlock(&iaxsl[callno]);
12264    }
12265 
12266    register_peer_exten(peer, 0);
12267 
12268    if (peer->dnsmgr)
12269       ast_dnsmgr_release(peer->dnsmgr);
12270 
12271    if (peer->mwi_event_sub)
12272       ast_event_unsubscribe(peer->mwi_event_sub);
12273 
12274    ast_string_field_free_memory(peer);
12275 }

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

References iax2_peer::sockfd.

Referenced by load_module().

14299 {
14300    struct iax2_peer *peer = obj;
14301 
14302    if (peer->sockfd < 0)
14303       peer->sockfd = defaultsockfd;
14304 
14305    return 0;
14306 }

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

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

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

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

static void poke_all_peers ( void   )  [static]

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

13388 {
13389    struct ao2_iterator i;
13390    struct iax2_peer *peer;
13391 
13392    i = ao2_iterator_init(peers, 0);
13393    while ((peer = ao2_iterator_next(&i))) {
13394       iax2_poke_peer(peer, 0);
13395       peer_unref(peer);
13396    }
13397    ao2_iterator_destroy(&i);
13398 }

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

12885 {
12886    struct iax2_peer *peer;
12887    struct ao2_iterator i;
12888 
12889    i = ao2_iterator_init(peers, 0);
12890    while ((peer = ao2_iterator_next(&i))) {
12891       if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
12892          unlink_peer(peer);
12893       }
12894       peer_unref(peer);
12895    }
12896    ao2_iterator_destroy(&i);
12897 }

static void prune_users ( void   )  [static]

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

12869 {
12870    struct iax2_user *user;
12871    struct ao2_iterator i;
12872 
12873    i = ao2_iterator_init(users, 0);
12874    while ((user = ao2_iterator_next(&i))) {
12875       if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
12876          ao2_unlink(users, user);
12877       }
12878       user_unref(user);
12879    }
12880    ao2_iterator_destroy(&i);
12881 }

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

Definition at line 14315 of file chan_iax2.c.

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

14316 {
14317    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14318 
14319    /* The frames_received field is used to hold whether we're matching
14320     * against a full frame or not ... */
14321 
14322    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
14323       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14324 }

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

References chan_iax2_pvt::peercallno.

14309 {
14310    const struct chan_iax2_pvt *pvt = obj;
14311 
14312    return pvt->peercallno;
14313 }

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

07737 {
07738    struct ast_iax2_full_hdr fh;
07739    fh.scallno = htons(src | IAX_FLAG_FULL);
07740    fh.dcallno = htons(dst);
07741    fh.ts = 0;
07742    fh.oseqno = 0;
07743    fh.iseqno = 0;
07744    fh.type = AST_FRAME_IAX;
07745    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07746    iax_outputframe(NULL, &fh, 0, sin, 0);
07747 #if 0
07748    if (option_debug)
07749 #endif   
07750       ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07751          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07752    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07753 }

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

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

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

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

08535 {
08536    char multi[256];
08537    char *stringp, *ext;
08538    if (!ast_strlen_zero(regcontext)) {
08539       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08540       stringp = multi;
08541       while((ext = strsep(&stringp, "&"))) {
08542          if (onoff) {
08543             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08544                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08545                        "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08546          } else
08547             ast_context_remove_extension(regcontext, ext, 1, NULL);
08548       }
08549    }
08550 }

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

Verify inbound registration.

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

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

static int registry_authrequest ( int  callno  )  [static]

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

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

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

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

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

static char* regstate2str ( int  regstate  )  [static]

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

07021 {
07022    switch(regstate) {
07023    case REG_STATE_UNREGISTERED:
07024       return "Unregistered";
07025    case REG_STATE_REGSENT:
07026       return "Request Sent";
07027    case REG_STATE_AUTHSENT:
07028       return "Auth. Sent";
07029    case REG_STATE_REGISTERED:
07030       return "Registered";
07031    case REG_STATE_REJECTED:
07032       return "Rejected";
07033    case REG_STATE_TIMEOUT:
07034       return "Timeout";
07035    case REG_STATE_NOAUTH:
07036       return "No Authentication";
07037    default:
07038       return "Unknown";
07039    }
07040 }

static int reload ( void   )  [static]

Definition at line 13448 of file chan_iax2.c.

References reload_config().

13449 {
13450    return reload_config();
13451 }

static int reload_config ( void   )  [static]

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

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

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

09366 {
09367    int i;
09368    unsigned int length, offset = 0;
09369    char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09370 
09371    for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09372       length = ies->ospblocklength[i];
09373       if (length != 0) {
09374          if (length > IAX_MAX_OSPBLOCK_SIZE) {
09375             /* OSP token block length wrong, clear buffer */
09376             offset = 0;
09377             break;
09378          } else {
09379             memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09380             offset += length;
09381          }
09382       } else {
09383          break;
09384       }
09385    }
09386    *(full_osptoken + offset) = '\0';
09387    if (strlen(full_osptoken) != offset) {
09388       /* OSP token length wrong, clear buffer */
09389       *full_osptoken = '\0';
09390    }
09391 
09392    ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09393 }

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

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

09355 {
09356    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09357    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09358    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09359    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09360    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09361    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09362    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09363 }

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

07460 {
07461    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07462 }

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

07479 {
07480    int call_num = i->callno;
07481    /* It is assumed that the callno has already been locked */
07482    iax2_predestroy(i->callno);
07483    if (!iaxs[call_num])
07484       return -1;
07485    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07486 }

static int send_command_immediate ( struct chan_iax2_pvt ,
char  ,
int  ,
unsigned  int,
const unsigned char *  ,
int  ,
int   
) [static]

Definition at line 7488 of file chan_iax2.c.

References __send_command().

Referenced by iax2_vnak(), and socket_process().

07489 {
07490    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07491 }

static int send_command_locked ( unsigned short  callno,
char  ,
int  ,
unsigned  int,
const unsigned char *  ,
int  ,
int   
) [static]

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

07465 {
07466    int res;
07467    ast_mutex_lock(&iaxsl[callno]);
07468    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07469    ast_mutex_unlock(&iaxsl[callno]);
07470    return res;
07471 }

static int send_command_transfer ( struct chan_iax2_pvt ,
char  ,
int  ,
unsigned  int,
const unsigned char *  ,
int   
) [static]

Definition at line 7493 of file chan_iax2.c.

References __send_command().

Referenced by socket_process(), and try_transfer().

07494 {
07495    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07496 }

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

09069 {
09070    int res = 0;
09071    struct iax_frame *fr;
09072    struct ast_iax2_meta_hdr *meta;
09073    struct ast_iax2_meta_trunk_hdr *mth;
09074    int calls = 0;
09075    
09076    /* Point to frame */
09077    fr = (struct iax_frame *)tpeer->trunkdata;
09078    /* Point to meta data */
09079    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09080    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09081    if (tpeer->trunkdatalen) {
09082       /* We're actually sending a frame, so fill the meta trunk header and meta header */
09083       meta->zeros = 0;
09084       meta->metacmd = IAX_META_TRUNK;
09085       if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09086          meta->cmddata = IAX_META_TRUNK_MINI;
09087       else
09088          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09089       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09090       /* And the rest of the ast_iax2 header */
09091       fr->direction = DIRECTION_OUTGRESS;
09092       fr->retrans = -1;
09093       fr->transfer = 0;
09094       /* Any appropriate call will do */
09095       fr->data = fr->afdata;
09096       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09097       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09098       calls = tpeer->calls;
09099 #if 0
09100       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));
09101 #endif      
09102       /* Reset transmit trunk side data */
09103       tpeer->trunkdatalen = 0;
09104       tpeer->calls = 0;
09105    }
09106    if (res < 0)
09107       return res;
09108    return calls;
09109 }

static int set_config ( const char *  config_file,
int  reload 
) [static]

Load configuration.

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

12917 {
12918    struct ast_config *cfg, *ucfg;
12919    format_t capability = iax2_capability;
12920    struct ast_variable *v;
12921    char *cat;
12922    const char *utype;
12923    const char *tosval;
12924    int format;
12925    int portno = IAX_DEFAULT_PORTNO;
12926    int  x;
12927    int mtuv;
12928    int subscribe_network_change = 1;
12929    struct iax2_user *user;
12930    struct iax2_peer *peer;
12931    struct ast_netsock *ns;
12932    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
12933 #if 0
12934    static unsigned short int last_port=0;
12935 #endif
12936 
12937    cfg = ast_config_load(config_file, config_flags);
12938 
12939    if (!cfg) {
12940       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
12941       return -1;
12942    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
12943       ucfg = ast_config_load("users.conf", config_flags);
12944       if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
12945          return 0;
12946       /* Otherwise we need to reread both files */
12947       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12948       if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
12949          ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config_file);
12950          ast_config_destroy(ucfg);
12951          return 0;
12952       }
12953    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
12954       ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config_file);
12955       return 0;
12956    } else { /* iax.conf changed, gotta reread users.conf, too */
12957       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12958       if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
12959          ast_log(LOG_ERROR, "Config file users.conf is in an invalid format.  Aborting.\n");
12960          ast_config_destroy(cfg);
12961          return 0;
12962       }
12963    }
12964 
12965    if (reload) {
12966       set_config_destroy();
12967    }
12968 
12969    /* Reset global codec prefs */
12970    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
12971 
12972    /* Reset Global Flags */
12973    memset(&globalflags, 0, sizeof(globalflags));
12974    ast_set_flag64(&globalflags, IAX_RTUPDATE);
12975    ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
12976 
12977 #ifdef SO_NO_CHECK
12978    nochecksums = 0;
12979 #endif
12980    /* Reset default parking lot */
12981    default_parkinglot[0] = '\0';
12982 
12983    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12984    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12985    global_max_trunk_mtu = MAX_TRUNK_MTU;
12986    global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
12987    global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
12988 
12989    maxauthreq = 3;
12990 
12991    srvlookup = 0;
12992 
12993    v = ast_variable_browse(cfg, "general");
12994 
12995    /* Seed initial tos value */
12996    tosval = ast_variable_retrieve(cfg, "general", "tos");
12997    if (tosval) {
12998       if (ast_str2tos(tosval, &qos.tos))
12999          ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13000    }
13001    /* Seed initial cos value */
13002    tosval = ast_variable_retrieve(cfg, "general", "cos");
13003    if (tosval) {
13004       if (ast_str2cos(tosval, &qos.cos))
13005          ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13006    }
13007    while(v) {
13008       if (!strcasecmp(v->name, "bindport")){ 
13009          if (reload)
13010             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13011          else
13012             portno = atoi(v->value);
13013       } else if (!strcasecmp(v->name, "pingtime")) 
13014          ping_time = atoi(v->value);
13015       else if (!strcasecmp(v->name, "iaxthreadcount")) {
13016          if (reload) {
13017             if (atoi(v->value) != iaxthreadcount)
13018                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13019          } else {
13020             iaxthreadcount = atoi(v->value);
13021             if (iaxthreadcount < 1) {
13022                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13023                iaxthreadcount = 1;
13024             } else if (iaxthreadcount > 256) {
13025                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13026                iaxthreadcount = 256;
13027             }
13028          }
13029       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13030          if (reload) {
13031             AST_LIST_LOCK(&dynamic_list);
13032             iaxmaxthreadcount = atoi(v->value);
13033             AST_LIST_UNLOCK(&dynamic_list);
13034          } else {
13035             iaxmaxthreadcount = atoi(v->value);
13036             if (iaxmaxthreadcount < 0) {
13037                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13038                iaxmaxthreadcount = 0;
13039             } else if (iaxmaxthreadcount > 256) {
13040                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13041                iaxmaxthreadcount = 256;
13042             }
13043          }
13044       } else if (!strcasecmp(v->name, "nochecksums")) {
13045 #ifdef SO_NO_CHECK
13046          if (ast_true(v->value))
13047             nochecksums = 1;
13048          else
13049             nochecksums = 0;
13050 #else
13051          if (ast_true(v->value))
13052             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13053 #endif
13054       }
13055       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
13056          maxjitterbuffer = atoi(v->value);
13057       else if (!strcasecmp(v->name, "resyncthreshold")) 
13058          resyncthreshold = atoi(v->value);
13059       else if (!strcasecmp(v->name, "maxjitterinterps")) 
13060          maxjitterinterps = atoi(v->value);
13061       else if (!strcasecmp(v->name, "jittertargetextra"))
13062          jittertargetextra = atoi(v->value);
13063       else if (!strcasecmp(v->name, "lagrqtime")) 
13064          lagrq_time = atoi(v->value);
13065       else if (!strcasecmp(v->name, "maxregexpire")) 
13066          max_reg_expire = atoi(v->value);
13067       else if (!strcasecmp(v->name, "minregexpire")) 
13068          min_reg_expire = atoi(v->value);
13069       else if (!strcasecmp(v->name, "bindaddr")) {
13070          if (reload) {
13071             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13072          } else {
13073             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13074                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13075             } else {
13076                   if (strchr(v->value, ':'))
13077                   ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13078                   else
13079                   ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13080                if (defaultsockfd < 0) 
13081                   defaultsockfd = ast_netsock_sockfd(ns);
13082                ast_netsock_unref(ns);
13083             }
13084          }
13085       } else if (!strcasecmp(v->name, "authdebug")) {
13086          authdebug = ast_true(v->value);
13087       } else if (!strcasecmp(v->name, "encryption")) {
13088             iax2_encryption |= get_encrypt_methods(v->value);
13089             if (!iax2_encryption) {
13090                ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13091             }
13092       } else if (!strcasecmp(v->name, "forceencryption")) {
13093          if (ast_false(v->value)) {
13094             ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13095          } else {
13096             iax2_encryption |= get_encrypt_methods(v->value);
13097             if (iax2_encryption) {
13098                ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13099             }
13100          }
13101       } else if (!strcasecmp(v->name, "transfer")) {
13102          if (!strcasecmp(v->value, "mediaonly")) {
13103             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13104          } else if (ast_true(v->value)) {
13105             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13106          } else
13107             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13108       } else if (!strcasecmp(v->name, "codecpriority")) {
13109          if(!strcasecmp(v->value, "caller"))
13110             ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13111          else if(!strcasecmp(v->value, "disabled"))
13112             ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13113          else if(!strcasecmp(v->value, "reqonly")) {
13114             ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13115             ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13116          }
13117       } else if (!strcasecmp(v->name, "jitterbuffer"))
13118          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13119       else if (!strcasecmp(v->name, "forcejitterbuffer"))
13120          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13121       else if (!strcasecmp(v->name, "delayreject"))
13122          delayreject = ast_true(v->value);
13123       else if (!strcasecmp(v->name, "allowfwdownload"))
13124          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13125       else if (!strcasecmp(v->name, "rtcachefriends"))
13126          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13127       else if (!strcasecmp(v->name, "rtignoreregexpire"))
13128          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13129       else if (!strcasecmp(v->name, "rtupdate"))
13130          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13131       else if (!strcasecmp(v->name, "rtsavesysname"))
13132          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13133       else if (!strcasecmp(v->name, "trunktimestamps"))
13134          ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13135       else if (!strcasecmp(v->name, "rtautoclear")) {
13136          int i = atoi(v->value);
13137          if(i > 0)
13138             global_rtautoclear = i;
13139          else
13140             i = 0;
13141          ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13142       } else if (!strcasecmp(v->name, "trunkfreq")) {
13143          trunkfreq = atoi(v->value);
13144          if (trunkfreq < 10)
13145             trunkfreq = 10;
13146       } else if (!strcasecmp(v->name, "trunkmtu")) {
13147          mtuv = atoi(v->value);
13148          if (mtuv  == 0 )
13149             global_max_trunk_mtu = 0;
13150          else if (mtuv >= 172 && mtuv < 4000)
13151             global_max_trunk_mtu = mtuv;
13152          else
13153             ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13154                mtuv, v->lineno);
13155       } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13156          trunkmaxsize = atoi(v->value);
13157          if (trunkmaxsize == 0)
13158             trunkmaxsize = MAX_TRUNKDATA;
13159       } else if (!strcasecmp(v->name, "autokill")) {
13160          if (sscanf(v->value, "%30d", &x) == 1) {
13161             if (x >= 0)
13162                autokill = x;
13163             else
13164                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13165          } else if (ast_true(v->value)) {
13166             autokill = DEFAULT_MAXMS;
13167          } else {
13168             autokill = 0;
13169          }
13170       } else if (!strcasecmp(v->name, "bandwidth")) {
13171          if (!strcasecmp(v->value, "low")) {
13172             capability = IAX_CAPABILITY_LOWBANDWIDTH;
13173          } else if (!strcasecmp(v->value, "medium")) {
13174             capability = IAX_CAPABILITY_MEDBANDWIDTH;
13175          } else if (!strcasecmp(v->value, "high")) {
13176             capability = IAX_CAPABILITY_FULLBANDWIDTH;
13177          } else
13178             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13179       } else if (!strcasecmp(v->name, "allow")) {
13180          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13181       } else if (!strcasecmp(v->name, "disallow")) {
13182          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13183       } else if (!strcasecmp(v->name, "register")) {
13184          iax2_register(v->value, v->lineno);
13185       } else if (!strcasecmp(v->name, "iaxcompat")) {
13186          iaxcompat = ast_true(v->value);
13187       } else if (!strcasecmp(v->name, "regcontext")) {
13188          ast_copy_string(regcontext, v->value, sizeof(regcontext));
13189          /* Create context if it doesn't exist already */
13190          ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13191       } else if (!strcasecmp(v->name, "tos")) {
13192          if (ast_str2tos(v->value, &qos.tos))
13193             ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13194       } else if (!strcasecmp(v->name, "cos")) {
13195          if (ast_str2cos(v->value, &qos.cos))
13196             ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13197       } else if (!strcasecmp(v->name, "parkinglot")) {
13198          ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13199       } else if (!strcasecmp(v->name, "accountcode")) {
13200          ast_copy_string(accountcode, v->value, sizeof(accountcode));
13201       } else if (!strcasecmp(v->name, "mohinterpret")) {
13202          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13203       } else if (!strcasecmp(v->name, "mohsuggest")) {
13204          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13205       } else if (!strcasecmp(v->name, "amaflags")) {
13206          format = ast_cdr_amaflags2int(v->value);
13207          if (format < 0) {
13208             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13209          } else {
13210             amaflags = format;
13211          }
13212       } else if (!strcasecmp(v->name, "language")) {
13213          ast_copy_string(language, v->value, sizeof(language));
13214       } else if (!strcasecmp(v->name, "maxauthreq")) {
13215          maxauthreq = atoi(v->value);
13216          if (maxauthreq < 0)
13217             maxauthreq = 0;
13218       } else if (!strcasecmp(v->name, "adsi")) {
13219          adsi = ast_true(v->value);
13220       } else if (!strcasecmp(v->name, "srvlookup")) {
13221          srvlookup = ast_true(v->value);
13222       } else if (!strcasecmp(v->name, "connectedline")) {
13223          if (ast_true(v->value)) {
13224             ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13225          } else if (!strcasecmp(v->value, "send")) {
13226             ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13227             ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13228          } else if (!strcasecmp(v->value, "receive")) {
13229             ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13230             ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13231          } else {
13232             ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13233          }
13234       } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13235          if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13236             ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number.  %s is not valid at line %d\n", v->value, v->lineno);
13237          }
13238       } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13239          if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13240             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);
13241          }
13242       } else if (!strcasecmp(v->name, "calltokenoptional")) {
13243          if (add_calltoken_ignore(v->value)) {
13244             ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13245          }
13246       } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13247          if (ast_true(v->value)) {
13248             subscribe_network_change = 1;
13249          } else if (ast_false(v->value)) {
13250             subscribe_network_change = 0;
13251          } else {
13252             ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13253          }
13254       } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13255          if (ast_true(v->value)) {
13256             ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13257          } else if (ast_false(v->value)) {
13258             ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13259          } else {
13260             ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13261          }
13262       }/*else if (strcasecmp(v->name,"type")) */
13263       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13264       v = v->next;
13265    }
13266 
13267    if (subscribe_network_change) {
13268       network_change_event_subscribe();
13269    } else {
13270       network_change_event_unsubscribe();
13271    }
13272 
13273    if (defaultsockfd < 0) {
13274       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13275          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13276       } else {
13277          ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13278          defaultsockfd = ast_netsock_sockfd(ns);
13279          ast_netsock_unref(ns);
13280       }
13281    }
13282    if (reload) {
13283       ast_netsock_release(outsock);
13284       outsock = ast_netsock_list_alloc();
13285       if (!outsock) {
13286          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13287          return -1;
13288       }
13289       ast_netsock_init(outsock);
13290    }
13291 
13292    if (min_reg_expire > max_reg_expire) {
13293       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13294          min_reg_expire, max_reg_expire, max_reg_expire);
13295       min_reg_expire = max_reg_expire;
13296    }
13297    iax2_capability = capability;
13298    
13299    if (ucfg) {
13300       struct ast_variable *gen;
13301       int genhasiax;
13302       int genregisteriax;
13303       const char *hasiax, *registeriax;
13304       
13305       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13306       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13307       gen = ast_variable_browse(ucfg, "general");
13308       cat = ast_category_browse(ucfg, NULL);
13309       while (cat) {
13310          if (strcasecmp(cat, "general")) {
13311             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13312             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13313             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13314                /* Start with general parameters, then specific parameters, user and peer */
13315                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13316                if (user) {
13317                   ao2_link(users, user);
13318                   user = user_unref(user);
13319                }
13320                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13321                if (peer) {
13322                   if (ast_test_flag64(peer, IAX_DYNAMIC))
13323                      reg_source_db(peer);
13324                   ao2_link(peers, peer);
13325                   peer = peer_unref(peer);
13326                }
13327             }
13328             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13329                char tmp[256];
13330                const char *host = ast_variable_retrieve(ucfg, cat, "host");
13331                const char *username = ast_variable_retrieve(ucfg, cat, "username");
13332                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13333                if (!host)
13334                   host = ast_variable_retrieve(ucfg, "general", "host");
13335                if (!username)
13336                   username = ast_variable_retrieve(ucfg, "general", "username");
13337                if (!secret)
13338                   secret = ast_variable_retrieve(ucfg, "general", "secret");
13339                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13340                   if (!ast_strlen_zero(secret))
13341                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13342                   else
13343                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13344                   iax2_register(tmp, 0);
13345                }
13346             }
13347          }
13348          cat = ast_category_browse(ucfg, cat);
13349       }
13350       ast_config_destroy(ucfg);
13351    }
13352    
13353    cat = ast_category_browse(cfg, NULL);
13354    while(cat) {
13355       if (strcasecmp(cat, "general")) {
13356          utype = ast_variable_retrieve(cfg, cat, "type");
13357          if (!strcasecmp(cat, "callnumberlimits")) {
13358             build_callno_limits(ast_variable_browse(cfg, cat));
13359          } else if (utype) {
13360             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13361                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13362                if (user) {
13363                   ao2_link(users, user);
13364                   user = user_unref(user);
13365                }
13366             }
13367             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13368                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13369                if (peer) {
13370                   if (ast_test_flag64(peer, IAX_DYNAMIC))
13371                      reg_source_db(peer);
13372                   ao2_link(peers, peer);
13373                   peer = peer_unref(peer);
13374                }
13375             } else if (strcasecmp(utype, "user")) {
13376                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13377             }
13378          } else
13379             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13380       }
13381       cat = ast_category_browse(cfg, cat);
13382    }
13383    ast_config_destroy(cfg);
13384    return 1;
13385 }

static void set_config_destroy ( void   )  [static]

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

09791 {
09792    iax2_lock_owner(callno);
09793    if (iaxs[callno] && iaxs[callno]->owner) {
09794       if (causecode) {
09795          iaxs[callno]->owner->hangupcause = causecode;
09796       }
09797       ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0);
09798       ast_channel_unlock(iaxs[callno]->owner);
09799    }
09800 }

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

09803 {
09804    struct sockaddr_in sin;
09805    int res;
09806    int updatehistory=1;
09807    int new = NEW_PREVENT;
09808    int dcallno = 0;
09809    char decrypted = 0;
09810    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09811    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09812    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09813    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09814    struct iax_frame *fr;
09815    struct iax_frame *cur;
09816    struct ast_frame f = { 0, };
09817    struct ast_channel *c = NULL;
09818    struct iax2_dpcache *dp;
09819    struct iax2_peer *peer;
09820    struct iax_ies ies;
09821    struct iax_ie_data ied0, ied1;
09822    format_t format;
09823    int fd;
09824    int exists;
09825    int minivid = 0;
09826    char empty[32]="";      /* Safety measure */
09827    struct iax_frame *duped_fr;
09828    char host_pref_buf[128];
09829    char caller_pref_buf[128];
09830    struct ast_codec_pref pref;
09831    char *using_prefs = "mine";
09832 
09833    /* allocate an iax_frame with 4096 bytes of data buffer */
09834    fr = alloca(sizeof(*fr) + 4096);
09835    memset(fr, 0, sizeof(*fr));
09836    fr->afdatalen = 4096; /* From alloca() above */
09837 
09838    /* Copy frequently used parameters to the stack */
09839    res = thread->buf_len;
09840    fd = thread->iofd;
09841    memcpy(&sin, &thread->iosin, sizeof(sin));
09842 
09843    if (res < sizeof(*mh)) {
09844       ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09845       return 1;
09846    }
09847    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09848       if (res < sizeof(*vh)) {
09849          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));
09850          return 1;
09851       }
09852 
09853       /* This is a video frame, get call number */
09854       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09855       minivid = 1;
09856    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09857       return socket_process_meta(res, meta, &sin, fd, fr);
09858 
09859 #ifdef DEBUG_SUPPORT
09860    if (res >= sizeof(*fh))
09861       iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09862 #endif
09863    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09864       if (res < sizeof(*fh)) {
09865          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));
09866          return 1;
09867       }
09868 
09869       /* Get the destination call number */
09870       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09871 
09872 
09873       /* check to make sure this full frame isn't encrypted before we attempt
09874        * to look inside of it. If it is encrypted, decrypt it first. Its ok if the
09875        * callno is not found here, that just means one hasn't been allocated for
09876        * this connection yet. */
09877       if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09878          ast_mutex_lock(&iaxsl[fr->callno]);
09879          if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
09880             if (decrypt_frame(fr->callno, fh, &f, &res)) {
09881                ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09882                ast_mutex_unlock(&iaxsl[fr->callno]);
09883                return 1;
09884             }
09885             decrypted = 1;
09886          }
09887          ast_mutex_unlock(&iaxsl[fr->callno]);
09888       }
09889 
09890       /* Retrieve the type and subclass */
09891       f.frametype = fh->type;
09892       if (f.frametype == AST_FRAME_VIDEO) {
09893          f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09894       } else if (f.frametype == AST_FRAME_VOICE) {
09895          f.subclass.codec = uncompress_subclass(fh->csub);
09896       } else {
09897          f.subclass.integer = uncompress_subclass(fh->csub);
09898       }
09899 
09900       /* Deal with POKE/PONG without allocating a callno */
09901       if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
09902          /* Reply back with a PONG, but don't care about the result. */
09903          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09904          return 1;
09905       } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
09906          /* Ignore */
09907          return 1;
09908       }
09909 
09910       f.datalen = res - sizeof(*fh);
09911       if (f.datalen) {
09912          if (f.frametype == AST_FRAME_IAX) {
09913             if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09914                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09915                ast_variables_destroy(ies.vars);
09916                return 1;
09917             }
09918             f.data.ptr = NULL;
09919             f.datalen = 0;
09920          } else {
09921             f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09922             memset(&ies, 0, sizeof(ies));
09923          }
09924       } else {
09925          if (f.frametype == AST_FRAME_IAX)
09926             f.data.ptr = NULL;
09927          else
09928             f.data.ptr = empty;
09929          memset(&ies, 0, sizeof(ies));
09930       }
09931 
09932       if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
09933          /* only set NEW_ALLOW if calltoken checks out */
09934          if (handle_call_token(fh, &ies, &sin, fd)) {
09935             ast_variables_destroy(ies.vars);
09936             return 1;
09937          }
09938 
09939          if (ies.calltoken && ies.calltokendata) {
09940             /* if we've gotten this far, and the calltoken ie data exists,
09941              * then calltoken validation _MUST_ have taken place.  If calltoken
09942              * data is provided, it is always validated reguardless of any
09943              * calltokenoptional or requirecalltoken options */
09944             new = NEW_ALLOW_CALLTOKEN_VALIDATED;
09945          } else {
09946             new = NEW_ALLOW;
09947          }
09948       }
09949    } else {
09950       /* Don't know anything about it yet */
09951       f.frametype = AST_FRAME_NULL;
09952       f.subclass.integer = 0;
09953       memset(&ies, 0, sizeof(ies));
09954    }
09955 
09956    if (!fr->callno) {
09957       int check_dcallno = 0;
09958 
09959       /*
09960        * We enforce accurate destination call numbers for ACKs.  This forces the other
09961        * end to know the destination call number before call setup can complete.
09962        *
09963        * Discussed in the following thread:
09964        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
09965        */
09966 
09967       if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
09968          check_dcallno = 1;
09969       }
09970 
09971       if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
09972          if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
09973             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09974          } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
09975             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09976          }
09977          ast_variables_destroy(ies.vars);
09978          return 1;
09979       }
09980    }
09981 
09982    if (fr->callno > 0)
09983       ast_mutex_lock(&iaxsl[fr->callno]);
09984 
09985    if (!fr->callno || !iaxs[fr->callno]) {
09986       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
09987          frame, reply with an inval */
09988       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09989          /* We can only raw hangup control frames */
09990          if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
09991              (f.subclass.integer != IAX_COMMAND_TXCNT) &&
09992              (f.subclass.integer != IAX_COMMAND_TXACC) &&
09993              (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
09994              (f.frametype != AST_FRAME_IAX))
09995             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
09996             fd);
09997       }
09998       if (fr->callno > 0) 
09999          ast_mutex_unlock(&iaxsl[fr->callno]);
10000       ast_variables_destroy(ies.vars);
10001       return 1;
10002    }
10003    if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10004       if (decrypt_frame(fr->callno, fh, &f, &res)) {
10005          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10006          ast_variables_destroy(ies.vars);
10007          ast_mutex_unlock(&iaxsl[fr->callno]);
10008          return 1;
10009       }
10010       decrypted = 1;
10011    }
10012 
10013 #ifdef DEBUG_SUPPORT
10014    if (decrypted) {
10015       iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10016    }
10017 #endif
10018 
10019 
10020    /* count this frame */
10021    iaxs[fr->callno]->frames_received++;
10022 
10023    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10024       f.subclass.integer != IAX_COMMAND_TXCNT &&      /* for attended transfer */
10025       f.subclass.integer != IAX_COMMAND_TXACC) {      /* for attended transfer */
10026       unsigned short new_peercallno;
10027       
10028       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10029       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10030          if (iaxs[fr->callno]->peercallno) {
10031             remove_by_peercallno(iaxs[fr->callno]);
10032          }
10033          iaxs[fr->callno]->peercallno = new_peercallno;
10034          store_by_peercallno(iaxs[fr->callno]);
10035       }
10036    }
10037    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10038       if (iaxdebug)
10039          ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10040       /* Check if it's out of order (and not an ACK or INVAL) */
10041       fr->oseqno = fh->oseqno;
10042       fr->iseqno = fh->iseqno;
10043       fr->ts = ntohl(fh->ts);
10044 #ifdef IAXTESTS
10045       if (test_resync) {
10046          ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10047          fr->ts += test_resync;
10048       }
10049 #endif /* IAXTESTS */
10050 #if 0
10051       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10052            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10053                         (f.subclass == IAX_COMMAND_NEW ||
10054                          f.subclass == IAX_COMMAND_AUTHREQ ||
10055                          f.subclass == IAX_COMMAND_ACCEPT ||
10056                          f.subclass == IAX_COMMAND_REJECT))      ) )
10057 #endif
10058       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10059          updatehistory = 0;
10060       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10061          (iaxs[fr->callno]->iseqno ||
10062             ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10063             (f.subclass.integer != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
10064             (f.subclass.integer != IAX_COMMAND_TXREL) &&    /* for attended transfer */
10065             (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
10066             (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10067             (f.frametype != AST_FRAME_IAX))) {
10068          if (
10069           ((f.subclass.integer != IAX_COMMAND_ACK) &&
10070            (f.subclass.integer != IAX_COMMAND_INVAL) &&
10071            (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10072            (f.subclass.integer != IAX_COMMAND_TXREADY) &&      /* for attended transfer */
10073            (f.subclass.integer != IAX_COMMAND_TXREL) &&     /* for attended transfer */
10074            (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
10075            (f.subclass.integer != IAX_COMMAND_TXACC) &&
10076            (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10077            (f.frametype != AST_FRAME_IAX)) {
10078             /* If it's not an ACK packet, it's out of order. */
10079             ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
10080                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10081             /* Check to see if we need to request retransmission,
10082              * and take sequence number wraparound into account */
10083             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10084                /* If we've already seen it, ack it XXX There's a border condition here XXX */
10085                if ((f.frametype != AST_FRAME_IAX) || 
10086                      ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10087                   ast_debug(1, "Acking anyway\n");
10088                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
10089                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
10090                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10091                }
10092             } else {
10093                /* Send a VNAK requesting retransmission */
10094                iax2_vnak(fr->callno);
10095             }
10096             ast_variables_destroy(ies.vars);
10097             ast_mutex_unlock(&iaxsl[fr->callno]);
10098             return 1;
10099          }
10100       } else {
10101          /* Increment unless it's an ACK or VNAK */
10102          if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10103              (f.subclass.integer != IAX_COMMAND_INVAL) &&
10104              (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10105              (f.subclass.integer != IAX_COMMAND_TXACC) &&
10106             (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10107              (f.frametype != AST_FRAME_IAX))
10108             iaxs[fr->callno]->iseqno++;
10109       }
10110       /* Ensure text frames are NULL-terminated */
10111       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10112          if (res < thread->buf_size)
10113             thread->buf[res++] = '\0';
10114          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
10115             thread->buf[res - 1] = '\0';
10116       }
10117 
10118       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
10119          from the real peer, not the transfer peer */
10120       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
10121           ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10122            (f.frametype != AST_FRAME_IAX))) {
10123          unsigned char x;
10124          int call_to_destroy;
10125          /* First we have to qualify that the ACKed value is within our window */
10126          if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10127             x = fr->iseqno;
10128          else 
10129             x = iaxs[fr->callno]->oseqno;
10130          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10131             /* The acknowledgement is within our window.  Time to acknowledge everything
10132                that it says to */
10133             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10134                /* Ack the packet with the given timestamp */
10135                if (iaxdebug)
10136                   ast_debug(1, "Cancelling transmission of packet %d\n", x);
10137                call_to_destroy = 0;
10138                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10139                   /* If it's our call, and our timestamp, mark -1 retries */
10140                   if (x == cur->oseqno) {
10141                      cur->retries = -1;
10142                      /* Destroy call if this is the end */
10143                      if (cur->final)
10144                         call_to_destroy = fr->callno;
10145                   }
10146                }
10147                if (call_to_destroy) {
10148                   if (iaxdebug)
10149                      ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10150                   ast_mutex_lock(&iaxsl[call_to_destroy]);
10151                   iax2_destroy(call_to_destroy);
10152                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
10153                }
10154             }
10155             /* Note how much we've received acknowledgement for */
10156             if (iaxs[fr->callno])
10157                iaxs[fr->callno]->rseqno = fr->iseqno;
10158             else {
10159                /* Stop processing now */
10160                ast_variables_destroy(ies.vars);
10161                ast_mutex_unlock(&iaxsl[fr->callno]);
10162                return 1;
10163             }
10164          } else {
10165             ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10166          }
10167       }
10168       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
10169          ((f.frametype != AST_FRAME_IAX) || 
10170           ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10171            (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10172          /* Only messages we accept from a transfer host are TXACC and TXCNT */
10173          ast_variables_destroy(ies.vars);
10174          ast_mutex_unlock(&iaxsl[fr->callno]);
10175          return 1;
10176       }
10177 
10178       /* when we receive the first full frame for a new incoming channel,
10179          it is safe to start the PBX on the channel because we have now
10180          completed a 3-way handshake with the peer */
10181       if ((f.frametype == AST_FRAME_VOICE) ||
10182           (f.frametype == AST_FRAME_VIDEO) ||
10183           (f.frametype == AST_FRAME_IAX)) {
10184          if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10185             ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10186             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
10187                ast_variables_destroy(ies.vars);
10188                ast_mutex_unlock(&iaxsl[fr->callno]);
10189                return 1;
10190             }
10191          }
10192 
10193          if (ies.vars) {
10194             struct ast_datastore *variablestore = NULL;
10195             struct ast_variable *var, *prev = NULL;
10196             AST_LIST_HEAD(, ast_var_t) *varlist;
10197 
10198             iax2_lock_owner(fr->callno);
10199             if (!iaxs[fr->callno]) {
10200                ast_variables_destroy(ies.vars);
10201                ast_mutex_unlock(&iaxsl[fr->callno]);
10202                return 1;
10203             }
10204             if ((c = iaxs[fr->callno]->owner)) {
10205                varlist = ast_calloc(1, sizeof(*varlist));
10206                variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10207 
10208                if (variablestore && varlist) {
10209                   variablestore->data = varlist;
10210                   variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10211                   AST_LIST_HEAD_INIT(varlist);
10212                   ast_debug(1, "I can haz IAX vars?\n");
10213                   for (var = ies.vars; var; var = var->next) {
10214                      struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10215                      if (prev) {
10216                         ast_free(prev);
10217                      }
10218                      prev = var;
10219                      if (!newvar) {
10220                         /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
10221                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10222                      } else {
10223                         AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10224                      }
10225                   }
10226                   if (prev) {
10227                      ast_free(prev);
10228                   }
10229                   ies.vars = NULL;
10230                   ast_channel_datastore_add(c, variablestore);
10231                } else {
10232                   ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10233                   if (variablestore) {
10234                      ast_datastore_free(variablestore);
10235                   }
10236                   if (varlist) {
10237                      ast_free(varlist);
10238                   }
10239                }
10240                ast_channel_unlock(c);
10241             } else {
10242                /* No channel yet, so transfer the variables directly over to the pvt,
10243                 * for later inheritance. */
10244                ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10245                for (var = ies.vars; var && var->next; var = var->next);
10246                if (var) {
10247                   var->next = iaxs[fr->callno]->iaxvars;
10248                   iaxs[fr->callno]->iaxvars = ies.vars;
10249                   ies.vars = NULL;
10250                }
10251             }
10252          }
10253 
10254          if (ies.vars) {
10255             ast_debug(1, "I have IAX variables, but they were not processed\n");
10256          }
10257       }
10258 
10259       /* once we receive our first IAX Full Frame that is not CallToken related, send all
10260        * queued signaling frames that were being held. */
10261       if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10262          send_signaling(iaxs[fr->callno]);
10263       }
10264 
10265       if (f.frametype == AST_FRAME_VOICE) {
10266          if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10267                iaxs[fr->callno]->voiceformat = f.subclass.codec;
10268                ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10269                if (iaxs[fr->callno]->owner) {
10270                   iax2_lock_owner(fr->callno);
10271                   if (iaxs[fr->callno]) {
10272                      if (iaxs[fr->callno]->owner) {
10273                         format_t orignative;
10274 
10275                         orignative = iaxs[fr->callno]->owner->nativeformats;
10276                         iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10277                         if (iaxs[fr->callno]->owner->readformat)
10278                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10279                         iaxs[fr->callno]->owner->nativeformats = orignative;
10280                         ast_channel_unlock(iaxs[fr->callno]->owner);
10281                      }
10282                   } else {
10283                      ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10284                      /* Free remote variables (if any) */
10285                      if (ies.vars) {
10286                         ast_variables_destroy(ies.vars);
10287                         ast_debug(1, "I can haz iaxvars, but they is no good.  :-(\n");
10288                         ies.vars = NULL;
10289                      }
10290                      ast_mutex_unlock(&iaxsl[fr->callno]);
10291                      return 1;
10292                   }
10293                }
10294          }
10295       }
10296       if (f.frametype == AST_FRAME_VIDEO) {
10297          if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10298             ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10299             iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10300          }
10301       }
10302       if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10303          if (f.subclass.integer == AST_CONTROL_BUSY) {
10304             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10305          } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
10306             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10307          }
10308       }
10309       if (f.frametype == AST_FRAME_IAX) {
10310          ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10311          /* Handle the IAX pseudo frame itself */
10312          if (iaxdebug)
10313             ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10314 
10315                         /* Update last ts unless the frame's timestamp originated with us. */
10316          if (iaxs[fr->callno]->last < fr->ts &&
10317                             f.subclass.integer != IAX_COMMAND_ACK &&
10318                             f.subclass.integer != IAX_COMMAND_PONG &&
10319                             f.subclass.integer != IAX_COMMAND_LAGRP) {
10320             iaxs[fr->callno]->last = fr->ts;
10321             if (iaxdebug)
10322                ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10323          }
10324          iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10325          if (!iaxs[fr->callno]->first_iax_message) {
10326             iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10327          }
10328          switch(f.subclass.integer) {
10329          case IAX_COMMAND_ACK:
10330             /* Do nothing */
10331             break;
10332          case IAX_COMMAND_QUELCH:
10333             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10334                     /* Generate Manager Hold event, if necessary*/
10335                if (iaxs[fr->callno]->owner) {
10336                   ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10337                      "Status: On\r\n"
10338                      "Channel: %s\r\n"
10339                      "Uniqueid: %s\r\n",
10340                      iaxs[fr->callno]->owner->name,
10341                      iaxs[fr->callno]->owner->uniqueid);
10342                }
10343 
10344                ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10345                if (ies.musiconhold) {
10346                   iax2_lock_owner(fr->callno);
10347                   if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10348                      break;
10349                   }
10350                   if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10351                      const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10352 
10353                      /*
10354                       * We already hold the owner lock so we do not
10355                       * need to check iaxs[fr->callno] after it returns.
10356                       */
10357                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
10358                         S_OR(moh_suggest, NULL),
10359                         !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10360                   }
10361                   ast_channel_unlock(iaxs[fr->callno]->owner);
10362                }
10363             }
10364             break;
10365          case IAX_COMMAND_UNQUELCH:
10366             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10367                iax2_lock_owner(fr->callno);
10368                if (!iaxs[fr->callno]) {
10369                   break;
10370                }
10371                /* Generate Manager Unhold event, if necessary */
10372                if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10373                   ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10374                      "Status: Off\r\n"
10375                      "Channel: %s\r\n"
10376                      "Uniqueid: %s\r\n",
10377                      iaxs[fr->callno]->owner->name,
10378                      iaxs[fr->callno]->owner->uniqueid);
10379                }
10380 
10381                ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10382                if (!iaxs[fr->callno]->owner) {
10383                   break;
10384                }
10385                if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10386                   /*
10387                    * We already hold the owner lock so we do not
10388                    * need to check iaxs[fr->callno] after it returns.
10389                    */
10390                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10391                }
10392                ast_channel_unlock(iaxs[fr->callno]->owner);
10393             }
10394             break;
10395          case IAX_COMMAND_TXACC:
10396             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10397                /* Ack the packet with the given timestamp */
10398                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10399                   /* Cancel any outstanding txcnt's */
10400                   if (cur->transfer) {
10401                      cur->retries = -1;
10402                   }
10403                }
10404                memset(&ied1, 0, sizeof(ied1));
10405                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10406                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10407                iaxs[fr->callno]->transferring = TRANSFER_READY;
10408             }
10409             break;
10410          case IAX_COMMAND_NEW:
10411             /* Ignore if it's already up */
10412             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10413                break;
10414             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10415                ast_mutex_unlock(&iaxsl[fr->callno]);
10416                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10417                ast_mutex_lock(&iaxsl[fr->callno]);
10418                if (!iaxs[fr->callno]) {
10419                   break;
10420                }
10421             }
10422             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
10423             if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10424                int new_callno;
10425                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10426                   fr->callno = new_callno;
10427             }
10428             /* For security, always ack immediately */
10429             if (delayreject)
10430                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10431             if (check_access(fr->callno, &sin, &ies)) {
10432                /* They're not allowed on */
10433                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10434                if (authdebug)
10435                   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);
10436                break;
10437             }
10438             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10439                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10440                ast_log(LOG_WARNING, "Rejected connect attempt.  No secret present while force encrypt enabled.\n");
10441                break;
10442             }
10443             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10444                const char *context, *exten, *cid_num;
10445 
10446                context = ast_strdupa(iaxs[fr->callno]->context);
10447                exten = ast_strdupa(iaxs[fr->callno]->exten);
10448                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10449 
10450                /* This might re-enter the IAX code and need the lock */
10451                ast_mutex_unlock(&iaxsl[fr->callno]);
10452                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10453                ast_mutex_lock(&iaxsl[fr->callno]);
10454 
10455                if (!iaxs[fr->callno]) {
10456                   break;
10457                }
10458             } else
10459                exists = 0;
10460             /* Get OSP token if it does exist */
10461             save_osptoken(fr, &ies);
10462             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10463                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10464                   memset(&ied0, 0, sizeof(ied0));
10465                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10466                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10467                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10468                   if (!iaxs[fr->callno]) {
10469                      break;
10470                   }
10471                   if (authdebug)
10472                      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);
10473                } else {
10474                   /* Select an appropriate format */
10475 
10476                   if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10477                      if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10478                         using_prefs = "reqonly";
10479                      } else {
10480                         using_prefs = "disabled";
10481                      }
10482                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10483                      memset(&pref, 0, sizeof(pref));
10484                      strcpy(caller_pref_buf, "disabled");
10485                      strcpy(host_pref_buf, "disabled");
10486                   } else {
10487                      using_prefs = "mine";
10488                      /* If the information elements are in here... use them */
10489                      if (ies.codec_prefs)
10490                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10491                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10492                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
10493                         if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10494                            pref = iaxs[fr->callno]->rprefs;
10495                            using_prefs = "caller";
10496                         } else {
10497                            pref = iaxs[fr->callno]->prefs;
10498                         }
10499                      } else
10500                         pref = iaxs[fr->callno]->prefs;
10501 
10502                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10503                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10504                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10505                   }
10506                   if (!format) {
10507                      if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10508                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10509                      if (!format) {
10510                         memset(&ied0, 0, sizeof(ied0));
10511                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10512                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10513                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10514                         if (!iaxs[fr->callno]) {
10515                            break;
10516                         }
10517                         if (authdebug) {
10518                            char tmp[256], tmp2[256], tmp3[256];
10519                            if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10520                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10521                                  ast_inet_ntoa(sin.sin_addr),
10522                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10523                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10524                            } else {
10525                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10526                                  ast_inet_ntoa(sin.sin_addr),
10527                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10528                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10529                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10530                            }
10531                         }
10532                      } else {
10533                         /* Pick one... */
10534                         if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10535                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10536                               format = 0;
10537                         } else {
10538                            if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10539                               using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10540                               memset(&pref, 0, sizeof(pref));
10541                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10542                               strcpy(caller_pref_buf,"disabled");
10543                               strcpy(host_pref_buf,"disabled");
10544                            } else {
10545                               using_prefs = "mine";
10546                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10547                                  /* Do the opposite of what we tried above. */
10548                                  if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10549                                     pref = iaxs[fr->callno]->prefs;
10550                                  } else {
10551                                     pref = iaxs[fr->callno]->rprefs;
10552                                     using_prefs = "caller";
10553                                  }
10554                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10555                               } else /* if no codec_prefs IE do it the old way */
10556                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10557                            }
10558                         }
10559 
10560                         if (!format) {
10561                            char tmp[256], tmp2[256], tmp3[256];
10562                            memset(&ied0, 0, sizeof(ied0));
10563                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10564                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10565                            ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10566                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10567                            if (!iaxs[fr->callno]) {
10568                               break;
10569                            }
10570                            if (authdebug) {
10571                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10572                                  ast_inet_ntoa(sin.sin_addr),
10573                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10574                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10575                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10576                            }
10577                            ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10578                            break;
10579                         }
10580                      }
10581                   }
10582                   if (format) {
10583                      /* No authentication required, let them in */
10584                      memset(&ied1, 0, sizeof(ied1));
10585                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10586                      iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10587                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10588                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10589                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10590                         ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10591                                     "%srequested format = %s,\n"
10592                                     "%srequested prefs = %s,\n"
10593                                     "%sactual format = %s,\n"
10594                                     "%shost prefs = %s,\n"
10595                                     "%spriority = %s\n",
10596                                     ast_inet_ntoa(sin.sin_addr), 
10597                                     VERBOSE_PREFIX_4,
10598                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
10599                                     VERBOSE_PREFIX_4,
10600                                     caller_pref_buf,
10601                                     VERBOSE_PREFIX_4,
10602                                     ast_getformatname(format), 
10603                                     VERBOSE_PREFIX_4,
10604                                     host_pref_buf, 
10605                                     VERBOSE_PREFIX_4,
10606                                     using_prefs);
10607 
10608                         iaxs[fr->callno]->chosenformat = format;
10609                         ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10610                      } else {
10611                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10612                         /* If this is a TBD call, we're ready but now what...  */
10613                         ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10614                      }
10615                   }
10616                }
10617                break;
10618             }
10619             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10620                merge_encryption(iaxs[fr->callno],ies.encmethods);
10621             else
10622                iaxs[fr->callno]->encmethods = 0;
10623             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10624                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10625             break;
10626          case IAX_COMMAND_DPREQ:
10627             /* Request status in the dialplan */
10628             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10629                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10630                if (iaxcompat) {
10631                   /* Spawn a thread for the lookup */
10632                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10633                } else {
10634                   /* Just look it up */
10635                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10636                }
10637             }
10638             break;
10639          case IAX_COMMAND_HANGUP:
10640             ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10641             ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10642             /* Set hangup cause according to remote and hangupsource */
10643             if (iaxs[fr->callno]->owner) {
10644                set_hangup_source_and_cause(fr->callno, ies.causecode);
10645                if (!iaxs[fr->callno]) {
10646                   break;
10647                }
10648             }
10649 
10650             /* Send ack immediately, before we destroy */
10651             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10652             iax2_destroy(fr->callno);
10653             break;
10654          case IAX_COMMAND_REJECT:
10655             /* Set hangup cause according to remote and hangup source */
10656             if (iaxs[fr->callno]->owner) {
10657                set_hangup_source_and_cause(fr->callno, ies.causecode);
10658                if (!iaxs[fr->callno]) {
10659                   break;
10660                }
10661             }
10662 
10663             if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10664                if (iaxs[fr->callno]->owner && authdebug)
10665                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10666                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10667                      ies.cause ? ies.cause : "<Unknown>");
10668                ast_debug(1, "Immediately destroying %d, having received reject\n",
10669                   fr->callno);
10670             }
10671             /* Send ack immediately, before we destroy */
10672             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10673                          fr->ts, NULL, 0, fr->iseqno);
10674             if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10675                iaxs[fr->callno]->error = EPERM;
10676             iax2_destroy(fr->callno);
10677             break;
10678          case IAX_COMMAND_TRANSFER:
10679          {
10680             struct ast_channel *bridged_chan;
10681             struct ast_channel *owner;
10682 
10683             iax2_lock_owner(fr->callno);
10684             if (!iaxs[fr->callno]) {
10685                /* Initiating call went away before we could transfer. */
10686                break;
10687             }
10688             owner = iaxs[fr->callno]->owner;
10689             bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10690             if (bridged_chan && ies.called_number) {
10691                ast_mutex_unlock(&iaxsl[fr->callno]);
10692 
10693                /* Set BLINDTRANSFER channel variables */
10694                pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10695                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10696 
10697                if (ast_parking_ext_valid(ies.called_number, c, iaxs[fr->callno]->context)) {
10698                   ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10699                   if (iax_park(bridged_chan, owner, ies.called_number)) {
10700                      ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10701                         bridged_chan->name);
10702                   }
10703                   ast_mutex_lock(&iaxsl[fr->callno]);
10704                } else {
10705                   ast_mutex_lock(&iaxsl[fr->callno]);
10706 
10707                   if (iaxs[fr->callno]) {
10708                      if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context,
10709                         ies.called_number, 1)) {
10710                         ast_log(LOG_WARNING,
10711                            "Async goto of '%s' to '%s@%s' failed\n",
10712                            bridged_chan->name, ies.called_number,
10713                            iaxs[fr->callno]->context);
10714                      } else {
10715                         ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10716                            bridged_chan->name, ies.called_number,
10717                            iaxs[fr->callno]->context);
10718                      }
10719                   } else {
10720                      /* Initiating call went away before we could transfer. */
10721                   }
10722                }
10723             } else {
10724                ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10725             }
10726             if (owner) {
10727                ast_channel_unlock(owner);
10728             }
10729 
10730             break;
10731          }
10732          case IAX_COMMAND_ACCEPT:
10733             /* Ignore if call is already up or needs authentication or is a TBD */
10734             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10735                break;
10736             if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10737                /* Send ack immediately, before we destroy */
10738                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10739                iax2_destroy(fr->callno);
10740                break;
10741             }
10742             if (ies.format) {
10743                iaxs[fr->callno]->peerformat = ies.format;
10744             } else {
10745                if (iaxs[fr->callno]->owner)
10746                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10747                else
10748                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10749             }
10750             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));
10751             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10752                memset(&ied0, 0, sizeof(ied0));
10753                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10754                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10755                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10756                if (!iaxs[fr->callno]) {
10757                   break;
10758                }
10759                if (authdebug) {
10760                   char tmp1[256], tmp2[256];
10761                   ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
10762                      ast_inet_ntoa(sin.sin_addr),
10763                      ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10764                      ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10765                }
10766             } else {
10767                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10768                iax2_lock_owner(fr->callno);
10769                if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10770                   /* Switch us to use a compatible format */
10771                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10772                   ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10773 
10774                   /* Setup read/write formats properly. */
10775                   if (iaxs[fr->callno]->owner->writeformat)
10776                      ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
10777                   if (iaxs[fr->callno]->owner->readformat)
10778                      ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
10779                   ast_channel_unlock(iaxs[fr->callno]->owner);
10780                }
10781             }
10782             if (iaxs[fr->callno]) {
10783                AST_LIST_LOCK(&dpcache);
10784                AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10785                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10786                      iax2_dprequest(dp, fr->callno);
10787                AST_LIST_UNLOCK(&dpcache);
10788             }
10789             break;
10790          case IAX_COMMAND_POKE:
10791             /* Send back a pong packet with the original timestamp */
10792             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10793             break;
10794          case IAX_COMMAND_PING:
10795          {
10796             struct iax_ie_data pingied;
10797             construct_rr(iaxs[fr->callno], &pingied);
10798             /* Send back a pong packet with the original timestamp */
10799             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10800          }
10801             break;
10802          case IAX_COMMAND_PONG:
10803             /* Calculate ping time */
10804             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10805             /* save RR info */
10806             save_rr(fr, &ies);
10807 
10808             /* Good time to write jb stats for this call */
10809             log_jitterstats(fr->callno);
10810 
10811             if (iaxs[fr->callno]->peerpoke) {
10812                peer = iaxs[fr->callno]->peerpoke;
10813                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
10814                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10815                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10816                      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); 
10817                      ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */
10818                   }
10819                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10820                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
10821                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10822                      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); 
10823                      ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
10824                   }
10825                }
10826                peer->lastms = iaxs[fr->callno]->pingtime;
10827                if (peer->smoothing && (peer->lastms > -1))
10828                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10829                else if (peer->smoothing && peer->lastms < 0)
10830                   peer->historicms = (0 + peer->historicms) / 2;
10831                else              
10832                   peer->historicms = iaxs[fr->callno]->pingtime;
10833 
10834                /* Remove scheduled iax2_poke_noanswer */
10835                if (peer->pokeexpire > -1) {
10836                   if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10837                      peer_unref(peer);
10838                      peer->pokeexpire = -1;
10839                   }
10840                }
10841                /* Schedule the next cycle */
10842                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
10843                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10844                else
10845                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10846                if (peer->pokeexpire == -1)
10847                   peer_unref(peer);
10848                /* and finally send the ack */
10849                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10850                /* And wrap up the qualify call */
10851                iax2_destroy(fr->callno);
10852                peer->callno = 0;
10853                ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10854             }
10855             break;
10856          case IAX_COMMAND_LAGRQ:
10857          case IAX_COMMAND_LAGRP:
10858             f.src = "LAGRQ";
10859             f.mallocd = 0;
10860             f.offset = 0;
10861             f.samples = 0;
10862             iax_frame_wrap(fr, &f);
10863             if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
10864                /* Received a LAGRQ - echo back a LAGRP */
10865                fr->af.subclass.integer = IAX_COMMAND_LAGRP;
10866                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10867             } else {
10868                /* Received LAGRP in response to our LAGRQ */
10869                unsigned int ts;
10870                /* This is a reply we've been given, actually measure the difference */
10871                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10872                iaxs[fr->callno]->lag = ts - fr->ts;
10873                if (iaxdebug)
10874                   ast_debug(1, "Peer %s lag measured as %dms\n",
10875                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10876             }
10877             break;
10878          case IAX_COMMAND_AUTHREQ:
10879             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10880                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>");
10881                break;
10882             }
10883             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10884                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10885                         .subclass.integer = AST_CONTROL_HANGUP,
10886                };
10887                ast_log(LOG_WARNING, 
10888                   "I don't know how to authenticate %s to %s\n", 
10889                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10890                iax2_queue_frame(fr->callno, &hangup_fr);
10891             }
10892             break;
10893          case IAX_COMMAND_AUTHREP:
10894             /* For security, always ack immediately */
10895             if (delayreject)
10896                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10897             /* Ignore once we've started */
10898             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10899                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>");
10900                break;
10901             }
10902             if (authenticate_verify(iaxs[fr->callno], &ies)) {
10903                if (authdebug)
10904                   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);
10905                memset(&ied0, 0, sizeof(ied0));
10906                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10907                break;
10908             }
10909             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10910                /* This might re-enter the IAX code and need the lock */
10911                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10912             } else
10913                exists = 0;
10914             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10915                if (authdebug)
10916                   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);
10917                memset(&ied0, 0, sizeof(ied0));
10918                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10919                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10920                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10921                if (!iaxs[fr->callno]) {
10922                   break;
10923                }
10924             } else {
10925                /* Select an appropriate format */
10926                if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10927                   if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10928                      using_prefs = "reqonly";
10929                   } else {
10930                      using_prefs = "disabled";
10931                   }
10932                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10933                   memset(&pref, 0, sizeof(pref));
10934                   strcpy(caller_pref_buf, "disabled");
10935                   strcpy(host_pref_buf, "disabled");
10936                } else {
10937                   using_prefs = "mine";
10938                   if (ies.codec_prefs)
10939                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10940                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10941                      if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10942                         pref = iaxs[fr->callno]->rprefs;
10943                         using_prefs = "caller";
10944                      } else {
10945                         pref = iaxs[fr->callno]->prefs;
10946                      }
10947                   } else /* if no codec_prefs IE do it the old way */
10948                      pref = iaxs[fr->callno]->prefs;
10949                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10950                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10951                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10952                }
10953                if (!format) {
10954                   char tmp1[256], tmp2[256], tmp3[256];
10955                   if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10956                      ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
10957                         ast_getformatname(iaxs[fr->callno]->peerformat),
10958                         ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
10959                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10960                   }
10961                   if (!format) {
10962                      if (authdebug) {
10963                         if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10964                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
10965                               ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10966                               ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10967                         } else {
10968                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10969                               ast_inet_ntoa(sin.sin_addr),
10970                               ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10971                               ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10972                               ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10973                         }
10974                      }
10975                      memset(&ied0, 0, sizeof(ied0));
10976                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10977                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10978                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10979                      if (!iaxs[fr->callno]) {
10980                         break;
10981                      }
10982                   } else {
10983                      /* Pick one... */
10984                      if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10985                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10986                            format = 0;
10987                      } else {
10988                         if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10989                            using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10990                            memset(&pref, 0, sizeof(pref));
10991                            format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
10992                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10993                            strcpy(caller_pref_buf,"disabled");
10994                            strcpy(host_pref_buf,"disabled");
10995                         } else {
10996                            using_prefs = "mine";
10997                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10998                               /* Do the opposite of what we tried above. */
10999                               if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11000                                  pref = iaxs[fr->callno]->prefs;
11001                               } else {
11002                                  pref = iaxs[fr->callno]->rprefs;
11003                                  using_prefs = "caller";
11004                               }
11005                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11006                            } else /* if no codec_prefs IE do it the old way */
11007                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
11008                         }
11009                      }
11010                      if (!format) {
11011                         char tmp1[256], tmp2[256], tmp3[256];
11012                         ast_log(LOG_ERROR, "No best format in %s???\n",
11013                            ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11014                         if (authdebug) {
11015                            if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11016                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11017                                  ast_inet_ntoa(sin.sin_addr),
11018                                  ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11019                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11020                            } else {
11021                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11022                                  ast_inet_ntoa(sin.sin_addr),
11023                                  ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11024                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11025                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11026                            }
11027                         }
11028                         memset(&ied0, 0, sizeof(ied0));
11029                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11030                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11031                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11032                         if (!iaxs[fr->callno]) {
11033                            break;
11034                         }
11035                      }
11036                   }
11037                }
11038                if (format) {
11039                   /* Authentication received */
11040                   memset(&ied1, 0, sizeof(ied1));
11041                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11042                   iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11043                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11044                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11045                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11046                      ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11047                                  "%srequested format = %s,\n"
11048                                  "%srequested prefs = %s,\n"
11049                                  "%sactual format = %s,\n"
11050                                  "%shost prefs = %s,\n"
11051                                  "%spriority = %s\n", 
11052                                  ast_inet_ntoa(sin.sin_addr), 
11053                                  VERBOSE_PREFIX_4,
11054                                  ast_getformatname(iaxs[fr->callno]->peerformat),
11055                                  VERBOSE_PREFIX_4,
11056                                  caller_pref_buf,
11057                                  VERBOSE_PREFIX_4,
11058                                  ast_getformatname(format),
11059                                  VERBOSE_PREFIX_4,
11060                                  host_pref_buf,
11061                                  VERBOSE_PREFIX_4,
11062                                  using_prefs);
11063 
11064                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11065                      if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
11066                         iax2_destroy(fr->callno);
11067                      else if (ies.vars) {
11068                         struct ast_datastore *variablestore;
11069                         struct ast_variable *var, *prev = NULL;
11070                         AST_LIST_HEAD(, ast_var_t) *varlist;
11071                         varlist = ast_calloc(1, sizeof(*varlist));
11072                         variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11073                         if (variablestore && varlist) {
11074                            variablestore->data = varlist;
11075                            variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11076                            AST_LIST_HEAD_INIT(varlist);
11077                            ast_debug(1, "I can haz IAX vars? w00t\n");
11078                            for (var = ies.vars; var; var = var->next) {
11079                               struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11080                               if (prev)
11081                                  ast_free(prev);
11082                               prev = var;
11083                               if (!newvar) {
11084                                  /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11085                                  ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11086                               } else {
11087                                  AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11088                               }
11089                            }
11090                            if (prev)
11091                               ast_free(prev);
11092                            ies.vars = NULL;
11093                            ast_channel_datastore_add(c, variablestore);
11094                         } else {
11095                            ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11096                            if (variablestore)
11097                               ast_datastore_free(variablestore);
11098                            if (varlist)
11099                               ast_free(varlist);
11100                         }
11101                      }
11102                   } else {
11103                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11104                      /* If this is a TBD call, we're ready but now what...  */
11105                      ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11106                      if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11107                         goto immediatedial;
11108                      }
11109                   }
11110                }
11111             }
11112             break;
11113          case IAX_COMMAND_DIAL:
11114 immediatedial:
11115             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11116                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11117                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11118                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11119                   if (authdebug)
11120                      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);
11121                   memset(&ied0, 0, sizeof(ied0));
11122                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11123                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11124                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11125                   if (!iaxs[fr->callno]) {
11126                      break;
11127                   }
11128                } else {
11129                   char tmp[256];
11130                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11131                   ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11132                      ast_inet_ntoa(sin.sin_addr),
11133                      ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11134                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11135                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11136                   if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
11137                      iax2_destroy(fr->callno);
11138                   else if (ies.vars) {
11139                      struct ast_datastore *variablestore;
11140                      struct ast_variable *var, *prev = NULL;
11141                      AST_LIST_HEAD(, ast_var_t) *varlist;
11142                      varlist = ast_calloc(1, sizeof(*varlist));
11143                      variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11144                      ast_debug(1, "I can haz IAX vars? w00t\n");
11145                      if (variablestore && varlist) {
11146                         variablestore->data = varlist;
11147                         variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11148                         AST_LIST_HEAD_INIT(varlist);
11149                         for (var = ies.vars; var; var = var->next) {
11150                            struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11151                            if (prev)
11152                               ast_free(prev);
11153                            prev = var;
11154                            if (!newvar) {
11155                               /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11156                               ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11157                            } else {
11158                               AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11159                            }
11160                         }
11161                         if (prev)
11162                            ast_free(prev);
11163                         ies.vars = NULL;
11164                         ast_channel_datastore_add(c, variablestore);
11165                      } else {
11166                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11167                         if (variablestore)
11168                            ast_datastore_free(variablestore);
11169                         if (varlist)
11170                            ast_free(varlist);
11171                      }
11172                   }
11173                }
11174             }
11175             break;
11176          case IAX_COMMAND_INVAL:
11177             iaxs[fr->callno]->error = ENOTCONN;
11178             ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11179             iax2_destroy(fr->callno);
11180             ast_debug(1, "Destroying call %d\n", fr->callno);
11181             break;
11182          case IAX_COMMAND_VNAK:
11183             ast_debug(1, "Received VNAK: resending outstanding frames\n");
11184             /* Force retransmission */
11185             vnak_retransmit(fr->callno, fr->iseqno);
11186             break;
11187          case IAX_COMMAND_REGREQ:
11188          case IAX_COMMAND_REGREL:
11189             /* For security, always ack immediately */
11190             if (delayreject)
11191                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11192             if (register_verify(fr->callno, &sin, &ies)) {
11193                if (!iaxs[fr->callno]) {
11194                   break;
11195                }
11196                /* Send delayed failure */
11197                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11198                break;
11199             }
11200             if (!iaxs[fr->callno]) {
11201                break;
11202             }
11203             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11204                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11205 
11206                if (f.subclass.integer == IAX_COMMAND_REGREL) {
11207                   memset(&sin, 0, sizeof(sin));
11208                   sin.sin_family = AF_INET;
11209                }
11210                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11211                   ast_log(LOG_WARNING, "Registry error\n");
11212                }
11213                if (!iaxs[fr->callno]) {
11214                   break;
11215                }
11216                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11217                   ast_mutex_unlock(&iaxsl[fr->callno]);
11218                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11219                   ast_mutex_lock(&iaxsl[fr->callno]);
11220                }
11221                break;
11222             }
11223             registry_authrequest(fr->callno);
11224             break;
11225          case IAX_COMMAND_REGACK:
11226             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
11227                ast_log(LOG_WARNING, "Registration failure\n");
11228             /* Send ack immediately, before we destroy */
11229             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11230             iax2_destroy(fr->callno);
11231             break;
11232          case IAX_COMMAND_REGREJ:
11233             if (iaxs[fr->callno]->reg) {
11234                if (authdebug) {
11235                   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));
11236                   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>");
11237                }
11238                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11239             }
11240             /* Send ack immediately, before we destroy */
11241             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11242             iax2_destroy(fr->callno);
11243             break;
11244          case IAX_COMMAND_REGAUTH:
11245             /* Authentication request */
11246             if (registry_rerequest(&ies, fr->callno, &sin)) {
11247                memset(&ied0, 0, sizeof(ied0));
11248                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11249                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11250                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11251             }
11252             break;
11253          case IAX_COMMAND_TXREJ:
11254             iaxs[fr->callno]->transferring = 0;
11255             ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11256             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11257             if (iaxs[fr->callno]->bridgecallno) {
11258                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11259                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
11260                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11261                }
11262             }
11263             break;
11264          case IAX_COMMAND_TXREADY:
11265             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
11266                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
11267                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
11268                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11269                else
11270                   iaxs[fr->callno]->transferring = TRANSFER_READY;
11271                ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11272                if (iaxs[fr->callno]->bridgecallno) {
11273                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
11274                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
11275                      /* They're both ready, now release them. */
11276                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11277                         ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11278                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11279 
11280                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11281                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11282 
11283                         memset(&ied0, 0, sizeof(ied0));
11284                         memset(&ied1, 0, sizeof(ied1));
11285                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11286                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11287                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11288                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11289                      } else {
11290                         ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11291                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11292 
11293                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11294                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11295                         ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11296                         ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11297 
11298                         /* Stop doing lag & ping requests */
11299                         stop_stuff(fr->callno);
11300                         stop_stuff(iaxs[fr->callno]->bridgecallno);
11301 
11302                         memset(&ied0, 0, sizeof(ied0));
11303                         memset(&ied1, 0, sizeof(ied1));
11304                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11305                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11306                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11307                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11308                      }
11309 
11310                   }
11311                }
11312             }
11313             break;
11314          case IAX_COMMAND_TXREQ:
11315             try_transfer(iaxs[fr->callno], &ies);
11316             break;
11317          case IAX_COMMAND_TXCNT:
11318             if (iaxs[fr->callno]->transferring)
11319                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11320             break;
11321          case IAX_COMMAND_TXREL:
11322             /* Send ack immediately, rather than waiting until we've changed addresses */
11323             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11324             complete_transfer(fr->callno, &ies);
11325             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
11326             break;   
11327          case IAX_COMMAND_TXMEDIA:
11328             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11329                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11330                   /* Cancel any outstanding frames and start anew */
11331                   if (cur->transfer) {
11332                      cur->retries = -1;
11333                   }
11334                }
11335                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
11336                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11337             }
11338             break;
11339          case IAX_COMMAND_RTKEY:
11340             if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11341                ast_log(LOG_WARNING, 
11342                   "we've been told to rotate our encryption key, "
11343                   "but this isn't an encrypted call. bad things will happen.\n"
11344                );
11345                break;
11346             }
11347 
11348             IAX_DEBUGDIGEST("Receiving", ies.challenge);
11349 
11350             ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11351             break;
11352          case IAX_COMMAND_DPREP:
11353             complete_dpreply(iaxs[fr->callno], &ies);
11354             break;
11355          case IAX_COMMAND_UNSUPPORT:
11356             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11357             break;
11358          case IAX_COMMAND_FWDOWNL:
11359             /* Firmware download */
11360             if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11361                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11362                break;
11363             }
11364             memset(&ied0, 0, sizeof(ied0));
11365             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11366             if (res < 0)
11367                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11368             else if (res > 0)
11369                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11370             else
11371                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11372             break;
11373          case IAX_COMMAND_CALLTOKEN:
11374          {
11375             struct iax_frame *cur;
11376             /* find last sent frame */
11377             if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11378                resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11379             }
11380             break;
11381          }
11382          default:
11383             ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11384             memset(&ied0, 0, sizeof(ied0));
11385             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11386             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11387          }
11388          /* Free remote variables (if any) */
11389          if (ies.vars) {
11390             ast_variables_destroy(ies.vars);
11391             ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11392             ies.vars = NULL;
11393          }
11394 
11395          /* Don't actually pass these frames along */
11396          if ((f.subclass.integer != IAX_COMMAND_ACK) && 
11397            (f.subclass.integer != IAX_COMMAND_TXCNT) && 
11398            (f.subclass.integer != IAX_COMMAND_TXACC) && 
11399            (f.subclass.integer != IAX_COMMAND_INVAL) &&
11400            (f.subclass.integer != IAX_COMMAND_VNAK)) { 
11401             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11402                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11403          }
11404          ast_mutex_unlock(&iaxsl[fr->callno]);
11405          return 1;
11406       }
11407       /* Unless this is an ACK or INVAL frame, ack it */
11408       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11409          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11410    } else if (minivid) {
11411       f.frametype = AST_FRAME_VIDEO;
11412       if (iaxs[fr->callno]->videoformat > 0) 
11413          f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11414       else {
11415          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11416          iax2_vnak(fr->callno);
11417          ast_variables_destroy(ies.vars);
11418          ast_mutex_unlock(&iaxsl[fr->callno]);
11419          return 1;
11420       }
11421       f.datalen = res - sizeof(*vh);
11422       if (f.datalen)
11423          f.data.ptr = thread->buf + sizeof(*vh);
11424       else
11425          f.data.ptr = NULL;
11426 #ifdef IAXTESTS
11427       if (test_resync) {
11428          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11429       } else
11430 #endif /* IAXTESTS */
11431          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11432    } else {
11433       /* A mini frame */
11434       f.frametype = AST_FRAME_VOICE;
11435       if (iaxs[fr->callno]->voiceformat > 0)
11436          f.subclass.codec = iaxs[fr->callno]->voiceformat;
11437       else {
11438          ast_debug(1, "Received mini frame before first full voice frame\n");
11439          iax2_vnak(fr->callno);
11440          ast_variables_destroy(ies.vars);
11441          ast_mutex_unlock(&iaxsl[fr->callno]);
11442          return 1;
11443       }
11444       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11445       if (f.datalen < 0) {
11446          ast_log(LOG_WARNING, "Datalen < 0?\n");
11447          ast_variables_destroy(ies.vars);
11448          ast_mutex_unlock(&iaxsl[fr->callno]);
11449          return 1;
11450       }
11451       if (f.datalen)
11452          f.data.ptr = thread->buf + sizeof(*mh);
11453       else
11454          f.data.ptr = NULL;
11455 #ifdef IAXTESTS
11456       if (test_resync) {
11457          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11458       } else
11459 #endif /* IAXTESTS */
11460       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11461       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
11462    }
11463    /* Don't pass any packets until we're started */
11464    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11465       ast_variables_destroy(ies.vars);
11466       ast_mutex_unlock(&iaxsl[fr->callno]);
11467       return 1;
11468    }
11469    /* Don't allow connected line updates unless we are configured to */
11470    if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) {
11471       struct ast_party_connected_line connected;
11472 
11473       if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11474          ast_variables_destroy(ies.vars);
11475          ast_mutex_unlock(&iaxsl[fr->callno]);
11476          return 1;
11477       }
11478 
11479       /* Initialize defaults */
11480       ast_party_connected_line_init(&connected);
11481       connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11482       connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11483 
11484       if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11485          ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11486          ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11487          iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11488 
11489          if (iaxs[fr->callno]->owner) {
11490             ast_set_callerid(iaxs[fr->callno]->owner,
11491                S_COR(connected.id.number.valid, connected.id.number.str, ""),
11492                S_COR(connected.id.name.valid, connected.id.name.str, ""),
11493                NULL);
11494             iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11495             iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11496          }
11497       }
11498       ast_party_connected_line_free(&connected);
11499    }
11500    /* Common things */
11501    f.src = "IAX2";
11502    f.mallocd = 0;
11503    f.offset = 0;
11504    f.len = 0;
11505    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11506       f.samples = ast_codec_get_samples(&f);
11507       /* We need to byteswap incoming slinear samples from network byte order */
11508       if (f.subclass.codec == AST_FORMAT_SLINEAR)
11509          ast_frame_byteswap_be(&f);
11510    } else
11511       f.samples = 0;
11512    iax_frame_wrap(fr, &f);
11513 
11514    /* If this is our most recent packet, use it as our basis for timestamping */
11515    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11516       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
11517       fr->outoforder = 0;
11518    } else {
11519       if (iaxdebug && iaxs[fr->callno])
11520          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);
11521       fr->outoforder = -1;
11522    }
11523    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11524    duped_fr = iaxfrdup2(fr);
11525    if (duped_fr) {
11526       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11527    }
11528    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11529       iaxs[fr->callno]->last = fr->ts;
11530 #if 1
11531       if (iaxdebug)
11532          ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11533 #endif
11534    }
11535 
11536    /* Always run again */
11537    ast_variables_destroy(ies.vars);
11538    ast_mutex_unlock(&iaxsl[fr->callno]);
11539    return 1;
11540 }

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

09594 {
09595    unsigned char metatype;
09596    struct ast_iax2_meta_trunk_mini *mtm;
09597    struct ast_iax2_meta_trunk_hdr *mth;
09598    struct ast_iax2_meta_trunk_entry *mte;
09599    struct iax2_trunk_peer *tpeer;
09600    unsigned int ts;
09601    void *ptr;
09602    struct timeval rxtrunktime;
09603    struct ast_frame f = { 0, };
09604 
09605    if (packet_len < sizeof(*meta)) {
09606       ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 
09607          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09608       return 1;
09609    }
09610 
09611    if (meta->metacmd != IAX_META_TRUNK)
09612       return 1;
09613 
09614    if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09615       ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09616          (int) (sizeof(*meta) + sizeof(*mth)));
09617       return 1;
09618    }
09619    mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09620    ts = ntohl(mth->ts);
09621    metatype = meta->cmddata;
09622    packet_len -= (sizeof(*meta) + sizeof(*mth));
09623    ptr = mth->data;
09624    tpeer = find_tpeer(sin, sockfd);
09625    if (!tpeer) {
09626       ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 
09627          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09628       return 1;
09629    }
09630    tpeer->trunkact = ast_tvnow();
09631    if (!ts || ast_tvzero(tpeer->rxtrunktime))
09632       tpeer->rxtrunktime = tpeer->trunkact;
09633    rxtrunktime = tpeer->rxtrunktime;
09634    ast_mutex_unlock(&tpeer->lock);
09635    while (packet_len >= sizeof(*mte)) {
09636       /* Process channels */
09637       unsigned short callno, trunked_ts, len;
09638 
09639       if (metatype == IAX_META_TRUNK_MINI) {
09640          mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09641          ptr += sizeof(*mtm);
09642          packet_len -= sizeof(*mtm);
09643          len = ntohs(mtm->len);
09644          callno = ntohs(mtm->mini.callno);
09645          trunked_ts = ntohs(mtm->mini.ts);
09646       } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09647          mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09648          ptr += sizeof(*mte);
09649          packet_len -= sizeof(*mte);
09650          len = ntohs(mte->len);
09651          callno = ntohs(mte->callno);
09652          trunked_ts = 0;
09653       } else {
09654          ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09655          break;
09656       }
09657       /* Stop if we don't have enough data */
09658       if (len > packet_len)
09659          break;
09660       fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09661       if (!fr->callno)
09662          continue;
09663 
09664       /* If it's a valid call, deliver the contents.  If not, we
09665          drop it, since we don't have a scallno to use for an INVAL */
09666       /* Process as a mini frame */
09667       memset(&f, 0, sizeof(f));
09668       f.frametype = AST_FRAME_VOICE;
09669       if (!iaxs[fr->callno]) {
09670          /* drop it */
09671       } else if (iaxs[fr->callno]->voiceformat == 0) {
09672          ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09673          iax2_vnak(fr->callno);
09674       } else {
09675          f.subclass.codec = iaxs[fr->callno]->voiceformat;
09676          f.datalen = len;
09677          if (f.datalen >= 0) {
09678             if (f.datalen)
09679                f.data.ptr = ptr;
09680             else
09681                f.data.ptr = NULL;
09682             if (trunked_ts)
09683                fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09684             else
09685                fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09686             /* Don't pass any packets until we're started */
09687             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09688                struct iax_frame *duped_fr;
09689 
09690                /* Common things */
09691                f.src = "IAX2";
09692                f.mallocd = 0;
09693                f.offset = 0;
09694                if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
09695                   f.samples = ast_codec_get_samples(&f);
09696                else
09697                   f.samples = 0;
09698                fr->outoforder = 0;
09699                iax_frame_wrap(fr, &f);
09700                duped_fr = iaxfrdup2(fr);
09701                if (duped_fr)
09702                   schedule_delivery(duped_fr, 1, 1, &fr->ts);
09703                if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09704                   iaxs[fr->callno]->last = fr->ts;
09705             }
09706          } else {
09707             ast_log(LOG_WARNING, "Datalen < 0?\n");
09708          }
09709       }
09710       ast_mutex_unlock(&iaxsl[fr->callno]);
09711       ptr += len;
09712       packet_len -= len;
09713    }
09714 
09715    return 1;
09716 }

static int socket_read ( int *  id,
int  fd,
short  events,
void *  cbdata 
) [static]

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

09514 {
09515    struct iax2_thread *thread;
09516    socklen_t len;
09517    time_t t;
09518    static time_t last_errtime = 0;
09519    struct ast_iax2_full_hdr *fh;
09520 
09521    if (!(thread = find_idle_thread())) {
09522       time(&t);
09523       if (t != last_errtime)
09524          ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09525       last_errtime = t;
09526       usleep(1);
09527       return 1;
09528    }
09529 
09530    len = sizeof(thread->iosin);
09531    thread->iofd = fd;
09532    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09533    thread->buf_size = sizeof(thread->readbuf);
09534    thread->buf = thread->readbuf;
09535    if (thread->buf_len < 0) {
09536       if (errno != ECONNREFUSED && errno != EAGAIN)
09537          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09538       handle_error();
09539       thread->iostate = IAX_IOSTATE_IDLE;
09540       signal_condition(&thread->lock, &thread->cond);
09541       return 1;
09542    }
09543    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
09544       thread->iostate = IAX_IOSTATE_IDLE;
09545       signal_condition(&thread->lock, &thread->cond);
09546       return 1;
09547    }
09548    
09549    /* Determine if this frame is a full frame; if so, and any thread is currently
09550       processing a full frame for the same callno from this peer, then drop this
09551       frame (and the peer will retransmit it) */
09552    fh = (struct ast_iax2_full_hdr *) thread->buf;
09553    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09554       struct iax2_thread *cur = NULL;
09555       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09556       
09557       AST_LIST_LOCK(&active_list);
09558       AST_LIST_TRAVERSE(&active_list, cur, list) {
09559          if ((cur->ffinfo.callno == callno) &&
09560              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09561             break;
09562       }
09563       if (cur) {
09564          /* we found another thread processing a full frame for this call,
09565             so queue it up for processing later. */
09566          defer_full_frame(thread, cur);
09567          AST_LIST_UNLOCK(&active_list);
09568          thread->iostate = IAX_IOSTATE_IDLE;
09569          signal_condition(&thread->lock, &thread->cond);
09570          return 1;
09571       } else {
09572          /* this thread is going to process this frame, so mark it */
09573          thread->ffinfo.callno = callno;
09574          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09575          thread->ffinfo.type = fh->type;
09576          thread->ffinfo.csub = fh->csub;
09577          AST_LIST_INSERT_HEAD(&active_list, thread, list);
09578       }
09579       AST_LIST_UNLOCK(&active_list);
09580    }
09581    
09582    /* Mark as ready and send on its way */
09583    thread->iostate = IAX_IOSTATE_READY;
09584 #ifdef DEBUG_SCHED_MULTITHREAD
09585    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09586 #endif
09587    signal_condition(&thread->lock, &thread->cond);
09588 
09589    return 1;
09590 }

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

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

09231 {
09232    pthread_t newthread;
09233    struct dpreq_data *dpr;
09234    
09235    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09236       return;
09237 
09238    dpr->callno = callno;
09239    ast_copy_string(dpr->context, context, sizeof(dpr->context));
09240    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09241    if (callerid)
09242       dpr->callerid = ast_strdup(callerid);
09243    if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09244       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09245    }
09246 }

static int start_network_thread ( void   )  [static]

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

12095 {
12096    struct iax2_thread *thread;
12097    int threadcount = 0;
12098    int x;
12099    for (x = 0; x < iaxthreadcount; x++) {
12100       thread = ast_calloc(1, sizeof(*thread));
12101       if (thread) {
12102          thread->type = IAX_THREAD_TYPE_POOL;
12103          thread->threadnum = ++threadcount;
12104          ast_mutex_init(&thread->lock);
12105          ast_cond_init(&thread->cond, NULL);
12106          ast_mutex_init(&thread->init_lock);
12107          ast_cond_init(&thread->init_cond, NULL);
12108          if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12109             ast_log(LOG_WARNING, "Failed to create new thread!\n");
12110             ast_mutex_destroy(&thread->lock);
12111             ast_cond_destroy(&thread->cond);
12112             ast_mutex_destroy(&thread->init_lock);
12113             ast_cond_destroy(&thread->init_cond);
12114             ast_free(thread);
12115             thread = NULL;
12116             continue;
12117          }
12118          AST_LIST_LOCK(&idle_list);
12119          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12120          AST_LIST_UNLOCK(&idle_list);
12121       }
12122    }
12123    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
12124    ast_verb(2, "%d helper threads started\n", threadcount);
12125    return 0;
12126 }

static void stop_stuff ( int  callno  )  [static]

Definition at line 8936 of file chan_iax2.c.

References iax2_destroy_helper(), and iaxs.

Referenced by socket_process().

08937 {
08938    iax2_destroy_helper(iaxs[callno]);
08939 }

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

09120 {
09121    int res, processed = 0, totalcalls = 0;
09122    struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09123    struct timeval now = ast_tvnow();
09124 
09125    if (iaxtrunkdebug)
09126       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09127 
09128    if (timer) { 
09129       ast_timer_ack(timer, 1);
09130    }
09131 
09132    /* For each peer that supports trunking... */
09133    AST_LIST_LOCK(&tpeers);
09134    AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09135       processed++;
09136       res = 0;
09137       ast_mutex_lock(&tpeer->lock);
09138       /* We can drop a single tpeer per pass.  That makes all this logic
09139          substantially easier */
09140       if (!drop && iax2_trunk_expired(tpeer, &now)) {
09141          /* Take it out of the list, but don't free it yet, because it
09142             could be in use */
09143          AST_LIST_REMOVE_CURRENT(list);
09144          drop = tpeer;
09145       } else {
09146          res = send_trunk(tpeer, &now);
09147          trunk_timed++; 
09148          if (iaxtrunkdebug)
09149             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);
09150       }     
09151       totalcalls += res;   
09152       res = 0;
09153       ast_mutex_unlock(&tpeer->lock);
09154    }
09155    AST_LIST_TRAVERSE_SAFE_END;
09156    AST_LIST_UNLOCK(&tpeers);
09157 
09158    if (drop) {
09159       ast_mutex_lock(&drop->lock);
09160       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
09161          because by the time they could get tpeerlock, we've already grabbed it */
09162       ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09163       if (drop->trunkdata) {
09164          ast_free(drop->trunkdata);
09165          drop->trunkdata = NULL;
09166       }
09167       ast_mutex_unlock(&drop->lock);
09168       ast_mutex_destroy(&drop->lock);
09169       ast_free(drop);
09170       
09171    }
09172 
09173    if (iaxtrunkdebug)
09174       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09175    iaxtrunkdebug = 0;
09176 
09177    return 1;
09178 }

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

Definition at line 14333 of file chan_iax2.c.

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

Referenced by load_objects().

14334 {
14335    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14336 
14337    /* The frames_received field is used to hold whether we're matching
14338     * against a full frame or not ... */
14339 
14340    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14341       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14342 }

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

Definition at line 14326 of file chan_iax2.c.

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

14327 {
14328    const struct chan_iax2_pvt *pvt = obj;
14329 
14330    return pvt->transfercallno;
14331 }

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

08265 {
08266    int newcall = 0;
08267    char newip[256];
08268    struct iax_ie_data ied;
08269    struct sockaddr_in new;
08270    
08271    
08272    memset(&ied, 0, sizeof(ied));
08273    if (ies->apparent_addr)
08274       memmove(&new, ies->apparent_addr, sizeof(new));
08275    if (ies->callno)
08276       newcall = ies->callno;
08277    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08278       ast_log(LOG_WARNING, "Invalid transfer request\n");
08279       return -1;
08280    }
08281    pvt->transfercallno = newcall;
08282    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08283    inet_aton(newip, &pvt->transfer.sin_addr);
08284    pvt->transfer.sin_family = AF_INET;
08285    pvt->transferid = ies->transferid;
08286    /* only store by transfercallno if this is a new transfer,
08287     * just in case we get a duplicate TXREQ */
08288    if (pvt->transferring == TRANSFER_NONE) {
08289       store_by_transfercallno(pvt);
08290    }
08291    pvt->transferring = TRANSFER_BEGIN;
08292 
08293    if (ies->transferid)
08294       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08295    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08296    return 0;
08297 }

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

08554 {
08555    if (peer->expire > -1) {
08556       if (!ast_sched_thread_del(sched, peer->expire)) {
08557          peer->expire = -1;
08558          peer_unref(peer);
08559       }
08560    }
08561 
08562    if (peer->pokeexpire > -1) {
08563       if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08564          peer->pokeexpire = -1;
08565          peer_unref(peer);
08566       }
08567    }
08568 
08569    ao2_unlink(peers, peer);
08570 }

static int unload_module ( void   )  [static]

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

References ast_mutex_unlock, and iaxsl.

Referenced by iax2_bridge().

05431 {
05432    ast_mutex_unlock(&iaxsl[callno1]);
05433    ast_mutex_unlock(&iaxsl[callno0]);
05434 }

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

08669 {
08670    /* Called from IAX thread only, with proper iaxsl lock */
08671    struct iax_ie_data ied = {
08672       .pos = 0,
08673    };
08674    struct iax2_peer *p;
08675    int msgcount;
08676    char data[80];
08677    int version;
08678    const char *peer_name;
08679    int res = -1;
08680    struct ast_sockaddr sockaddr;
08681 
08682    ast_sockaddr_from_sin(&sockaddr, sin);
08683 
08684    peer_name = ast_strdupa(iaxs[callno]->peer);
08685 
08686    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
08687    ast_mutex_unlock(&iaxsl[callno]);
08688    if (!(p = find_peer(peer_name, 1))) {
08689       ast_mutex_lock(&iaxsl[callno]);
08690       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08691       return -1;
08692    }
08693    ast_mutex_lock(&iaxsl[callno]);
08694    if (!iaxs[callno])
08695       goto return_unref;
08696 
08697    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08698       if (sin->sin_addr.s_addr) {
08699          time_t nowtime;
08700          time(&nowtime);
08701          realtime_update_peer(peer_name, &sockaddr, nowtime);
08702       } else {
08703          realtime_update_peer(peer_name, &sockaddr, 0);
08704       }
08705    }
08706 
08707    if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08708       if (iax2_regfunk) {
08709          iax2_regfunk(p->name, 1);
08710       }
08711 
08712       /* modify entry in peercnts table as _not_ registered */
08713       peercnt_modify(0, 0, &p->addr);
08714 
08715       /* Stash the IP address from which they registered */
08716       ast_sockaddr_from_sin(&p->addr, sin);
08717 
08718       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08719       if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08720          ast_db_put("IAX/Registry", p->name, data);
08721          ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08722                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08723          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08724          register_peer_exten(p, 1);
08725          ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
08726       } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08727          ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08728                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08729          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08730          register_peer_exten(p, 0);
08731          ast_db_del("IAX/Registry", p->name);
08732          ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */
08733       }
08734       /* Update the host */
08735       /* Verify that the host is really there */
08736       iax2_poke_peer(p, callno);
08737    }
08738 
08739    /* modify entry in peercnts table as registered */
08740    if (p->maxcallno) {
08741       peercnt_modify(1, p->maxcallno, &p->addr);
08742    }
08743 
08744    /* Make sure our call still exists, an INVAL at the right point may make it go away */
08745    if (!iaxs[callno]) {
08746       res = -1;
08747       goto return_unref;
08748    }
08749 
08750    /* Store socket fd */
08751    p->sockfd = fd;
08752    /* Setup the expiry */
08753    if (p->expire > -1) {
08754       if (!ast_sched_thread_del(sched, p->expire)) {
08755          p->expire = -1;
08756          peer_unref(p);
08757       }
08758    }
08759    /* treat an unspecified refresh interval as the minimum */
08760    if (!refresh)
08761       refresh = min_reg_expire;
08762    if (refresh > max_reg_expire) {
08763       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08764          p->name, max_reg_expire, refresh);
08765       p->expiry = max_reg_expire;
08766    } else if (refresh < min_reg_expire) {
08767       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08768          p->name, min_reg_expire, refresh);
08769       p->expiry = min_reg_expire;
08770    } else {
08771       p->expiry = refresh;
08772    }
08773    if (p->expiry && sin->sin_addr.s_addr) {
08774       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08775       if (p->expire == -1)
08776          peer_unref(p);
08777    }
08778    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08779    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08780    if (sin->sin_addr.s_addr) {
08781       struct sockaddr_in peer_addr;
08782 
08783       ast_sockaddr_to_sin(&p->addr, &peer_addr);
08784 
08785       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08786       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08787       if (!ast_strlen_zero(p->mailbox)) {
08788          struct ast_event *event;
08789          int new, old;
08790          char *mailbox, *context;
08791 
08792          context = mailbox = ast_strdupa(p->mailbox);
08793          strsep(&context, "@");
08794          if (ast_strlen_zero(context))
08795             context = "default";
08796 
08797          event = ast_event_get_cached(AST_EVENT_MWI,
08798             AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08799             AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08800             AST_EVENT_IE_END);
08801          if (event) {
08802             new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08803             old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08804             ast_event_destroy(event);
08805          } else { /* Fall back on checking the mailbox directly */
08806             ast_app_inboxcount(p->mailbox, &new, &old);
08807          }
08808 
08809          if (new > 255) {
08810             new = 255;
08811          }
08812          if (old > 255) {
08813             old = 255;
08814          }
08815          msgcount = (old << 8) | new;
08816 
08817          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08818       }
08819       if (ast_test_flag64(p, IAX_HASCALLERID)) {
08820          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08821          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08822       }
08823    }
08824    version = iax_check_version(devtype);
08825    if (version) 
08826       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08827 
08828    res = 0;
08829 
08830 return_unref:
08831    peer_unref(p);
08832 
08833    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08834 }

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

References ast_set_flag64, IAX_DELME, and user.

Referenced by delete_users().

12831 {
12832    struct iax2_user *user = obj;
12833 
12834    ast_set_flag64(user, IAX_DELME);
12835 
12836    return 0;
12837 }

static void user_destructor ( void *  obj  )  [static]

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

12556 {
12557    struct iax2_user *user = obj;
12558 
12559    ast_free_ha(user->ha);
12560    free_context(user->contexts);
12561    if(user->vars) {
12562       ast_variables_destroy(user->vars);
12563       user->vars = NULL;
12564    }
12565    ast_string_field_free_memory(user);
12566 }

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

14498 {
14499    struct ast_data *data_user, *data_authmethods, *data_enum_node;
14500    struct iax2_user *user;
14501    struct ao2_iterator i;
14502    char auth[90];
14503    char *pstr = "";
14504 
14505    i = ao2_iterator_init(users, 0);
14506    while ((user = ao2_iterator_next(&i))) {
14507       data_user = ast_data_add_node(data_root, "user");
14508       if (!data_user) {
14509          user_unref(user);
14510          continue;
14511       }
14512 
14513       ast_data_add_structure(iax2_user, data_user, user);
14514 
14515       ast_data_add_codecs(data_user, "codecs", user->capability);
14516 
14517       if (!ast_strlen_zero(user->secret)) {
14518          ast_copy_string(auth, user->secret, sizeof(auth));
14519       } else if (!ast_strlen_zero(user->inkeys)) {
14520          snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14521       } else {
14522          ast_copy_string(auth, "no secret", sizeof(auth));
14523       }
14524       ast_data_add_password(data_user, "secret", auth);
14525 
14526       ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14527 
14528       /* authmethods */
14529       data_authmethods = ast_data_add_node(data_user, "authmethods");
14530       if (!data_authmethods) {
14531          ast_data_remove_node(data_root, data_user);
14532          continue;
14533       }
14534       ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14535       ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14536       ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14537 
14538       /* amaflags */
14539       data_enum_node = ast_data_add_node(data_user, "amaflags");
14540       if (!data_enum_node) {
14541          ast_data_remove_node(data_root, data_user);
14542          continue;
14543       }
14544       ast_data_add_int(data_enum_node, "value", user->amaflags);
14545       ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14546 
14547       ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14548 
14549       if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14550          pstr = "REQ only";
14551       } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14552          pstr = "disabled";
14553       } else {
14554          pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14555       }
14556       ast_data_add_str(data_user, "codec-preferences", pstr);
14557 
14558       user_unref(user);
14559 
14560       if (!ast_data_search_match(search, data_user)) {
14561          ast_data_remove_node(data_root, data_user);
14562       }
14563    }
14564    ao2_iterator_destroy(&i);
14565 
14566    return 0;
14567 }

static void vnak_retransmit ( int  callno,
int  last 
) [static]

Definition at line 9037 of file chan_iax2.c.

References AST_LIST_TRAVERSE, f, frame_queue, iax_frame::list, and send_packet().

Referenced by socket_process().

09038 {
09039    struct iax_frame *f;
09040 
09041    AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09042       /* Send a copy immediately */
09043       if (((unsigned char) (f->oseqno - last) < 128) &&
09044             (f->retries >= 0)) {
09045          send_packet(f);
09046       }
09047    }
09048 }

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 14708 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 14708 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 14037 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 14579 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 13923 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 13843 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 9784 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 11801 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 14569 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 14574 of file chan_iax2.c.


Generated on Mon Jun 27 16:51:06 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7